Auf dieser Seite

Einfaches Balkendiagramm

Verwendung von „ Bars3D “ in einer QML-Anwendung.

„Einfaches Balkendiagramm“ zeigt, wie man mit „ Bars3D “ und QML ein einfaches 3D-Balkendiagramm erstellt.

3D-Balkendiagramme, die Ausgaben- und Einkommensdaten für einen Zeitraum von mehreren Jahren darstellen

In den folgenden Abschnitten wird beschrieben, wie man zwischen Reihen wechselt und mehrere Reihen gleichzeitig anzeigt. Weitere Informationen zu den grundlegenden Funktionen von QML-Anwendungen finden Sie unter „Einfaches Streudiagramm“.

Ausführen des Beispiels

Sie können das Beispiel wie folgt ausführen:

Daten

Der Beispieldatensatz umfasst die monatlichen Einnahmen und Ausgaben eines fiktiven Unternehmens über mehrere Jahre hinweg. 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 zum Diagramm „ Bars3D “ hinzu. 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 der Eigenschaft „ itemModel “ der „ ItemModelBarDataProxy “ innerhalb der Reihe zugewiesen. Geben Sie für die „ valueRole “ das Feld „ income “ an, da es den gewünschten Wert enthält. Das Abrufen der Jahre und Monate ist etwas komplizierter, da beide im selben Feld enthalten sind. Um diese Werte zu extrahieren, geben Sie für sowohl „ rowRole “ als auch „ columnRole “ das Feld „ timestamp “ an. Legen Sie zusätzlich ein Suchmuster und eine Ersetzungsregel für diese Rollen fest, um für jede Rolle den richtigen Teil des Feldinhalts zu extrahieren. Das Suchmuster ist ein normaler regulärer Ausdruck in JavaScript, und die Ersetzungsregel legt fest, womit der Feldinhalt, der dem regulären Ausdruck entspricht, ersetzt wird. Ersetzen Sie in diesem Fall den gesamten Feldinhalt durch nur das Jahr oder den Monat, also die erste erfasste Teilzeichenfolge sowohl für Zeilen als auch für Spalten. Weitere Informationen zur Ersetzungsfunktion mit regulären Ausdrücken finden Sie in der Dokumentation zur Funktion „ QString::replace “ (const QRegExp &rx, const QString &after).

Die Eigenschaft „ multiMatchBehavior “ legt fest, was geschehen soll, wenn mehrere Elemente des Elementmodells mit derselben Zeilen-/Spaltenkombination übereinstimmen. In diesem Fall werden ihre Werte addiert. Diese Eigenschaft hat keine Auswirkung, wenn Werte für jeden Monat angezeigt werden, da es in unserem Elementmodell keine doppelten Monate gibt. Sie wird jedoch später relevant, wenn Sie die Jahressummen anzeigen möchten.

Fügen Sie anschließend 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, diese könnten jedoch als positive Balken dargestellt werden, um einen einfachen Vergleich mit den Einkommensbalken zu ermöglichen. Verwenden Sie die Eigenschaft „ valueRolePattern “, um das Minuszeichen zu entfernen; es muss keine Ersatzzeichenfolge angegeben werden, da die Standardersetzung 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, aktivieren Sie die automatische Drehung der Achsenbeschriftungen.

Wechseln der Reihen

Richten Sie unter „ main.qml “ das Diagramm und verschiedene UI-Elemente ein. Hier sind drei interessante Code-Blöcke hervorzuheben. Der erste zeigt, wie Sie die visualisierten Daten zwischen Einnahmen, Ausgaben und beidem wechseln können, indem Sie einfach die Sichtbarkeit der beiden Reihen ändern:

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 Format der Achsenbeschriftungen und der Elementauswahlbeschriftungen wurde angepasst, damit das Minuszeichen bei den Ausgaben korrekt angezeigt wird, die eigentlich als positive Werte ausgewertet wurden.

Der zweite interessante Block ist derjenige, in dem die visualisierten Daten durch Anpassen der Proxy-Eigenschaften geändert werden:

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 jedes Jahres zu einem einzigen Balken zusammengefasst. Dies wird erreicht, indem ein „ columnRolePattern “ angegeben wird, der mit allen Modellelementen übereinstimmt. Auf diese Weise verfügt die Reihe nur über eine einzige Spalte. Das zuvor für den Proxy festgelegte kumulative „ multiMatchBehavior “ kommt nun zum Tragen und bewirkt, dass die Werte aller zwölf Monate jedes Jahres zu einem einzigen Balken addiert werden.

Um nur eine Teilmenge 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 visualisiert.

Der dritte interessante Block zeigt, wie man den Zeilen- und Spaltenindex eines Elements ermittelt, 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)

Beispielprojekt @ code.qt.io

© 2026 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.