Einfaches Balkendiagramm
Verwendung von Bars3D in einer QML-Anwendung.
Simple Bar Graph zeigt, wie man mit Bars3D und QML ein einfaches 3D-Balkendiagramm erstellt.
In den folgenden Abschnitten wird beschrieben, wie Sie Serien umschalten und mehr als eine Serie gleichzeitig anzeigen können. Weitere Informationen zur grundlegenden Funktionalität von QML-Anwendungen finden Sie unter Einfaches Streudiagramm.
Ausführen des Beispiels
Zum Ausführen des Beispiels von Qt Creatorzu starten, öffnen Sie den Modus Welcome und wählen Sie das Beispiel unter Examples aus. Weitere Informationen finden Sie unter Erstellen und Ausführen eines Beispiels.
Daten
Der Beispieldatensatz besteht aus den monatlichen Einnahmen und Ausgaben eines fiktiven Unternehmens über mehrere Jahre. Die Daten sind in einem Listenmodell in Data.qml
wie folgt definiert:
ListModel { id: dataModel ListElement{ timestamp: "2016-01"; expenses: "-4"; income: "5" } ListElement{ timestamp: "2016-02"; expenses: "-5"; income: "6" } ListElement{ timestamp: "2016-03"; expenses: "-7"; income: "4" } ...
Jedes Datenelement hat drei Rollen: Zeitstempel, Einnahmen und Ausgaben. Der Zeitstempelwert hat das Format: <four digit year>-<two digit month>
. Normalerweise würden Sie Jahre und Monate den Zeilen und Spalten eines Balkendiagramms zuordnen, aber Sie können nur entweder Einnahmen oder Ausgaben als Wert anzeigen.
Fügen Sie nun die Daten in das Diagramm Bars3D ein. Erstellen Sie darin zwei Bar3DSeries, beginnend mit einer Reihe für die Einnahmen:
Bar3DSeries { id: barSeries itemLabelFormat: "Income, @colLabel, @rowLabel: @valueLabel" baseGradient: barGradient ItemModelBarDataProxy { id: modelProxy itemModel: graphData.model rowRole: "timestamp" columnRole: "timestamp" valueRole: "income" rowRolePattern: /^(\d\d\d\d).*$/ columnRolePattern: /^.*-(\d\d)$/ rowRoleReplace: "\\1" columnRoleReplace: "\\1" multiMatchBehavior: ItemModelBarDataProxy.MultiMatchBehavior.Cumulative } ...
Die Daten werden an die Eigenschaft itemModel
der ItemModelBarDataProxy innerhalb der Reihe angehängt. Für valueRole
geben Sie das Feld income
an, da es den gewünschten Wert enthält. Die Ermittlung der Jahre und Monate ist etwas komplizierter, da sie sich beide im selben Feld befinden. Um diese Werte zu extrahieren, geben Sie das Feld timestamp
sowohl für rowRole
als auch für columnRole
an. Zusätzlich geben Sie ein Suchmuster und eine Ersetzungsregel für diese Rollen an, um den richtigen Teil des Feldinhalts für jede Rolle zu extrahieren. Das Suchmuster ist ein normaler regulärer JavaScript-Ausdruck, und die Ersetzungsregel gibt an, durch was der Feldinhalt, der mit dem regulären Ausdruck übereinstimmt, ersetzt wird. In diesem Fall wird der gesamte Feldinhalt nur durch das Jahr oder den Monat ersetzt, der die erste erfasste Teilzeichenkette für beide Zeilen und Spalten ist. Weitere Informationen über die Ersetzungsfunktion mit regulären Ausdrücken finden Sie in der Dokumentation der Funktion QString::replace(const QRegExp &rx, const QString &after).
Die Eigenschaft multiMatchBehavior
gibt an, was zu tun ist, wenn mehrere Elementmodellelemente auf dieselbe Zeilen-/Spaltenkombination passen. In diesem Fall werden ihre Werte addiert. Diese Eigenschaft hat keine Auswirkungen, wenn Werte für jeden Monat angezeigt werden, da es in unserem Artikelmodell keine doppelten Monate gibt. Sie wird jedoch später relevant, wenn Sie die Jahressummen anzeigen möchten.
Fügen Sie dann eine weitere Reihe für die Ausgaben hinzu:
Bar3DSeries { id: secondarySeries visible: false itemLabelFormat: "Expenses, @colLabel, @rowLabel: -@valueLabel" baseGradient: secondaryGradient ItemModelBarDataProxy { id: secondaryProxy itemModel: graphData.model rowRole: "timestamp" columnRole: "timestamp" valueRole: "expenses" rowRolePattern: /^(\d\d\d\d).*$/ columnRolePattern: /^.*-(\d\d)$/ valueRolePattern: /-/ rowRoleReplace: "\\1" columnRoleReplace: "\\1" multiMatchBehavior: ItemModelBarDataProxy.MultiMatchBehavior.Cumulative } ...
Das Modell enthält Ausgaben als negative Werte, aber sie könnten als positive Balken dargestellt werden, um einen einfachen Vergleich mit den Einnahmen zu ermöglichen. Verwenden Sie die valueRolePattern
, um das Minuszeichen zu entfernen, und es muss keine Ersatzzeichenfolge angegeben werden, da die Standard-Ersatzzeichenfolge eine leere Zeichenfolge ist.
Verwenden Sie die Eigenschaft visible
der Reihe, um die zweite Reihe vorerst auszublenden.
Benutzerdefinierte Achsenbeschriftungen
Axes.qml
definiert die Kategoriebeschriftungen für die Spaltenachse neu, da die Daten Zahlen für Monate enthalten, die die Beschriftungen überladen würden:
Category3DAxis { id: columnAxis labels: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] labelAutoAngle: 30 }
Um die Achsenbeschriftungen bei niedrigen Kamerawinkeln besser lesbar zu machen, stellen Sie die automatische Drehung der Achsenbeschriftung ein.
Umschalten von Serien
Richten Sie unter main.qml
das Diagramm und verschiedene UI-Elemente ein. Es gibt drei interessante Codeblöcke, die hier hervorzuheben sind. Der erste zeigt, wie man die visualisierten Daten zwischen Einnahmen, Ausgaben und beidem ändern kann, indem man einfach die Sichtbarkeit der beiden Reihen ändert:
onClicked: { if (text === "Show Expenses") { barSeries.visible = false secondarySeries.visible = true barGraph.valueAxis.labelFormat = "-%.2f M\u20AC" secondarySeries.itemLabelFormat = "Expenses, @colLabel, @rowLabel: @valueLabel" text = "Show Both" } else if (text === "Show Both") { barSeries.visible = true barGraph.valueAxis.labelFormat = "%.2f M\u20AC" secondarySeries.itemLabelFormat = "Expenses, @colLabel, @rowLabel: -@valueLabel" text = "Show Income" } else { // text === "Show Income" secondarySeries.visible = false text = "Show Expenses" } }
Das Achsenbeschriftungsformat und die Formate der Elementauswahl werden so angepasst, dass das negative Vorzeichen für Ausgaben, die eigentlich als positive Werte aufgelöst wurden, korrekt angezeigt wird.
Im zweiten interessanten Block werden die visualisierten Daten durch Anpassung der Proxy-Eigenschaften geändert:
onClicked: { if (text === "Show yearly totals") { modelProxy.autoRowCategories = true secondaryProxy.autoRowCategories = true modelProxy.columnRolePattern = /^.*$/ secondaryProxy.columnRolePattern = /^.*$/ graphAxes.value.autoAdjustRange = true barGraph.columnAxis = graphAxes.total text = "Show all years" } else if (text === "Show all years") { modelProxy.autoRowCategories = true secondaryProxy.autoRowCategories = true modelProxy.columnRolePattern = /^.*-(\d\d)$/ secondaryProxy.columnRolePattern = /^.*-(\d\d)$/ graphAxes.value.min = 0 graphAxes.value.max = 35 barGraph.columnAxis = graphAxes.column text = "Show 2020 - 2022" } else { // text === "Show 2020 - 2022" // Explicitly defining row categories, since we do not want to show data for // all years in the model, just for the selected ones. modelProxy.autoRowCategories = false secondaryProxy.autoRowCategories = false modelProxy.rowCategories = ["2020", "2021", "2022"] secondaryProxy.rowCategories = ["2020", "2021", "2022"] text = "Show yearly totals" } }
Um die Jahressummen anzuzeigen, werden die zwölf Monate eines jeden Jahres zu einem einzigen Balken zusammengefasst. Dies wird durch die Angabe einer columnRolePattern
erreicht, die mit allen Modellelementen übereinstimmt. Auf diese Weise wird die Reihe nur eine einzige Spalte haben. Die zuvor für den Proxy angegebene kumulative multiMatchBehavior
wird jetzt relevant, da die Werte aller zwölf Monate jedes Jahres zu einem einzigen Balken addiert werden.
Um nur eine Untergruppe von Jahren anzuzeigen, setzen Sie autoRowCategories
für das Element ItemModelBarDataProxy auf false und definieren Sie die Zeilenkategorien explizit. Auf diese Weise werden nur die Elemente in den angegebenen Zeilenkategorien angezeigt.
Der dritte interessante Block zeigt, wie man den Zeilen- und Spaltenindex eines Elements erhält, wenn man die Zeilen- und Spaltenwerte kennt, indem man die Methoden ItemModelBarDataProxy rowCategoryIndex()
und columnCategoryIndex()
verwendet:
var timestamp = graphData.model.get(mainview.currentRow).timestamp var pattern = /(\d\d\d\d)-(\d\d)/ var matches = pattern.exec(timestamp) var rowIndex = modelProxy.rowCategoryIndex(matches[1]) var colIndex if (barGraph.columnAxis == graphAxes.total) colIndex = 0 // Just one column when showing yearly totals else colIndex = modelProxy.columnCategoryIndex(matches[2]) if (selectedSeries.visible) mainview.selectedSeries.selectedBar = Qt.point(rowIndex, colIndex) else if (barSeries.visible) barSeries.selectedBar = Qt.point(rowIndex, colIndex) else secondarySeries.selectedBar = Qt.point(rowIndex, colIndex)
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.