Gráfico de barras simple
Usando Bars3D en una aplicación QML.
Simple Bar Graph muestra cómo hacer un simple gráfico de barras en 3D utilizando Bars3D y QML.

Las siguientes secciones describen cómo cambiar de serie y mostrar más de una serie a la vez. Para obtener más información sobre la funcionalidad básica de la aplicación QML, consulte Simple Scatter Graph.
Ejecución del ejemplo
Para ejecutar el ejemplo desde Qt Creatorabra el modo Welcome y seleccione el ejemplo de Examples. Para más información, consulte Qt Creator: Tutorial: Construir y ejecutar.
Datos
El conjunto de datos del ejemplo son los ingresos y gastos mensuales de una empresa ficticia a lo largo de varios años. Los datos se definen en un modelo de lista en Data.qml de la siguiente manera:
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" } ...
Cada dato tiene tres funciones: marca de tiempo, ingresos y gastos. El valor de la marca de tiempo tiene el formato: <four digit year>-<two digit month>. Normalmente, se asignarían años y meses a las filas y columnas de un gráfico de barras, pero sólo se pueden mostrar los ingresos o los gastos como valor.
Ahora, añada los datos al gráfico Bars3D. Crea dos Bar3DSeries dentro de él, empezando con una serie para los ingresos:
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 } ...
Los datos se adjuntan a la propiedad itemModel del ItemModelBarDataProxy dentro de la serie. Para valueRole, especifique el campo income, ya que contiene el valor que desea. Obtener los años y los meses es un poco más complicado, ya que ambos se encuentran en el mismo campo. Para extraer esos valores, especifique el campo timestamp tanto para rowRole como para columnRole, y especifique además un patrón de búsqueda y una regla de reemplazo para esos roles a fin de extraer la parte correcta del contenido del campo para cada rol. El patrón de búsqueda es una expresión regular normal de JavaScript y la regla de sustitución especifica con qué se sustituye el contenido del campo que coincide con la expresión regular. En este caso, sustituye todo el contenido del campo por sólo el año o el mes, que es la primera subcadena capturada tanto para las filas como para las columnas. Para obtener más información sobre la función de sustitución con expresión regular, consulte la documentación de la función QString::replace(const QRegExp &rx, const QString &after).
La propiedad multiMatchBehavior especifica qué hacer en caso de que varios elementos del modelo de elementos coincidan con la misma combinación de fila/columna. En este caso, suma sus valores. Esta propiedad no tiene ningún efecto cuando se muestran los valores de cada mes, ya que no hay meses duplicados en nuestro modelo de ítems, pero se vuelve relevante más adelante cuando quiera mostrar los totales anuales.
A continuación, añada otra serie para los gastos:
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 } ...
El modelo contiene los gastos como valores negativos, pero usted quiere mostrarlos como barras positivas, para que puedan ser fácilmente comparados con las barras de ingresos. Utilice valueRolePattern para eliminar el signo menos. No es necesario especificar ninguna cadena de sustitución, ya que la sustitución por defecto es una cadena vacía.
Utilice la propiedad visible de la serie para ocultar la segunda serie por ahora.
Etiquetas de eje personalizadas
Axes.qml redefine las etiquetas de categoría para el eje de columnas porque los datos contienen números para los meses, lo que desordenarían las etiquetas:
CategoryAxis3D { id: columnAxis labels: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"] labelAutoRotation: 30 }
Para que las etiquetas de los ejes sean más legibles en ángulos de cámara bajos, establezca la rotación automática de las etiquetas de los ejes.
Cambio de series
En main.qml, configure el gráfico y varios elementos de la interfaz de usuario. Hay tres bloques de código interesantes a destacar aquí. El primero muestra cómo cambiar los datos visualizados entre ingresos, gastos y ambos, simplemente cambiando la visibilidad de las dos series:
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"; } }
El formato de la etiqueta del eje y los formatos de la etiqueta de selección de elementos se ajustan para que el signo negativo se muestre correctamente para los gastos, que en realidad se resolvieron como valores positivos.
El segundo bloque interesante es en el que se cambian los datos visualizados ajustando las propiedades del 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"; } }
Para mostrar los totales anuales, se combinan los doce meses de cada año en una sola barra. Esto se consigue especificando un columnRolePattern que coincida con todos los elementos del modelo. De esta forma, el proxy de datos sólo tendrá una única columna. El multiMatchBehavior acumulativo especificado anteriormente para el proxy cobra relevancia ahora, haciendo que los valores de los doce meses de cada año se sumen en una sola barra.
Para mostrar sólo un subconjunto de años, establezca autoRowCategories en false en el elemento ItemModelBarDataProxy y defina explícitamente las categorías de las filas. De este modo, sólo se visualizarán los elementos de las categorías de filas especificadas.
El tercer bloque interesante muestra cómo obtener el índice de fila y columna de un elemento si conoce los valores de fila y columna mediante los métodos ItemModelBarDataProxy rowCategoryIndex() y 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.