Ich versuche, eine spezielle Art von Donut-Diagramm in D3, die verschiedene Ringe für positive und negative Werte enthalten wird. Die Werte können größer als 100% oder kleiner als -100% sein, so dass ein Bogen den verbleibenden Wert darstellt. Unten ist das Beispielbild des Diagramms: Spezielle Donut-Tabelle mit verschiedenen Ringen/Bögen für positive und negative Werte
Die erste positive Kategorie (Category_1 - Gray) Wert ist 80, so ist es 80% füllen den Kreis mit grau, so dass die 20% für nächste positive Kategorie. Der nächste positive Kategoriewert (Category_2 - Orange) ist 160. Also verwendet er zuerst die 20%, die von Category_1 übriggeblieben sind (Wert 140, der noch übrig ist). Dann füllt es den nächsten Kreis (aufwärts) mit 100% (40 Wert ist jetzt übrig) und für den verbleibenden Wert (40) wird ein Teilkreis nach oben erzeugt.
Jetzt haben wir Category_3 (dunkelrot) als negativ (-120%), also wenn man einen nach innen gerichteten Kreis erstellt und ihn zu 100% füllt (20 Wert jetzt links) und dann einen nach innen gerichteten Bogen erzeugt verbleibender Wert (20). Wir haben eine andere negative Kategorie (Category_4 - rot), also beginnt sie dort, wo die vorherige negative Kategorie (Category_3) endete und füllt 20% von dort.
Edit 3: Ich habe ein sehr einfaches Arc-basiertes Donut-Diagramm erstellt, und wenn der Gesamtwert 100 übersteigt, kann ich für die verbleibenden Werte äußere Ringe erstellen. Unten ist die JSFiddle Link:
http://jsfiddle.net/rishabh1990/zmuqze80/
data = [20, 240];
var startAngle = 0;
var previousData = 0;
var exceedingData;
var cumulativeData = 0;
var remainder = 100;
var innerRadius = 60;
var outerRadius = 40;
var filledFlag;
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
for (var i = 0; i < data.length; i++) {
filledFlag = 0;
exceedingData = 0;
console.log("---------- Iteration: " + (i + 1) + "---------");
if (data[i] > remainder) {
filledFlag = 1;
exceedingData = data[i] - remainder;
console.log("Exceeding: " + exceedingData);
data[i] = data[i] - exceedingData;
data.splice(i + 1, 0, exceedingData);
}
if(filledFlag === 1) {
cumulativeData = 0;
} else {
cumulativeData += data[i];
}
console.log("Previous: " + previousData);
console.log("Data: " + data, "Current Data: " + data[i]);
var endAngle = (previousData + (data[i]/50)) * Math.PI;
console.log("Start " + startAngle, "End " + endAngle);
previousData = previousData + data[i]/50;
//if(i===1) endAngle = 1.4 * Math.PI;
//if(i===2) endAngle = 2 * Math.PI;
var vis = d3.select("#svg_donut");
arc.startAngle(startAngle).endAngle(endAngle);
vis.append("path")
.attr("d", arc)
.attr("transform", "translate(200,200)")
.style("fill", function(d) {
if (i === 0) return "red";
//if (i === 1) return "green";
//if (i === 2) return "blue"
//if (i === 3) return "orange"
//if (i === 4) return "yellow";
});
if (exceedingData > 0) {
console.log("Increasing Radius From " + outerRadius + " To " + (outerRadius + 40));
outerRadius = outerRadius + 22;
innerRadius = innerRadius + 22;
arc.innerRadius(innerRadius).outerRadius(outerRadius);
console.log("Outer: ", outerRadius);
}
if (remainder === 100) {
remainder = 100 - data[i];
} else {
remainder = 100 - cumulativeData;
};
if (filledFlag === 1) {
remainder = 100;
}
console.log("Remainder: " + remainder);
startAngle = endAngle;
}
Bitte einige Ideen für die Umsetzung teilen.
Was soll es tun, wenn zwei positive Werte> 100% sind? Wie wäre es, wenn Kategorie 1 180% wäre? Wie würde es zusammen mit Kategorie 2 erscheinen? – meetamit
@meetamit Es würde so aussehen: http://jsfiddle.net/dw0sx79v/3/ – Rishabh
Got it. Dies ist ein interessantes Problem, würde aber eine Weile dauern, um ein voll funktionsfähiges Beispiel zu erhalten. Ich denke, ich kann helfen, bin mir aber nicht sicher, wann ich dazu komme. Vielleicht morgen oder nachher. Erwägen Sie in der Zwischenzeit, eine Prämie für diese Frage zu posten. Sie werden mehr Augäpfel auf diese Weise bekommen – meetamit