甜甜圈图中的过渡色

时间:2018-07-03 07:55:18

标签: javascript d3.js charts

我有一个甜甜圈图,显示的评分超过10。如果评分> 5,它将显示为红色,否则显示为绿色。我还向图表添加了动画,以便评分逐渐提高。我需要做的唯一更改是,如果评级大于5,则评级弧应从绿色开始,一旦超过5,则应变为红色。

这是代码笔网址:https://codepen.io/javacodenet/pen/pKGmRx

var duration = 1500,
  transition = 200,
  percent = 7;
var width = 260;
var height = 260;
var thickness = 30;
var anglesRange = 0.75 * Math.PI
var dataset = {
    lower: calcPercent(0),
    upper: calcPercent(percent)
  },
  radius = Math.min(width, height) / 2;
var colors = ["#fb4f5d", "#efefef"]
var arc = d3.arc()
  .innerRadius(radius - thickness)
  .outerRadius(radius);

var pie = d3.pie()
  .value(function(d) {
    return d;
  })
  .sort(null)
  .startAngle(anglesRange * -1)
  .endAngle(anglesRange);

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

var path = svg.selectAll("path")
  .data(pie(dataset.lower))
  .enter().append("path")
  .attr('fill', '#efefef')
  .attr("d", arc)
  .each(function(d) {
    this._current = d;
  });

var text = svg.append("text")
  .attr("text-anchor", "middle")
  .attr("dy", ".3em");

var progress = 0;
format = d3.format("0");
var timeout = setTimeout(function() {
  clearTimeout(timeout);
  path = path.data(pie(dataset.upper))
    .attr('fill', (d, i) => {
      return i == 0 ? (d.value > 5 ? '#fb4f5d' : '#00FF00') : '#efefef';
    });
  path.transition().duration(duration).attrTween("d", function(a) {
    var i = d3.interpolate(this._current, a);
    var i2 = d3.interpolateNumber(progress, percent)
    console.log(i2);
    this._current = i(0);
    return function(t) {
      text.text(Math.round(i2(t)));
      return arc(i(t));
    };
  });
}, 200);

function calcPercent(percent) {
  return [percent, 10 - percent];
};
body {
  width: 100%;
  height: 100%;
  font-family: Lora, "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: #fff;
  background-color: #000;
}

path.color0 {
  fill: #fff;
}

path.color1 {
  fill: rgba(255, 255, 255, .3);
}

text {
  font-size: 7em;
  font-weight: 400;
  line-height: 16em;
  fill: #fff;
}
<html>
<head>
  <script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
  <div id="chart"></div>
</body>
</html>

2 个答案:

答案 0 :(得分:1)

您所需的结果并不十分清楚:您希望单个<path>元素超过5时变成红色,还是想要两个<path>元素,其中一个从0涂成绿色?到5,另一个从5到7涂成红色?

如果前者是正确的,只需将"fill"移动到attrTween方法内部。这是您所做的更改的代码:

var duration = 1500,
  transition = 200,
  percent = 7;
var width = 260;
var height = 260;
var thickness = 30;
var anglesRange = 0.75 * Math.PI
var dataset = {
    lower: calcPercent(0),
    upper: calcPercent(percent)
  },
  radius = Math.min(width, height) / 2;
var colors = ["#fb4f5d", "#efefef"]
var arc = d3.arc()
  .innerRadius(radius - thickness)
  .outerRadius(radius);

var pie = d3.pie()
  .value(function(d) {
    return d;
  })
  .sort(null)
  .startAngle(anglesRange * -1)
  .endAngle(anglesRange);

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

var path = svg.selectAll("path")
  .data(pie(dataset.lower))
  .enter().append("path")
  .attr('fill', '#efefef')
  .attr("d", arc)
  .each(function(d) {
    this._current = d;
  });

var text = svg.append("text")
  .attr("text-anchor", "middle")
  .attr("dy", ".3em");

var progress = 0;
format = d3.format("0");
var timeout = setTimeout(function() {
  clearTimeout(timeout);
  path = path.data(pie(dataset.upper));
  path.transition().duration(duration).attrTween("d", function(a, index) {
    var self = this;
    var i = d3.interpolate(this._current, a);
    var i2 = d3.interpolateNumber(progress, percent)
    this._current = i(0);
    return function(t) {
      d3.select(self).attr('fill', index !== 0 ? '#efefef' : i2(t) > 5 ? '#fb4f5d' : '#00FF00');
      text.text(Math.round(i2(t)));
      return arc(i(t));
    };
  });
}, 200);

function calcPercent(percent) {
  return [percent, 10 - percent];
};
body {
  width: 100%;
  height: 100%;
  font-family: Lora, "Helvetica Neue", Helvetica, Arial, sans-serif;
  color: #fff;
  background-color: #000;
}

path.color0 {
  fill: #fff;
}

path.color1 {
  fill: rgba(255, 255, 255, .3);
}

text {
  font-size: 7em;
  font-weight: 400;
  line-height: 16em;
  fill: #fff;
}
<html>

<head>
  <script src="https://d3js.org/d3.v5.min.js"></script>
</head>

<body>
  <div id="chart"></div>
</body>

</html>

答案 1 :(得分:0)

基本上,您可以解决的问题是:

  • 添加d3属性以填充甜甜圈的颜色
  • 评估光标的位置,以便根据此演算返回绿色或红色

让我们这样编码:

    var duration = 1500,
    transition = 200,
    percent = 7;
var width = 260;
var height = 260;
var thickness = 30;
  var anglesRange = 0.75 * Math.PI
var dataset = {
            lower: calcPercent(0),
            upper: calcPercent(percent)
        },
        radius = Math.min(width, height) / 2;
var colors = ["#fb4f5d", "#efefef"]
var arc = d3.arc()
.innerRadius(radius - thickness)
.outerRadius(radius);

var pie = d3.pie()
.value(function(d) { return d; })
.sort(null)
.startAngle(anglesRange * -1)
    	.endAngle( anglesRange);

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

var path = svg.selectAll("path")
                .data(pie(dataset.lower))
                .enter().append("path")
                .attr('fill', '#efefef')
                .attr("d", arc)
                .each(function (d) {
                    this._current = d;
                });

var text = svg.append("text")
        .attr("text-anchor", "middle")
        .attr("dy", ".3em");

var progress = 0;
 format = d3.format("0");
var timeout = setTimeout(function () {
    clearTimeout(timeout);
    path = path.data(pie(dataset.upper)).attr('e', (d,i)=> console.log(i));

    path.transition().duration(duration).attrTween("d", function (a) {
        var i = d3.interpolate(this._current, a);
        var i2 = d3.interpolateNumber(progress, percent)
        this._current = i(0);
        return function (t) {
            text.text( Math.round(i2(t)));
            return arc(i(t));
        };
    }).attrTween('fill', function (d,x) {
        var i = d3.interpolate(this._current, d);
        var i2 = d3.interpolateNumber(progress, percent)
        this._current = i(0);
        return function (t) {
            if(x){ return "#efefef"; }
            else { return i2(t) > 5 ? "#fb4f5d" : "#00FF00"; }
        }});
}, 200);

function calcPercent(percent) {
    return [percent, 10 - percent];
}; 
body {
    width: 100%;
    height: 100%;
    font-family: Lora,"Helvetica Neue",Helvetica,Arial,sans-serif;
    color: #fff;
    background-color: #000;
}
path.color0 {
    fill: #fff;
}
path.color1 {
    fill: rgba(255,255,255,.3);
}
text {
    font-size: 7em;
    font-weight: 400;
    line-height: 16em;
    fill: #fff;
}
<html>
  <head>
    <script src="https://d3js.org/d3.v5.min.js"></script>
  </head>
  <body>
    <div id="chart"></div>
  </body>
</html>