简体   繁体   中英

Pie chart drop-shadow or 3D d3.js

I'm new to D3.js and am starting to learn pie charts. I'm trying to create a drop shadow or add a 3d shape. I'm able to have the shadow appear but now each slice of the pie has its own. Is it possible to have the pie as a whole use the shadow rather than each individual slice? I'm hoping to make it sharp edged without a blur and one color.

To start with, I've been using this example that has been included in other posts. Please let me know if this is possible with a shadow or if there's another way to get this 3D shape. Thank you.

Snippets

var width = 500,
    height = 500,
    radius = Math.min(width, height) / 2.5;

var color = d3.scale.ordinal()
    .range(["#ED5545","#ED933A","#337382","#EDD55D","#64B5CE","#AA2731","#F7B166","#7DD886"])

var arc = d3.svg.arc()
    .outerRadius(radius - 40)
    .innerRadius(0);

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

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


//Drop Shadow    
var defs = svg.append("defs");

var filter = defs.append("filter")
      .attr("id", "dropshadow")

  filter.append("feGaussianBlur")
      .attr("in", "SourceAlpha")
      .attr("stdDeviation", 0)
      .attr("result", "blur");
  filter.append("feOffset")
      .attr("in", "blur")
      .attr("dx", 0)
      .attr("dy", 15)
      .attr("result", "offsetBlur");
   filter.append("feFlood")
        .attr("in", "offsetBlur")
        .attr("flood-color", "#93864d")
        .attr("flood-opacity", "1")
        .attr("result", "offsetColor");
    filter.append("feComposite")
        .attr("in", "offsetColor")
        .attr("in2", "offsetBlur")
        .attr("operator", "in")
        .attr("result", "offsetBlur");

  var feMerge = filter.append("feMerge");

  feMerge.append("feMergeNode")
      .attr("in", "offsetBlur")
  feMerge.append("feMergeNode")
      .attr("in", "SourceGraphic");

//CSV
d3.csv("foodData.csv", function(error, data) {

  data.forEach(function(d) {
    d.amount = +d.amount;
  });

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

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.food); });

});



.arc path {
  stroke: #93864d;
  stroke-width: 3;
}


 food,amount
 Pizza,30
 Burgers,20
 Seafood,2
 Junk,17
 bbq,7
 Other,4
 Mexican,10
 Vegetables,3`

The main issue is that you are appending the shadow to each wedge of the pie. As you've noted, this causes it to be appended to each slice. Instead, what you can do is create a circle behind the pie chart that is equal in size to the chart itself. Then all you have to do is append the blur/shadow/etc to that feature:

 var width = 400; var height = 400; var radius = 175; var svg = d3.select('body').append('svg') .attr('width',width) .attr('height',height); // you can use to groups to order elements, they appear in the order they are appended: var g1 = svg.append('g').attr('transform','translate('+width/2+','+height/2+')'); var g2 = svg.append('g').attr('transform','translate('+width/2+','+height/2+')'); // shadow stuff: var defs = svg.append("defs"); var filter = defs.append("filter") .attr("id", "dropshadow") filter.append("feGaussianBlur") .attr("in", "SourceAlpha") .attr("stdDeviation", 0) .attr("result", "blur"); filter.append("feOffset") .attr("in", "blur") .attr("dx", 0) .attr("dy", 15) .attr("result", "offsetBlur"); filter.append("feFlood") .attr("in", "offsetBlur") .attr("flood-color", "#93864d") .attr("flood-opacity", "1") .attr("result", "offsetColor"); filter.append("feComposite") .attr("in", "offsetColor") .attr("in2", "offsetBlur") .attr("operator", "in") .attr("result", "offsetBlur"); var feMerge = filter.append("feMerge"); feMerge.append("feMergeNode") .attr("in", "offsetBlur") feMerge.append("feMergeNode") .attr("in", "SourceGraphic"); // Now back to the pie chart: var data = [10,50,15,30,40,35]; var color = d3.schemeCategory10; var pie = d3.pie(); var path = d3.arc() .outerRadius(radius) .innerRadius(0); var arc = g2.selectAll(".arc") .data(pie(data)) .enter() .append('path') .attr('d',path) .attr('fill',function(d,i) { return color[i]; }); var shadow = g1.append('circle') .attr('r',radius) .attr("filter", "url(#dropshadow)"); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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