Graphique à barres simple
Utilisation de Bars3D dans une application QML.
La section «Graphique à barres simple » explique comment créer un graphique à barres 3D simple à l’aide de 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, on associe 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.MMBCumulative
}
...Les données sont associées à la propriété ` itemModel ` de l’`ItemModelBarDataProxy` au sein de la série. Pour ` 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, puis définissez en outre un motif de recherche et une règle de remplacement pour ces rôles afin d’extraire la partie correcte 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 pour chaque mois, car il n’y a pas de mois en double dans notre modèle d’éléments, mais elle devient 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.MMBCumulative
}
...Le modèle contient les dépenses sous forme de valeurs négatives, mais vous souhaitez les afficher sous forme de barres positives, afin de pouvoir les comparer facilement aux barres représentant les revenus. Pour ce faire, utilisez la propriété ` valueRolePattern ` afin de supprimer le signe moins. Il n’est pas nécessaire de spécifier de chaîne de remplacement, car la chaîne de remplacement 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 chiffres correspondant aux mois, ce qui encombrerait les libellés :
CategoryAxis3D {
id: columnAxis
labels: ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"]
labelAutoRotation: 30
}Pour rendre les étiquettes d’axe plus lisibles lorsque la caméra est placée à un angle faible, activez la rotation automatique des étiquettes d’axe.
Changement de série
Dans ` main.qml`, configurez le graphique et les différents é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 propriété ` columnRolePattern ` qui correspond à tous les éléments du modèle. Ainsi, le proxy de données ne comportera qu’une seule colonne. L’ multiMatchBehavior e cumulative spécifiée 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 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 rowCategoryIndex() et columnCategoryIndex() de ItemModelBarDataProxy :
onCurrentRowChanged: {
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.