Graphique à barres simple
Utilisation d'Bars3D dans une application QML.
La section «Graphique à barres simple » explique comment créer un graphique à barres 3D simple à l'aide d'Bars3D et de QML.

Les sections suivantes décrivent comment changer de série et afficher plusieurs séries à la fois. Pour plus d’informations sur les fonctionnalités de base des applications QML, consultez la section « Graphique de dispersion simple ».
Exécution de l'exemple
Vous pouvez exécuter l'exemple à partir de :
- Qt Creator
Ouvrez le mode « Welcome » et sélectionnez l’exemple dans « Examples ». Pour plus d’informations, consultez « Qt Creator » : Tutoriel : Compiler et exécuter.
- Qt Extension for Visual Studio Code
Exécutez la commande « Qt: Open Qt examples » à partir de Command Palette, puis sélectionnez l’exemple dans la liste. Pour plus d’informations, consultez Qt Extension for Visual Studio Code: Tutoriel : Compiler et exécuter.
Données
L'ensemble de données d'exemple correspond aux revenus et dépenses mensuels d'une entreprise fictive sur plusieurs années. Les données sont définies dans un modèle de liste dans Data.qml comme suit :
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" }
...Chaque élément de données comporte trois rôles : horodatage, recettes et dépenses. La valeur d’horodatage est au format : <four digit year>-<two digit month>. En général, vous associez les années et les mois aux lignes et aux colonnes d’un graphique à barres, mais vous ne pouvez afficher que les recettes ou les dépenses comme valeur.
Ajoutez maintenant les données au graphique Bars3D. Créez deux Bar3DSeries à l’intérieur, en commençant par une série pour les revenus :
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
}
...Les données sont associées à la propriété « itemModel » de l’ ItemModelBarDataProxy au sein de la série. Pour l’ valueRole, spécifiez le champ « income » car il contient la valeur souhaitée. L’extraction des années et des mois est un peu plus compliquée, car ils se trouvent tous deux dans le même champ. Pour extraire ces valeurs, spécifiez le champ « timestamp » à la fois pour « rowRole » et « columnRole ». De plus, définissez un motif de recherche et une règle de remplacement pour ces rôles afin d’extraire la partie appropriée du contenu du champ pour chaque rôle. Le motif de recherche est une expression régulière JavaScript standard, et la règle de remplacement spécifie par quoi le contenu du champ correspondant à l’expression régulière doit être remplacé. Dans ce cas, remplacez l’intégralité du contenu du champ par l’année ou le mois uniquement, qui constituent la première sous-chaîne capturée tant pour les lignes que pour les colonnes. Pour plus d’informations sur la fonctionnalité de remplacement avec des expressions régulières, consultez la documentation de la fonction ` QString::replace(const QRegExp &rx, const QString &after)`.
La propriété « multiMatchBehavior » spécifie la marche à suivre lorsque plusieurs éléments du modèle d’éléments correspondent à la même combinaison ligne/colonne. Dans ce cas, additionnez leurs valeurs. Cette propriété n’a aucun effet lors de l’affichage des valeurs mensuelles, car il n’y a pas de mois en double dans notre modèle d’éléments. Elle devient toutefois pertinente par la suite, lorsque vous souhaitez afficher les totaux annuels.
Ajoutez ensuite une autre série pour les dépenses :
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
}
...Le modèle contient les dépenses sous forme de valeurs négatives, mais celles-ci pourraient être affichées sous forme de barres positives pour faciliter la comparaison avec les barres de revenus. Utilisez la propriété ` valueRolePattern ` pour supprimer le signe moins ; il n’est pas nécessaire de spécifier de chaîne de remplacement, car la valeur par défaut est une chaîne vide.
Utilisez la propriété « visible » de la série pour masquer la deuxième série pour l’instant.
Étiquettes d’axe personnalisées
Axes.qml Redéfinissez les libellés de catégorie de l’axe des colonnes, car les données contiennent des nombres correspondant aux mois, ce qui encombrerait les libellés :
Category3DAxis {
id: columnAxis
labels: ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
labelAutoAngle: 30
}Pour rendre les étiquettes d’axe plus lisibles lorsque l’angle de vue est faible, activez la rotation automatique des étiquettes d’axe.
Changement de série
Dans ` main.qml`, configurez le graphique et divers éléments de l’interface utilisateur. Trois blocs de code intéressants méritent d’être soulignés ici. Le premier montre comment basculer entre l’affichage des revenus, des dépenses ou des deux, en modifiant simplement la visibilité des deux séries :
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"
}
}Le format des étiquettes d’axe et celui des étiquettes de sélection des éléments ont été ajustés pour que le signe négatif s’affiche correctement pour les dépenses, qui avaient en réalité été interprétées comme des valeurs positives.
Le deuxième bloc intéressant est celui où les données visualisées sont modifiées en ajustant les propriétés du proxy :
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"
}
}Pour afficher les totaux annuels, regroupez les douze mois de chaque année en un seul histogramme. Pour ce faire, spécifiez une valeur « columnRolePattern » qui corresponde à tous les éléments du modèle. De cette manière, la série ne comportera qu’une seule colonne. L’ multiMatchBehavior e cumulatif spécifié précédemment pour le proxy entre alors en jeu, ce qui entraîne l’addition des valeurs des douze mois de chaque année en un seul histogramme.
Pour n’afficher qu’un sous-ensemble d’années, définissez l’ autoRowCategories sur « false » pour l’élément « ItemModelBarDataProxy » et définissez explicitement les catégories de lignes. De cette manière, seuls les éléments appartenant aux catégories de lignes spécifiées sont visualisés.
Le troisième bloc intéressant montre comment obtenir l’index de ligne et de colonne d’un élément si vous connaissez les valeurs de ligne et de colonne, à l’aide des méthodes « ItemModelBarDataProxy » rowCategoryIndex() et columnCategoryIndex():
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)© 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.