Ich versuche, eine d3-Legendenzeichnungsfunktion zu ersetzen, die die manuelle Erstellung und Platzierung der Legendenelemente mit .data()
verwendet.d3.js: Legenden mit dynamischer Elementbreite
Ich war in der Lage, alles funktionierte, bis auf eine Sache: mit dem manuellen Durchlaufen der Daten-Array konnte ich sicherstellen, gleiche Abstände zwischen den Legendenelementen mit einer currentX
Tracker-Variable. Mit .data()
kann ich jedoch nicht auf die anderen Elemente verweisen und muss Boxen mit fester Breite verwenden, was der Designer hasst (und mich auch).
Mit dem folgenden Code, wie mache ich den neuen Code (obere Zeile) verhalten sich genau wie der alte Code (untere Reihe)?
(Bitte schlagen nicht vor, dass ich eine Legende Bibliothek verwenden, gibt es viele Event-Handling und mehr Material in der „realen“ Code, auf dem diese Testfall extrahiert wurde)
var config = {
circleYCenter: 170,
circleXCenter: 150,
legendMarginTop: 52,
legendMarginInner: 18,
legendDotHeight: 8,
legendDotWidth: 16,
};
var colors = {
'lightyellow': '#FEE284',
'darkblue': '#2872A3',
'dirtyorange': '#E68406',
};
function drawLegend(container, map) {
var legendGroup = container.append("g").attr({
"transform": "translate(0,50)",
"class": "legendGroup"
});
//New code
var elGroup = legendGroup.selectAll("g").data(map).enter().append("g").attr({
transform: function(d, i) {
return "translate(" + (i * 100) + ",0)"
}
});
elGroup.append("text").text(function(d) {
return d.label;
}).attr({
x: config.legendDotWidth + config.legendMarginInner
});
elGroup.append("rect").attr({
x: 0,
width: config.legendDotWidth,
y: -5,
height: config.legendDotHeight,
"fill": function(d) {
return d.color;
}
});
//Old code
var currentX = 0;
map.forEach(function(el, key) {
var elGroup = legendGroup.append("g").attr("transform", "translate(" + currentX + ",100)");
elGroup.append("rect").attr({
x: 0,
width: config.legendDotWidth,
y: -5,
height: config.legendDotHeight,
"fill": el.color
});
elGroup.append("text").attr({
"x": (config.legendDotWidth + 10),
"y": 0,
"alignment-baseline": "middle"
}).text(el.label);
currentX += elGroup.node().getBBox().width + config.legendMarginInner;
});
}
drawLegend(d3.select("svg"), [{
label: "foo",
color: colors.dirtyorange
}, {
label: "Banana",
color: colors.darkblue
}, {
label: "baz",
color: colors.lightyellow
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width=600 height=300></svg>
Vielen Dank! – Skynet
@Cyril, könntest du bitte in diese Ausgabe schauen https://jsfiddle.net/praveenuics/k1xssj9h/, Seine über die Legenden, werde ich mehrzeiliges Diagramm verwenden, wo es ungefähr 20 Trendlinie gibt, wo ich Legenden zeigen muss (20 In diesem Fall sind alle Legenden nebeneinander gestapelt, bis sie das Ende erreichen, aber ich brauche sie mit der Svg-Box/Scroll wird auch funktionieren, jede Hilfe wird sehr geschätzt. – Praveen