d3.js甜甜圈图-将阴影添加到突出显示的部分

时间:2019-08-19 10:25:26

标签: javascript d3.js

在我的项目中,我正在使用d3.js甜甜圈图来显示一些数据。单击每个弧形部分时,它将突出显示。要求是在单击时在突出显示的部分中添加阴影效果,因此它将突出显示更多。我正在使用笔触创建阴影效果,但它看起来不像阴影。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title> D3 Js Example </title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" media="screen" href="main.css" />
</head>
<body>

    <div id="my_dataviz"></div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.7/d3.min.js" ></script>
    <script>

        var lastSelected = "";
var firstSelected = "";

var width = 450
    height = 450
    margin = 40

var radius = Math.min(width, height) / 2 - margin

var normalArc = d3.arc().outerRadius(radius - 30).innerRadius(radius - 70);
var biggerArc = d3.arc().outerRadius(radius - 80).innerRadius(radius - 10);

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

var data = {a: 9, b: 20, c:30, d:8, e:12}

var color = d3.scaleOrdinal()
  .domain(data)
  .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"])

var pie = d3.pie()
  .value(function(d) {return d.value; })
var data_ready = pie(d3.entries(data))

  
svg
  .selectAll('whatever')
  .data(data_ready)
  .enter()
  .append('path')
  .attr('d', normalArc)
  .attr('fill', function(d){ return(color(d.data.key)) })
  .style("opacity", 0.7)
  .attr('d', function(d, index) {
        // If this is the first segment make it a wider arc
        if (index === 0) {
            firstSelected = this;
            return biggerArc(d);
        } else {
            return normalArc(d);
        }
    }).on("click", function(d) {
        if (firstSelected) {
            d3.select(firstSelected).attr("d", normalArc).style("stroke-width", "0px")
            firstSelected = false;
        }
        if (lastSelected) {
            d3.select(lastSelected).attr("d", normalArc).style("stroke-width", "0px")
        }
       d3.select(this).attr("d", biggerArc).style("stroke", "black").style("stroke-width", "10px")
        .style("stroke-opacity","0.08")
        .style('stroke-location',"outer")
        .style('paint-order','stroke')
        .style('stroke-linejoin',"round")

        lastSelected = this;
    })
    </script>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

经过数小时的搜索,我能够找到答案。我们需要为阴影创建过滤器,并将其附加到svg上,并在需要的弧形中添加过滤器作为属性

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title> D3 Js Example </title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" type="text/css" media="screen" href="main.css" />
</head>
<body>

    <div id="my_dataviz"></div>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.7/d3.min.js" ></script>
    <script>

        var lastSelected = "";
var firstSelected = "";

var width = 450
    height = 450
    margin = 40

var radius = Math.min(width, height) / 2 - margin

var normalArc = d3.arc().outerRadius(radius - 30).innerRadius(radius - 70);
var biggerArc = d3.arc().outerRadius(radius - 80).innerRadius(radius - 10);

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

 /* For the drop shadow filter... */
  var defs = svg.append("defs");

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

  filter.append("feGaussianBlur")
      .attr("in", "SourceAlpha")
      .attr("stdDeviation", 4)
      .attr("result", "blur");
  filter.append("feOffset")
      .attr("in", "blur")
      .attr("dx", 2)
      .attr("dy", 2)
      .attr("result", "offsetBlur");

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

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

var data = {a: 9, b: 20, c:30, d:8, e:12}

var color = d3.scaleOrdinal()
  .domain(data)
  .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"])

var pie = d3.pie()
  .value(function(d) {return d.value; })
var data_ready = pie(d3.entries(data))

  
svg
  .selectAll('whatever')
  .data(data_ready)
  .enter()
  .append('path')
  .attr('d', normalArc)
  .attr('fill', function(d){ return(color(d.data.key)) })
  .style("opacity", 0.7)
  .attr('d', function(d, index) {
        // If this is the first segment make it a wider arc
        if (index === 0) {
            firstSelected = this;
            return biggerArc(d);
        } else {
            return normalArc(d);
        }
    }).on("click", function(d) {
        if (firstSelected) {
            d3.select(firstSelected).attr("d", normalArc).attr("filter", "");
            firstSelected = false;
        }
        if (lastSelected) {
            d3.select(lastSelected).attr("d", normalArc).attr("filter", "");
        }
       d3.select(this).attr("d", biggerArc).attr("filter", "url(#dropshadow)");
        lastSelected = this;
    })
    
    if(firstSelected){
        d3.select(firstSelected).attr("filter", "url(#dropshadow)");
    }
    </script>
</body>
</html>