Graphique à barres simple
Utilisation de Bars3D dans une application QML.
Simple Bar Graph montre comment créer un simple graphique à barres en 3D à l'aide de Bars3D et de QML.

Les sections suivantes décrivent comment changer de série et afficher plus d'une série à la fois. Pour plus d'informations sur les fonctionnalités de base d'une application QML, voir Simple Scatter Graph (graphique de dispersion simple).
Exécution de l'exemple
Pour exécuter l'exemple à partir de Qt CreatorOuvrez le mode Welcome et sélectionnez l'exemple à partir de Examples. Pour plus d'informations, voir Qt Creator: Tutoriel : Construire et exécuter.
Données
Les données de l'exemple sont les revenus et les dépenses mensuels d'une entreprise fictive sur plusieurs années. Les données sont définies dans un modèle de liste à l'adresse Data.qml:
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 a trois rôles : l'horodatage, les revenus et les dépenses. La valeur de l'horodatage est au format : <four digit year>-<two digit month>. Habituellement, vous feriez correspondre les années et les mois aux lignes et aux colonnes d'un diagramme à barres, mais vous ne pouvez afficher que les revenus ou les dépenses en tant que valeur.
Ajoutez maintenant les données au graphique Bars3D. Créez deux Bar3DSeries à l'intérieur de celui-ci, 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 attachées à la propriété itemModel de la série ItemModelBarDataProxy. Pour valueRole, spécifiez le champ income, car il contient la valeur que vous souhaitez. Obtenir les années et les mois est un peu plus compliqué, car ils se trouvent dans le même champ. Pour extraire ces valeurs, spécifiez le champ timestamp pour rowRole et columnRole, et spécifiez également 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 normale 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, l'ensemble du contenu du champ est remplacé par l'année ou le mois, qui est la première sous-chaîne capturée pour les lignes et les colonnes. Pour plus d'informations sur la fonctionnalité de remplacement par une expression régulière, voir la documentation de la fonction QString::replace(const QRegExp &rx, const QString &after).
La propriété multiMatchBehavior indique ce qu'il faut faire lorsque plusieurs éléments du modèle d'élément correspondent à la même combinaison ligne/colonne. Dans ce cas, il convient d'additionner 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ément, mais elle devient pertinente plus tard 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 des 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 de revenus. Pour ce faire, utilisez le site valueRolePattern pour supprimer le signe moins. Il n'est pas nécessaire de spécifier une 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éfinit les étiquettes de catégorie pour l'axe des colonnes car les données contiennent des nombres pour les mois, ce qui encombrerait les étiquettes :
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 l'angle de la caméra est faible, activez la rotation automatique des étiquettes d'axe.
Changement de série
Dans main.qml, configurez le graphique et les divers éléments de l'interface utilisateur. Il y a trois blocs de code intéressants à souligner ici. Le premier montre comment changer les données visualisées entre les revenus, les dépenses et les deux, en changeant 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 de l'étiquette de l'axe et le format de l'étiquette de sélection de l'élément sont modifiés pour que le signe négatif apparaisse correctement pour les dépenses, qui étaient en fait résolues 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, il faut combiner les douze mois de chaque année en une seule barre. Pour ce faire, il convient de spécifier une adresse columnRolePattern qui correspond à tous les éléments du modèle. De cette façon, le proxy de données n'aura qu'une seule colonne. Le cumulatif multiMatchBehavior spécifié plus tôt pour le proxy devient pertinent maintenant, ce qui fait que les valeurs des douze mois de chaque année sont additionnées en une seule barre.
Pour n'afficher qu'un sous-ensemble d'années, réglez autoRowCategories sur false pour l'élément ItemModelBarDataProxy et définissez explicitement les catégories de lignes. De cette façon, seuls les éléments des catégories de ligne 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 en utilisant les méthodes ItemModelBarDataProxy, rowCategoryIndex() et columnCategoryIndex():
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.