admin管理员组

文章数量:1277406

I have started using d3.js. I have following requirement

Requirement:

What I have tried?

fiddle

Question?

How to achieve gradient as same as above image.

Any suggestion or idea will be grateful.

Note

I am just started d3.js.

I have started using d3.js. I have following requirement

Requirement:

What I have tried?

fiddle

Question?

How to achieve gradient as same as above image.

Any suggestion or idea will be grateful.

Note

I am just started d3.js.

Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Aug 10, 2015 at 6:13 karthickkarthick 6,17812 gold badges53 silver badges92 bronze badges 3
  • Maybe if you gaussian blur the stroke at the edge of the arc, that would do it. – Robert Longson Commented Aug 10, 2015 at 6:56
  • 1 You'll probably be using d3.arc, which has a specified start and end angle. So all you have to do is break each segment up into many smaller parts and apply the gradient to it (either via array or using a d3 scale). You could also simply create a pie chart of 100 arcs and color each individually based on the percentage. – JSBob Commented Aug 10, 2015 at 18:15
  • i believe, i've managed to do a gradient on the white background arc jsfiddle/BTfmH/242, although i'm not sure how it works. In fact it's a radial gradient but it works fine on a circle with linearGradient coordinates - x1,y1...not with cx,cy,r... Strange. – GL.awog Commented Aug 12, 2015 at 11:04
Add a ment  | 

1 Answer 1

Reset to default 10 +50

Edit - changed data structure and fiddle link to represent unfilled chunk at the beginning.

I would use the pie function in d3 to create a pie chart. The image above is basically a pie with two different gradient styles applied to the pie chunks. A red linear gradient and a black/white radial gradient.

I created a fiddle linked below to show you an example. The key here is that you need to structure your data to also include the percentage that should not have the red-gradient applied. Using the example above, we have three chunks with red and the rest as unfilled. Imagine the data set like so:

    var data = [{
    percent: 10,
    pie: 0
}, {
    percent: 13,
    pie: 1
}, {
    percent: 13,
    pie: 1
}, {
    percent: 6,
    pie: 1
}, {
    percent: 56,
    pie: 0
}];

So we have the percent and we also flag which chunks should be red and which chunk should be the unfilled section using the pie attribute.

You can use whatever data set you wish but I'm just using this as an example.

So next thing is to create your SVG element:

 var width = 400;
    var height = 400;
    var radius = Math.min(width, height) / 2;

    var arc = d3.svg.arc()
     .outerRadius(radius - 10)
     .innerRadius(((radius - 10) / 5) * 4);


    var pie = d3.layout.pie()
    .sort(null)
    .value(function (d) { return d.percent });

    var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

and after this we will create the two gradients to style the pie chunks. So first one is the linear red gradient:

// append a defs tag to SVG, This holds all our gradients and can be used
//by any element within the SVG we append it to
var defs = svg.append("svg:defs")

//next we append a linear gradient 
var red_gradient = defs.append("svg:linearGradient")
  .attr("id", "gradient")
  .attr("x1", "0%")
  .attr("y1", "0%")
  .attr("x2", "0%")
  .attr("y2", "100%")
  .attr("spreadMethod", "pad");

//first dark red color
    red_gradient.append("svg:stop")
        .attr("offset", "0%")
        .attr("stop-color", "rgb(221,48,2)")
        .attr("stop-opacity", 1);
//second light red color
    red_gradient.append("svg:stop")
        .attr("offset", "100%")
        .attr("stop-color", "rgb(247, 78, 1)")
        .attr("stop-opacity", 1);

Then we append the radial gradient for the unfilled part. This one is a little tricker because we need to move the gradient with a transform to get the right radial center. If you translate it half the width and height I think it should work out.

var radial_gradient = defs.append("radialGradient")
.attr("gradientUnits", "userSpaceOnUse")
.attr("cx", '50%')
.attr("cy", '50%')
.attr("r", "75%")
.attr("fx", '50%')
.attr("fy", '50%')
.attr('gradientTransform', "translate(-200,-200)")
.attr("id", 'gradient2');
 radial_gradient.append("stop").attr("offset", "0%").style("stop-color", "black");
 radial_gradient.append("stop").attr("offset", "55%").style("stop-color", "white");
 radial_gradient.append("stop").attr("offset", "95%").style("stop-color", "black");

Once we have set up the gradients, we can add the pie:

   var g = svg.selectAll(".arc")
     .data(pie(data))
     .enter().append("g")
     .attr("class", "arc");

    // we create a function to append the different chucks of the pie. 
    // we check the pie attribute from the data and apply the correct gradient.

    g.append("path")
    .attr("d", arc)
    .style("fill", function (d) {
        if (d.data.pie === 1) {
            console.log('true' + d.data.pie);
            return "url(#gradient)"
        }
        else {
            console.log('false' + d.data.pie);
            return "url(#gradient2)"
        }
    })

JSFiddle: http://jsfiddle/staceyburnsy/afo292ty/2/

本文标签: javascriptHow to draw gradient arc using d3jsStack Overflow