简体   繁体   English

D3甜甜圈图,负(逆时针)和正(顺时针)(角度是动态的)

[英]D3 donut chart for negative (anticlockwise) and positive (clockwise) (Angle being dynamic)

I get a JSON query and I want to present a positive (red) and negative (black) segment in the same graph. 我得到一个JSON查询,我想在同一张图中呈现一个正(红色)和负(黑色)段。 The positive is the first number in the JSON and the negative is the second one. 正数是JSON中的第一个数字,负数是第二个数字。

 var dataset = { numbers: [3200, 5400, 8600] }; var width = 960, height = 500, radius = Math.min(width, height) / 2; var enterClockwise = { startAngle: 0, endAngle: 0 }; var enterAntiClockwise = { startAngle: Math.PI * 2, endAngle: Math.PI * 2 }; //var color = d3.scale.category20(); var color = d3.scale.ordinal().range([d3.rgb("#c7003b"), d3.rgb('#000'), d3.rgb('#ccc'),d3.rgb('transparent')]) var pie = d3.layout.pie() .sort(null); var arc = d3.svg.arc() .innerRadius(radius - 80) .outerRadius(radius - 40); var arcThin = d3.svg.arc() .innerRadius(radius - 65) .outerRadius(radius - 55); var svg = d3.select('#Donut-chart').append('svg') .attr('id', 'Donut-chart-render') .attr("width", '100%') .attr("height", '100%') .attr('viewBox', (-width / 2) + ' ' + (-height / 2) + ' ' + width + ' ' + height) .attr('preserveAspectRatio', 'xMinYMin') var path = svg.selectAll("path") .data(pie(dataset.numbers)) .enter().append("path") .attr("fill", function (d, i) { return color(i); }) .attr("d", function(d){ return arc(enterClockwise); }) .each(function (d) { this._current = { data: d.data, value: d.value, startAngle: enterClockwise.startAngle, endAngle: enterClockwise.endAngle } }); path.transition() .duration(750) .attrTween("d", arcTween); function createChart() { path = path.data(pie(dataset[this.value])); path.enter().append("path") .attr("fill", function (d, i) { return color(i); }) .attr("d", arc(enterAntiClockwise)) .each(function (d) { this._current = { data: d.data, value: d.value, startAngle: enterAntiClockwise.startAngle, endAngle: enterAntiClockwise.endAngle }; }); } function arcTween(a, j) { var i = d3.interpolate(this._current, a); this._current = i(0); return function (t) { return (j === (dataset.numbers.length - 1)) ? arcThin(i(t)) : arc(i(t)); }; } /* function arcTweenOut(a, j) { var i = d3.interpolate(this._current, { startAngle: Math.PI * 2, endAngle: Math.PI * 2, value: 0 }); this._current = i(0); return function (t) { console.log(j === dataset.length - 1) return arc(i(t)); }; } */ function type(d) { d.value = +d.value; return d; } createChart(dataset); 
 @import url(https://fonts.googleapis.com/css?family=Karla);body{font-family:Karla,sans-serif;margin:auto;position:relative}.text{text-anchor:middle;color:#000;font-size:1.7em;font-weight:700;text-transform:uppercase}#legend{align-items:center;border-radius:5px;display:flex;height:0%;justify-content:space-around;width:95%;font-size:25px} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script> <div id="Donut-chart"></div> 

So, basically I want it to looks like this: 所以,基本上我希望它看起来像这样: 在此处输入图片说明

The positive will start from point 0 clockwise and the negative will start from the same point but anticlockwise. 正数将从顺时针的点0开始,负数将从相同的点但逆时针开始。

I had an idea of using the following: 我有使用以下方法的想法:

.each(function (d, i=0) {
    console.log(i);
    i++;
    if(i == 1){
      this._current = {
          data: d.data,
          value: d.value,
          startAngle: enterAntiClockwise.startAngle,
          endAngle: enterAntiClockwise.endAngle
      } 
    }
    else{
      this._current = {
          data: d.data,
          value: d.value,
          startAngle: enterClockwise.startAngle,
          endAngle: enterClockwise.endAngle
      } 
    }

});

which didn't work. 这没有用。

Simplest solution is to manipulate your data before appending the path. 最简单的解决方案是在添加路径之前操作数据。

var angleData = pie(dataset.numbers);
angleData[1].startAngle = 0;
angleData[1].endAngle = -angleData[1].endAngle + angleData[0].endAngle; // finding the clockwise angle
angleData[2].startAngle = angleData[0].endAngle; // shifting position of third arc
angleData[2].endAngle = (2*Math.PI) + angleData[1].endAngle;

 var dataset = { numbers: [3200, 5400, 8600] }; var width = 960, height = 500, radius = Math.min(width, height) / 2; var enterClockwise = { startAngle: 0, endAngle: 0 }; var enterAntiClockwise = { startAngle: Math.PI * 2, endAngle: Math.PI * 2 }; //var color = d3.scale.category20(); var color = d3.scale.ordinal().range([d3.rgb("#c7003b"), d3.rgb('#000'), d3.rgb('#ccc'),d3.rgb('transparent')]) var pie = d3.layout.pie() .sort(null); var arc = d3.svg.arc() .innerRadius(radius - 80) .outerRadius(radius - 40); var arcThin = d3.svg.arc() .innerRadius(radius - 65) .outerRadius(radius - 55); var svg = d3.select('#Donut-chart').append('svg') .attr('id', 'Donut-chart-render') .attr("width", '100%') .attr("height", '100%') .attr('viewBox', (-width / 2) + ' ' + (-height / 2) + ' ' + width + ' ' + height) .attr('preserveAspectRatio', 'xMinYMin').append("g").attr("class", "parent"); var angleData = pie(dataset.numbers); angleData[1].startAngle = 0; angleData[1].endAngle = -angleData[1].endAngle + angleData[0].endAngle; angleData[2].startAngle = angleData[0].endAngle; angleData[2].endAngle = (2*Math.PI) + angleData[1].endAngle; var path = svg.selectAll("path") .data(angleData) .enter().append("path") .attr("fill", function (d, i) { return color(i); }) .attr("d", function(d){ return arc(enterClockwise); }) .each(function (d) { this._current = { data: d.data, value: d.value, startAngle: enterClockwise.startAngle, endAngle: enterClockwise.endAngle } }); path.transition() .duration(750) .attrTween("d", arcTween); function createChart() { path = path.data(pie(dataset[this.value])); path.enter().append("path") .attr("fill", function (d, i) { return color(i); }) .attr("d", arc(enterAntiClockwise)) .each(function (d) { this._current = { data: d.data, value: d.value, startAngle: enterAntiClockwise.startAngle, endAngle: enterAntiClockwise.endAngle }; }); } function arcTween(a, j) { var i = d3.interpolate(this._current, a); this._current = i(0); return function (t) { return (j === (dataset.numbers.length - 1)) ? arcThin(i(t)) : arc(i(t)); }; } /* function arcTweenOut(a, j) { var i = d3.interpolate(this._current, { startAngle: Math.PI * 2, endAngle: Math.PI * 2, value: 0 }); this._current = i(0); return function (t) { console.log(j === dataset.length - 1) return arc(i(t)); }; } */ function type(d) { d.value = +d.value; return d; } 
 @import url(https://fonts.googleapis.com/css?family=Karla);body{font-family:Karla,sans-serif;margin:auto;position:relative}.text{text-anchor:middle;color:#000;font-size:1.7em;font-weight:700;text-transform:uppercase}#legend{align-items:center;border-radius:5px;display:flex;height:0%;justify-content:space-around;width:95%;font-size:25px} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script> <div id="Donut-chart"></div> 

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

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