Wie @Miichi erwähnt, dies ein Fehler in nvd3 ist ...
Ich bin überrascht, dass sie eine ToDo „herauszufinden, warum der Wert verschoben zu werden scheint“, weil es ziemlich offensichtlich ist ... Die Balken verwenden eine Ordinalskala mit .rangeBands()
, und die Linie verwendet eine lineare Skala, und die zwei Maßstäbe werden niemals so hergestellt, dass sie sich aufeinander beziehen, außer dass sie dieselben Endpunkte teilen.
Eine Lösung wäre, die Ordinalskala von den Balken zu nehmen und sie einfach um die Hälfte der Balkenbreite anzupassen, um die x-Skala der Linie zu bilden. Das würde die Linienpunkte in die Mitte der Balken bringen. Ich stelle mir vor, dass etwas Ähnliches in der nv.models.linePlusBarChart
, die @LarsKotthoff erwähnt, getan wird.
Grundsätzlich Ihre Linie der x-Skala würde wie folgt aussehen:
var xScaleLine = function(d) {
var offset = xScaleBars.rangeBand()/2;
return xScaleBars(d) + offset;
};
... wo xScaleBars
die x-Skala für den Stegabschnitt des Diagramms verwendet wird.
Durch das Durchkämmen des Quellcodes für nvd3 scheint es, dass diese Skala als chart.bars1.scale()
zugänglich ist.
Vielleicht eines Tages werden die Autoren von nvd3 entscheiden, dass ihre Kluft einer Bibliothek einige Dokumentation verdient. Für jetzt kann ich Ihnen die Art der Sache zeigen, die das Problem lösen würde, indem Sie ein kundenspezifisches Diagramm machen und zeigen, wie die zwei Skalen sich beziehen würden.
Zuerst werde ich Ihre Daten verwenden, aber die Linien- und Balkendaten in zwei Arrays trennen:
var barData = [
{"x":0,"y":6500},
{"x":1,"y":8600},
{"x":2,"y":17200},
{"x":3,"y":15597},
{"x":4,"y":8600},
{"x":5,"y":814}
];
var lineData = [
{"x":0,"y":2},
{"x":1,"y":2},
{"x":2,"y":4},
{"x":3,"y":6},
{"x":4,"y":2},
{"x":5,"y":5}
];
Dann die Waage für die Stäbe aufgebaut. Für die x-Skala verwende ich eine ordinale Skala und rangeRoundBands
mit dem Standard-Gruppenabstand für nvd3 multiBar
, die 0,1 ist. Für die y-Skala verwende ich eine reguläre lineare Skala, die .nice()
verwendet, so dass die Skala nicht auf einem unangenehmen Wert endet, wie es standardmäßig in nvd3 ist. Wenn Sie über dem größten Wert Platz haben, erhalten Sie einen Kontext, der "schön" ist, wenn Sie versuchen, ein Diagramm zu interpretieren.
var xScaleBars = d3.scale.ordinal()
.domain(d3.range(barData.length))
.rangeRoundBands([0, w], 0.1);
var yScaleBars = d3.scale.linear()
.domain([0, d3.max(barData, function(d) {return d.y;})])
.range([h, 0])
.nice(10);
Jetzt hier ist der wichtige Teil. Für die x-Skala Linie, keinen separaten Maßstab machen, aber nur es macht eine Funktion der x-Skala Bars:
var xScaleLine = function(d) {
var offset = xScaleBars.rangeBand()/2;
return xScaleBars(d) + offset;
};
Hier ist das komplette Beispiel als JSBin.Ich habe versucht, die wichtigsten Abschnitte mit Kommentaren zu dokumentieren, so dass es einfach ist, der Gesamtlogik zu folgen. Wenn Sie aus dem nvd3-Quellcode genau herausfinden können, wie jedes der Elemente des multiChart aufgerufen wird und wie Sie die einzelnen Maßstäbe der Bestandteile einstellen, dann können Sie vielleicht einfach den neuen Maßstab einstecken.
Mein Gefühl ist, dass Sie einen ziemlich guten Griff haben müssen, wie d3 arbeitet, um etwas Nützliches mit nvd3 zu tun, und wenn Sie es anpassen möchten, sind Sie wahrscheinlich besser dran nur Ihre eigenen Diagramm rollen. Auf diese Weise haben Sie vollständige Kenntnisse und Kontrolle darüber, was die Elementklassen und Variablennamen der Teile Ihres Diagramms sind, und können mit ihnen alles machen, was Sie wollen. Wenn nvd3 jemals die richtige Dokumentation bekommt, wird dies vielleicht eine einfache Lösung. Viel Glück, und ich hoffe, das hilft dir wenigstens beim Einstieg.
Sie könnten stattdessen die Linie plus Balkendiagramm verwenden. –
Danke für die Antwort. Aber in 'nv.models.linePlusBarChart' kann ich Attribut' bar' 'true | false' verwenden, ich habe keine Optionen mehr für verschiedene Diagramme. – Orbitum
Zusätzlich muss ich positionieren - auf welcher Achse Linien stehen und auf welchen Balken. 'multiChart' erlaubt das. – Orbitum