我收到如下所示的JSON响应:
var dataset = [
{positive: 20, negative: 40 ,total: 100}
];
并且我想以类似于以下的甜甜圈图显示数据:
正数将为20/100
,负数为40/100
,其余将为total-negative-positive
,即100-40-20 = 60
在这种情况下。
这非常有效,但我希望在D3图表中显示它:
Chart.types.Doughnut.extend({
name: "DoughnutAlt",
initialize: function (data) {
Chart.types.Doughnut.prototype.initialize.apply(this, arguments);
// save the actual clear method
var originalClear = this.clear;
// override the clear method to draw the background after each clear
this.clear = function () {
originalClear.apply(this, arguments)
var ctx = this.chart.ctx;
// use any one of the segments to get the inner and outer radius and center x and y
var firstSegment = this.segments[0];
// adjust 0.3 to increaase / decrease the width of the background
var gap = (firstSegment.outerRadius - firstSegment.innerRadius) * (1 - 0.3) / 2;
ctx.save();
ctx.fillStyle = "#EEE";
ctx.beginPath();
ctx.arc(firstSegment.x, firstSegment.y, firstSegment.outerRadius - gap, 0, 2 * Math.PI);
ctx.arc(firstSegment.x, firstSegment.y, firstSegment.innerRadius + gap, 0, 2 * Math.PI, true);
ctx.closePath();
ctx.fill();
ctx.restore();
}
}
});
var pointsUsed = [
{
value: 20,
color: "#c7003b",
},
{
value: 40,
color: "#000",
},
{
value: 60,
color: "transparent",
},
];
var pointsUsed_ctx = document.getElementById("pointsUsed").getContext("2d");
var pointsUsed = new Chart(pointsUsed_ctx).DoughnutAlt(pointsUsed, {
segmentShowStroke: false,
segmentStrokeWidth: 0,
percentageInnerCutout: 87,
showTooltips: false,
animationEasing: 'easeInOutCubic',
responsive: true
});
<script src="https://rawgit.com/nnnick/Chart.js/v1.0.2/Chart.min.js"></script>
<canvas id="pointsUsed" height="200" width="200"></canvas>
因此,我使用了响应式d3图表来显示此数据,并调整了数据集以包含总数。我要做的是使未使用零件的弧(总计-正-负)具有更细的弧。
var dataset = {
numbers: [20, 40, 40]
};
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 - 100)
.outerRadius(radius - 20);
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", 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);
var timeout = setTimeout(function () {
d3.select("input[value=\"oranges\"]").property("checked", true).each(change);
}, 2000);
function createChart() {
clearTimeout(timeout);
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
};
}); // store the initial values
path.exit()
.transition()
.duration(750)
.attrTween('d', arcTweenOut)
.remove() // now remove the exiting arcs
path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
}
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function (t) {
return arc(i(t));
};
}
function arcTweenOut(a) {
var i = d3.interpolate(this._current, { startAngle: Math.PI * 2, endAngle: Math.PI * 2, value: 0 });
this._current = i(0);
return function (t) {
return arc(i(t));
};
}
function type(d) {
d.value = +d.value;
return d;
}
createChart(dataset);
body {
margin: auto;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script>
<div id="Donut-chart"></div>
答案 0 :(得分:0)
只需设置第二个电弧发生器即可产生较细的线。在最后一个数据点上使用它:
var dataset = {
numbers: [20, 40, 40]
};
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 - 100)
.outerRadius(radius - 20);
var arcThin = d3.svg.arc()
.innerRadius(radius - 80)
.outerRadius(radius - 40);
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,i){
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);
var timeout = setTimeout(function () {
d3.select("input[value=\"oranges\"]").property("checked", true).each(change);
}, 2000);
function createChart() {
clearTimeout(timeout);
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
};
}); // store the initial values
path.exit()
.transition()
.duration(750)
.attrTween('d', arcTweenOut)
.remove() // now remove the exiting arcs
path.transition().duration(750).attrTween("d", arcTween); // redraw the arcs
}
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);
body {
margin: auto;
position: relative;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.0.0/d3.min.js"></script>
<div id="Donut-chart"></div>