diff options
| author | Ece Cinucen <ece.cinucen@qt.io> | 2024-11-19 18:34:09 +0100 |
|---|---|---|
| committer | Ece Cinucen <ece.cinucen@qt.io> | 2024-11-21 11:02:44 +0100 |
| commit | abfc11c4c2fb5cd35db910284c53b4e2e282b3fe (patch) | |
| tree | 82b441bc2cb72f38484203b866b9441a37724e66 /examples | |
| parent | d5fd9fe459a71bf469f9a1f531f5048b7f2be0f3 (diff) | |
Example: Add simple bar graph
Adding missing example from c++
Task-number: PYSIDE-841
Pick-to: 6.8
Change-Id: I36fe2cafd7bc50a76e2f261635c702ce0ee30329
Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/graphs/3d/bars/Bars/Axes.qml | 41 | ||||
| -rw-r--r-- | examples/graphs/3d/bars/Bars/Data.qml | 118 | ||||
| -rw-r--r-- | examples/graphs/3d/bars/Bars/Main.qml | 484 | ||||
| -rw-r--r-- | examples/graphs/3d/bars/Bars/qmldir | 4 | ||||
| -rw-r--r-- | examples/graphs/3d/bars/bars.pyproject | 9 | ||||
| -rw-r--r-- | examples/graphs/3d/bars/doc/bars-example.webp | bin | 0 -> 48706 bytes | |||
| -rw-r--r-- | examples/graphs/3d/bars/doc/bars.rst | 12 | ||||
| -rw-r--r-- | examples/graphs/3d/bars/main.py | 24 |
8 files changed, 692 insertions, 0 deletions
diff --git a/examples/graphs/3d/bars/Bars/Axes.qml b/examples/graphs/3d/bars/Bars/Axes.qml new file mode 100644 index 000000000..db87a7412 --- /dev/null +++ b/examples/graphs/3d/bars/Bars/Axes.qml @@ -0,0 +1,41 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtGraphs + +Item { + property alias column: columnAxis + property alias row: rowAxis + property alias value: valueAxis + property alias total: totalAxis + + // Custom labels for columns, since the data contains abbreviated month names. + //! [0] + Category3DAxis { + id: columnAxis + labels: ["January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"] + labelAutoAngle: 30 + } + //! [0] + Category3DAxis { + id: totalAxis + labels: ["Yearly total"] + labelAutoAngle: 30 + } + Category3DAxis { + // For row labels we can use row labels from data proxy, no labels defined for rows. + id: rowAxis + labelAutoAngle: 30 + } + + Value3DAxis { + id: valueAxis + min: 0 + max: 35 + labelFormat: "%.2f M\u20AC" + title: "Monthly income" + labelAutoAngle: 90 + } +} diff --git a/examples/graphs/3d/bars/Bars/Data.qml b/examples/graphs/3d/bars/Bars/Data.qml new file mode 100644 index 000000000..b088d4bb2 --- /dev/null +++ b/examples/graphs/3d/bars/Bars/Data.qml @@ -0,0 +1,118 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQml.Models + +Item { + property alias model: dataModel + + property var modelAsJsArray: { + var arr = []; + for (var i = 0; i < dataModel.count; i++) { + var row = dataModel.get(i); + arr.push({ + timestamp: row.timestamp, + expenses: row.expenses, + income: row.income + }); + } + return arr; + } + + //! [0] + 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" } + //! [0] + ListElement{ timestamp: "2016-04"; expenses: "-3"; income: "2" } + ListElement{ timestamp: "2016-05"; expenses: "-4"; income: "1" } + ListElement{ timestamp: "2016-06"; expenses: "-2"; income: "2" } + ListElement{ timestamp: "2016-07"; expenses: "-1"; income: "3" } + ListElement{ timestamp: "2016-08"; expenses: "-5"; income: "1" } + ListElement{ timestamp: "2016-09"; expenses: "-2"; income: "3" } + ListElement{ timestamp: "2016-10"; expenses: "-5"; income: "2" } + ListElement{ timestamp: "2016-11"; expenses: "-8"; income: "5" } + ListElement{ timestamp: "2016-12"; expenses: "-3"; income: "3" } + + ListElement{ timestamp: "2017-01"; expenses: "-3"; income: "1" } + ListElement{ timestamp: "2017-02"; expenses: "-4"; income: "2" } + ListElement{ timestamp: "2017-03"; expenses: "-12"; income: "4" } + ListElement{ timestamp: "2017-04"; expenses: "-13"; income: "6" } + ListElement{ timestamp: "2017-05"; expenses: "-14"; income: "11" } + ListElement{ timestamp: "2017-06"; expenses: "-7"; income: "7" } + ListElement{ timestamp: "2017-07"; expenses: "-6"; income: "4" } + ListElement{ timestamp: "2017-08"; expenses: "-4"; income: "15" } + ListElement{ timestamp: "2017-09"; expenses: "-2"; income: "18" } + ListElement{ timestamp: "2017-10"; expenses: "-29"; income: "25" } + ListElement{ timestamp: "2017-11"; expenses: "-23"; income: "29" } + ListElement{ timestamp: "2017-12"; expenses: "-5"; income: "9" } + + ListElement{ timestamp: "2018-01"; expenses: "-3"; income: "8" } + ListElement{ timestamp: "2018-02"; expenses: "-8"; income: "14" } + ListElement{ timestamp: "2018-03"; expenses: "-10"; income: "20" } + ListElement{ timestamp: "2018-04"; expenses: "-12"; income: "24" } + ListElement{ timestamp: "2018-05"; expenses: "-10"; income: "19" } + ListElement{ timestamp: "2018-06"; expenses: "-5"; income: "8" } + ListElement{ timestamp: "2018-07"; expenses: "-1"; income: "4" } + ListElement{ timestamp: "2018-08"; expenses: "-7"; income: "12" } + ListElement{ timestamp: "2018-09"; expenses: "-4"; income: "16" } + ListElement{ timestamp: "2018-10"; expenses: "-22"; income: "33" } + ListElement{ timestamp: "2018-11"; expenses: "-16"; income: "25" } + ListElement{ timestamp: "2018-12"; expenses: "-2"; income: "7" } + + ListElement{ timestamp: "2019-01"; expenses: "-4"; income: "5" } + ListElement{ timestamp: "2019-02"; expenses: "-4"; income: "7" } + ListElement{ timestamp: "2019-03"; expenses: "-11"; income: "14" } + ListElement{ timestamp: "2019-04"; expenses: "-16"; income: "22" } + ListElement{ timestamp: "2019-05"; expenses: "-3"; income: "5" } + ListElement{ timestamp: "2019-06"; expenses: "-4"; income: "8" } + ListElement{ timestamp: "2019-07"; expenses: "-7"; income: "9" } + ListElement{ timestamp: "2019-08"; expenses: "-9"; income: "13" } + ListElement{ timestamp: "2019-09"; expenses: "-1"; income: "6" } + ListElement{ timestamp: "2019-10"; expenses: "-14"; income: "25" } + ListElement{ timestamp: "2019-11"; expenses: "-19"; income: "29" } + ListElement{ timestamp: "2019-12"; expenses: "-5"; income: "7" } + + ListElement{ timestamp: "2020-01"; expenses: "-14"; income: "22" } + ListElement{ timestamp: "2020-02"; expenses: "-5"; income: "7" } + ListElement{ timestamp: "2020-03"; expenses: "-1"; income: "9" } + ListElement{ timestamp: "2020-04"; expenses: "-1"; income: "12" } + ListElement{ timestamp: "2020-05"; expenses: "-5"; income: "9" } + ListElement{ timestamp: "2020-06"; expenses: "-5"; income: "8" } + ListElement{ timestamp: "2020-07"; expenses: "-3"; income: "7" } + ListElement{ timestamp: "2020-08"; expenses: "-1"; income: "5" } + ListElement{ timestamp: "2020-09"; expenses: "-2"; income: "4" } + ListElement{ timestamp: "2020-10"; expenses: "-10"; income: "13" } + ListElement{ timestamp: "2020-11"; expenses: "-12"; income: "17" } + ListElement{ timestamp: "2020-12"; expenses: "-6"; income: "9" } + + ListElement{ timestamp: "2021-01"; expenses: "-2"; income: "6" } + ListElement{ timestamp: "2021-02"; expenses: "-4"; income: "8" } + ListElement{ timestamp: "2021-03"; expenses: "-7"; income: "12" } + ListElement{ timestamp: "2021-04"; expenses: "-9"; income: "15" } + ListElement{ timestamp: "2021-05"; expenses: "-7"; income: "19" } + ListElement{ timestamp: "2021-06"; expenses: "-9"; income: "18" } + ListElement{ timestamp: "2021-07"; expenses: "-13"; income: "17" } + ListElement{ timestamp: "2021-08"; expenses: "-5"; income: "9" } + ListElement{ timestamp: "2021-09"; expenses: "-3"; income: "8" } + ListElement{ timestamp: "2021-10"; expenses: "-13"; income: "15" } + ListElement{ timestamp: "2021-11"; expenses: "-8"; income: "17" } + ListElement{ timestamp: "2021-12"; expenses: "-7"; income: "10" } + + ListElement{ timestamp: "2022-01"; expenses: "-12"; income: "16" } + ListElement{ timestamp: "2022-02"; expenses: "-24"; income: "28" } + ListElement{ timestamp: "2022-03"; expenses: "-27"; income: "22" } + ListElement{ timestamp: "2022-04"; expenses: "-29"; income: "25" } + ListElement{ timestamp: "2022-05"; expenses: "-27"; income: "29" } + ListElement{ timestamp: "2022-06"; expenses: "-19"; income: "18" } + ListElement{ timestamp: "2022-07"; expenses: "-13"; income: "17" } + ListElement{ timestamp: "2022-08"; expenses: "-15"; income: "19" } + ListElement{ timestamp: "2022-09"; expenses: "-3"; income: "8" } + ListElement{ timestamp: "2022-10"; expenses: "-3"; income: "6" } + ListElement{ timestamp: "2022-11"; expenses: "-4"; income: "8" } + ListElement{ timestamp: "2022-12"; expenses: "-5"; income: "9" } + } +} diff --git a/examples/graphs/3d/bars/Bars/Main.qml b/examples/graphs/3d/bars/Bars/Main.qml new file mode 100644 index 000000000..e839fc39d --- /dev/null +++ b/examples/graphs/3d/bars/Bars/Main.qml @@ -0,0 +1,484 @@ +// Copyright (C) 2024 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls.Basic +import QtQuick.Layouts +import QtGraphs +import Qt.labs.qmlmodels + +pragma ComponentBehavior: Bound + +Item { + id: mainview + width: 1280 + height: 1024 + + property int buttonLayoutHeight: 180 + property int currentRow + state: Screen.width < Screen.height ? "portrait" : "landscape" + + Data { + id: graphData + } + + Axes { + id: graphAxes + } + + property Bar3DSeries selectedSeries + selectedSeries: barSeries + + function handleSelectionChange(series, position) { + if (position !== series.invalidSelectionPosition) + selectedSeries = series + + // Set tableView current row to selected bar + var rowRole = series.rowLabels[position.x] + var colRole + if (barGraph.columnAxis == graphAxes.total) + colRole = "01" + else + colRole = series.columnLabels[position.y] + var checkTimestamp = rowRole + "-" + colRole + + if (currentRow === -1 || checkTimestamp !== graphData.model.get(currentRow).timestamp) { + var totalRows = tableView.rows + for (var i = 0; i < totalRows; i++) { + var modelTimestamp = graphData.model.get(i).timestamp + if (modelTimestamp === checkTimestamp) { + currentRow = i + break + } + } + } + } + + ColumnLayout { + id: tableViewLayout + + anchors.top: parent.top + anchors.left: parent.left + + HorizontalHeaderView { + id: headerView + readonly property var columnNames: ["Month", "Expenses", "Income"] + + syncView: tableView + Layout.fillWidth: true + delegate: Text { + required property int index + padding: 3 + text: headerView.columnNames[index] + color: barGraph.theme.labelTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + } + + TableView { + id: tableView + Layout.fillWidth: true + Layout.fillHeight: true + + reuseItems: false + clip: true + + model: TableModel { + id: tableModel + TableModelColumn { display: "timestamp" } + TableModelColumn { display: "expenses" } + TableModelColumn { display: "income" } + + rows: graphData.modelAsJsArray + } + + delegate: Rectangle { + id: delegateRoot + required property int row + required property int column + required property string display + implicitHeight: 30 + implicitWidth: column === 0 ? tableView.width / 2 : tableView.width / 4 + color: row === mainview.currentRow ? barGraph.theme.grid.mainColor + : barGraph.theme.backgroundColor + border.color: row === mainview.currentRow ? barGraph.theme.labelTextColor + : barGraph.theme.grid.mainColor + border.width: 1 + MouseArea { + anchors.fill: parent + onClicked: { + mainview.currentRow = delegateRoot.row + + //! [2] + 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) + //! [2] + } + } + + Text { + id: delegateText + anchors.verticalCenter: parent.verticalCenter + width: parent.width + anchors.leftMargin: 4 + anchors.left: parent.left + anchors.right: parent.right + text: formattedText + property string formattedText: { + if (delegateRoot.column === 0) { + if (delegateRoot.display !== "") { + var pattern = /(\d\d\d\d)-(\d\d)/ + var matches = pattern.exec(delegateRoot.display) + var colIndex = parseInt(matches[2], 10) - 1 + return matches[1] + " - " + graphAxes.column.labels[colIndex] + } + } else { + return delegateRoot.display + } + } + color: delegateRoot.row === mainview.currentRow ? barGraph.theme.backgroundColor + : barGraph.theme.labelTextColor + horizontalAlignment: delegateRoot.column === 0 ? Text.AlignLeft + : Text.AlignHCenter + elide: Text.ElideRight + } + } + } + } + + ColumnLayout { + id: controlLayout + spacing: 0 + + Button { + id: changeDataButton + Layout.fillWidth: true + Layout.fillHeight: true + text: "Show 2020 - 2022" + clip: true + //! [1] + 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" + } + } + //! [1] + + contentItem: Text { + text: changeDataButton.text + opacity: changeDataButton.enabled ? 1.0 : 0.3 + color: barGraph.theme.labelTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + opacity: changeDataButton.enabled ? 1 : 0.3 + color: changeDataButton.down ? barGraph.theme.grid.mainColor : barGraph.theme.backgroundColor + border.color: changeDataButton.down ? barGraph.theme.labelTextColor : barGraph.theme.grid.mainColor + border.width: 1 + radius: 2 + } + } + + Button { + id: shadowToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Hide Shadows" + clip: true + onClicked: { + if (barGraph.shadowQuality == Graphs3D.ShadowQuality.None) { + barGraph.shadowQuality = Graphs3D.ShadowQuality.SoftHigh + text = "Hide Shadows" + } else { + barGraph.shadowQuality = Graphs3D.ShadowQuality.None + text = "Show Shadows" + } + } + contentItem: Text { + text: shadowToggle.text + opacity: shadowToggle.enabled ? 1.0 : 0.3 + color: barGraph.theme.labelTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + opacity: shadowToggle.enabled ? 1 : 0.3 + color: shadowToggle.down ? barGraph.theme.grid.mainColor : barGraph.theme.backgroundColor + border.color: shadowToggle.down ? barGraph.theme.labelTextColor : barGraph.theme.grid.mainColor + border.width: 1 + radius: 2 + } + } + + Button { + id: seriesToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Show Expenses" + clip: true + //! [0] + 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" + } + } + //! [0] + contentItem: Text { + text: seriesToggle.text + opacity: seriesToggle.enabled ? 1.0 : 0.3 + color: barGraph.theme.labelTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + opacity: seriesToggle.enabled ? 1 : 0.3 + color: seriesToggle.down ? barGraph.theme.grid.mainColor : barGraph.theme.backgroundColor + border.color: seriesToggle.down ? barGraph.theme.labelTextColor : barGraph.theme.grid.mainColor + border.width: 1 + radius: 2 + } + } + + Button { + id: marginToggle + Layout.fillWidth: true + Layout.fillHeight: true + text: "Use Margin" + clip: true + + onClicked: { + if (text === "Use Margin") { + barGraph.barSeriesMargin = Qt.size(0.2, 0.2) + barGraph.barSpacing = Qt.size(0.0, 0.0) + text = "Use Spacing" + } else if (text === "Use Spacing") { + barGraph.barSeriesMargin = Qt.size(0.0, 0.0) + barGraph.barSpacing = Qt.size(0.5, 0.5) + text = "Use Margin" + } + } + contentItem: Text { + text: marginToggle.text + opacity: marginToggle.enabled ? 1.0 : 0.3 + color: barGraph.theme.labelTextColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + elide: Text.ElideRight + } + + background: Rectangle { + opacity: marginToggle.enabled ? 1 : 0.3 + color: marginToggle.down ? barGraph.theme.grid.mainColor : barGraph.theme.backgroundColor + border.color: marginToggle.down ? barGraph.theme.labelTextColor : barGraph.theme.grid.mainColor + border.width: 1 + radius: 2 + } + } + } + + Item { + id: dataView + anchors.right: mainview.right + anchors.bottom: mainview.bottom + + Bars3D { + id: barGraph + anchors.fill: parent + shadowQuality: Graphs3D.ShadowQuality.SoftHigh + selectionMode: Graphs3D.SelectionFlag.Item + theme: GraphsTheme { + colorScheme: GraphsTheme.ColorScheme.Dark + labelBorderVisible: true + labelFont.pointSize: 35 + labelBackgroundVisible: true + colorStyle: GraphsTheme.ColorStyle.RangeGradient + singleHighlightGradient: customGradient + + Gradient { + id: customGradient + GradientStop { position: 1.0; color: "#FFFF00" } + GradientStop { position: 0.0; color: "#808000" } + } + } + barThickness: 0.7 + barSpacing: Qt.size(0.5, 0.5) + barSpacingRelative: false + cameraPreset: Graphs3D.CameraPreset.IsometricLeftHigh + columnAxis: graphAxes.column + rowAxis: graphAxes.row + valueAxis: graphAxes.value + + //! [4] + 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 + } + //! [4] + + Gradient { + id: secondaryGradient + GradientStop { position: 1.0; color: "#FF0000" } + GradientStop { position: 0.0; color: "#600000" } + } + + onSelectedBarChanged: (position) => mainview.handleSelectionChange(secondarySeries, + position) + } + + //! [3] + 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 + } + //! [3] + + Gradient { + id: barGradient + GradientStop { position: 1.0; color: "#00FF00" } + GradientStop { position: 0.0; color: "#006000" } + } + + onSelectedBarChanged: (position) => mainview.handleSelectionChange(barSeries, + position) + } + } + } + + states: [ + State { + name: "landscape" + PropertyChanges { + target: dataView + width: mainview.width / 4 * 3 + height: mainview.height + } + PropertyChanges { + target: tableViewLayout + height: mainview.height - buttonLayoutHeight + anchors.right: dataView.left + anchors.left: mainview.left + anchors.bottom: undefined + } + PropertyChanges { + target: controlLayout + width: mainview.width / 4 + height: buttonLayoutHeight + anchors.top: tableViewLayout.bottom + anchors.bottom: mainview.bottom + anchors.left: mainview.left + anchors.right: dataView.left + } + }, + State { + name: "portrait" + PropertyChanges { + target: dataView + width: mainview.width + height: mainview.width + } + PropertyChanges { + target: tableViewLayout + height: mainview.width + anchors.right: controlLayout.left + anchors.left: mainview.left + anchors.bottom: dataView.top + } + PropertyChanges { + target: controlLayout + width: mainview.height / 4 + height: mainview.width / 4 + anchors.top: mainview.top + anchors.bottom: dataView.top + anchors.left: undefined + anchors.right: mainview.right + } + } + ] +} diff --git a/examples/graphs/3d/bars/Bars/qmldir b/examples/graphs/3d/bars/Bars/qmldir new file mode 100644 index 000000000..d6ace351e --- /dev/null +++ b/examples/graphs/3d/bars/Bars/qmldir @@ -0,0 +1,4 @@ +module Bars +Main 1.0 Main.qml +Axes 1.0 Axes.qml +Data 1.0 Data.qml diff --git a/examples/graphs/3d/bars/bars.pyproject b/examples/graphs/3d/bars/bars.pyproject new file mode 100644 index 000000000..c8b979437 --- /dev/null +++ b/examples/graphs/3d/bars/bars.pyproject @@ -0,0 +1,9 @@ +{ + "files": [ + "main.py", + "Bars/Main.qml", + "Bars/Data.qml", + "Bars/Axes.qml", + "Bars/qmldir ", + ] +} diff --git a/examples/graphs/3d/bars/doc/bars-example.webp b/examples/graphs/3d/bars/doc/bars-example.webp Binary files differnew file mode 100644 index 000000000..8d55d57a5 --- /dev/null +++ b/examples/graphs/3d/bars/doc/bars-example.webp diff --git a/examples/graphs/3d/bars/doc/bars.rst b/examples/graphs/3d/bars/doc/bars.rst new file mode 100644 index 000000000..e36c543e6 --- /dev/null +++ b/examples/graphs/3d/bars/doc/bars.rst @@ -0,0 +1,12 @@ +Simple Bar Graph +================ + +The Qt 3D Bar Graph example demonstrates creating a 3D bar graph in QML +using Bars3D. It visualizes fictional company data for income and expenses +over time, showcasing features like data series switching, custom axis labels, +and interactive data selection. + + +.. image:: bars-example.webp + :width: 400 + :alt: Widget Screenshot diff --git a/examples/graphs/3d/bars/main.py b/examples/graphs/3d/bars/main.py new file mode 100644 index 000000000..0a75de48d --- /dev/null +++ b/examples/graphs/3d/bars/main.py @@ -0,0 +1,24 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import sys +from pathlib import Path + +from PySide6.QtGui import QGuiApplication +from PySide6.QtQuick import QQuickView + + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + view = QQuickView() + + view.engine().addImportPath(Path(__file__).parent) + view.loadFromModule("Bars", "Main") + view.setTitle("Monthly income / expenses") + view.setResizeMode(QQuickView.SizeRootObjectToView) + view.setColor("black") + view.show() + + ex = app.exec() + del view + sys.exit(ex) |
