简体   繁体   English

d3 用渐变填充区域

[英]d3 filling an area with a gradient

I'm wanting to fill the area of this line chart with a gradient, so that the bottom of the gradient is transparent, and the top of the area fill is black.我想用渐变填充这个折线图的区域,使渐变的底部是透明的,而区域填充的顶部是黑色的。 Is this possible?这可能吗?

All my google searches are bring up charts like: http://bl.ocks.org/d3noob/4433087 - I don't want the gradient to be based on the values, in this example I'd want red across the top of the area, not just when a value reaches that %.我所有的谷歌搜索都显示图表,如: http://bl.ocks.org/d3noob/4433087 - 我不希望渐变基于值,在这个例子中我想要红色穿过顶部该区域,而不仅仅是当一个值达到该百分比时。

 var entries = [{"date":"2016-01-06","value":15},{"date":"2015-11-17","value":15.4},{"date":"2015-11-11","value":16.5},{"date":"2015-09-24","value":15.1},{"date":"2015-08-22","value":15},{"date":"2015-08-12","value":15},{"date":"2015-07-30","value":14.6},{"date":"2015-07-19","value":14.8},{"date":"2015-07-18","value":14.9},{"date":"2015-07-12","value":14.9},{"date":"2015-07-08","value":14.9},{"date":"2015-06-29","value":14.3},{"date":"2015-06-21","value":14.5},{"date":"2015-06-18","value":14.7},{"date":"2015-06-09","value":15},{"date":"2015-06-08","value":14.1},{"date":"2014-12-06","value":13.4},{"date":"2014-09-10","value":13.1},{"date":"2014-08-01","value":14.2},{"date":"2014-07-07","value":15},{"date":"2014-05-31","value":14},{"date":"2014-05-24","value":15},{"date":"2014-05-14","value":15},{"date":"2014-05-13","value":14},{"date":"2014-05-08","value":14.5},{"date":"2014-05-02","value":15}]; var margin = {top: 30, right: 20, bottom: 30, left: 50}, overlayW = $('.chart').innerWidth(), overlayH = $('.chart').innerHeight(), width = overlayW, height = 250 - margin.top - margin.bottom, parseDate = d3.time.format("%Y-%m-%d").parse, bisectDate = d3.bisector(function(d) { return d.date; }).left, formatValue = d3.format(",.2f"); var x = d3.time.scale().range([0, width]); var y = d3.scale.linear().range([height, 0]); var xAxis = d3.svg.axis().scale(x).tickSize(0).tickValues(x.domain()).orient("bottom").tickFormat(d3.time.format("%b")); var yAxis = d3.svg.axis().scale(y).tickSize(0).ticks(5).orient("left"); var area = d3.svg.area().x(function(d) { return x(d.date); }).y0(height).y1(function(d) { return y(d.value); }); var svg = d3.select(".drawn").append("svg").attr("width", width).attr("height", height + margin.top + margin.bottom).append("g").attr("transform", "translate(-15,30)"); enter(entries); function enter(data) { data.forEach(function(d) { d.date = parseDate(d.date); d.value = +d.value; }); data.sort(function(a, b) { return a.date - b.date; }); x.domain([data[0].date, data[data.length - 1].date]); y.domain(d3.extent(data, function(d) { return d.value; })); //y.domain(d3.extent(data, function(d) { return d.value; })); var e = d3.extent(data, function(d) { return d.value; }); svg.append("path").datum(data).attr("class", "area").attr("d", area); svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(xAxis); svg.append("g").attr("class", "y axis").attr("transform", "translate(" + width + ",0)").call(yAxis); }
 .chart {display:block;background:#4BAC4E;height:250px;width:600px;}.axis path, .axis line { fill: none; stroke: rgba(0, 0, 0, .3); shape-rendering: crispEdges; } text { font: 400 11px mono; letter-spacing: .3px; text-transform: uppercase; fill: rgba(0, 0, 0, .3); }.domain { display: none; }.area { fill: black; stroke: none; stroke-width: 0; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="chart"> <div class="drawn"></div> </div>

https://jsfiddle.net/5kesyqu0/3/ https://jsfiddle.net/5kesyqu0/3/

You can achieve this making a linear gradient like this: 你可以实现这样做一个像这样的线性渐变:

//make defs and add the linear gradient
var lg = svgmain.append("defs").append("linearGradient")
.attr("id", "mygrad")//id of the gradient
.attr("x1", "0%")
.attr("x2", "0%")
.attr("y1", "0%")
.attr("y2", "100%")//since its a vertical linear gradient 
;
lg.append("stop")
.attr("offset", "0%")
.style("stop-color", "red")//end in red
.style("stop-opacity", 1)

lg.append("stop")
.attr("offset", "100%")
.style("stop-color", "blue")//start in blue
.style("stop-opacity", 1)

Then add this gradient to the fill of your path. 然后将此渐变添加到路径的填充中。

  svg.append("path")
      .datum(data)
      .attr("class", "area")
      .attr("d", area)
        .style("fill", "url(#mygrad)");//id of the gradient for fill

Working code here . 在这里工作代码。

Another example as per your requirement ( So that the bottom of the gradient is transparent, and the top of the area fill is red ). 另一个例子根据您的要求因此渐变的底部是透明的,并且区域填充的顶部是红色的 )。

I might be late to this party, but exactly the same result I wanted to accomplish recently.我可能会迟到这个聚会,但我最近想要完成的结果完全一样。 While browsing internet I found this SO question and decided to post my own answer.在浏览互联网时,我发现了这个 SO question 并决定发布我自己的答案。 Looks like no one else ever posted this solution yet.看起来还没有其他人发布过这个解决方案。 So, here goes:所以,这里是:

let svgDefs = svg.append('defs');    

let filterBlur = svgDefs
    .append("filter")
    .attr('id', 'blur')
    .attr("x", "0")
    .attr("y", "0")
    .append("feGaussianBlur")
    .attr("in", "SourceGraphic")
    .attr("stdDeviation", 20);
    
let mask = svgDefs
    .append("mask")
    .attr('id', 'mask')
    .datum(data)
    .append("path")
    .attr("fill", "#fff")
    .attr("d", d3.svg.area()
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.value); }));

svg.append("path")
    .datum(data)
    .attr("stroke", "#274EF6")
    .attr("stroke-width", 15)
    .attr("fill", "none")
    .attr("filter", "url(#blur)")
    .attr("mask", "url(#mask)")
    .attr("class", "line-blur")
    .attr("d", d3.svg.line()
        .x(function (d) {
            return x(d.date);
        })
        .y(function (d) {
            return y(d.value);
        }));

Basic idea is not to use area chart, instead use line chart with pretty wide line-width.基本思想是不使用面积图,而是使用线宽相当宽的折线图。 Then, apply blur effect to it and then mask property, where path of the mask will be created by that area, which we discarded at first step.然后,对其应用模糊效果,然后应用蒙版属性,蒙版的路径将由该区域创建,我们在第一步中将其丢弃。 Hope it is helpful希望对您有所帮助在此处输入图像描述

https://jsfiddle.net/RomanTourdyiev/dzcfsh1x/5/ https://jsfiddle.net/RomanTourdyiev/dzcfsh1x/5/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM