diff options
Diffstat (limited to 'examples/datavisualization/qmlbars/qml/qmlbars/main.qml')
-rw-r--r-- | examples/datavisualization/qmlbars/qml/qmlbars/main.qml | 405 |
1 files changed, 253 insertions, 152 deletions
diff --git a/examples/datavisualization/qmlbars/qml/qmlbars/main.qml b/examples/datavisualization/qmlbars/qml/qmlbars/main.qml index 203de239..0b40e957 100644 --- a/examples/datavisualization/qmlbars/qml/qmlbars/main.qml +++ b/examples/datavisualization/qmlbars/qml/qmlbars/main.qml @@ -1,45 +1,21 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Data Visualization module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:GPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 3 or (at your option) any later version -** approved by the KDE Free Qt Foundation. The licenses are as published by -** the Free Software Foundation and appearing in the file LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.1 -import QtQuick.Controls 1.0 -import QtQuick.Layouts 1.0 -import QtDataVisualization 1.1 -import QtQuick.Window 2.0 -import "." - -Rectangle { +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts +import QtDataVisualization +import Qt.labs.qmlmodels + +pragma ComponentBehavior: Bound + +Item { id: mainview width: 1280 height: 1024 - property int buttonLayoutHeight: 180; + property int buttonLayoutHeight: 180 + property int currentRow state: Screen.width < Screen.height ? "portrait" : "landscape" Data { @@ -54,31 +30,25 @@ Rectangle { selectedSeries: barSeries function handleSelectionChange(series, position) { - if (position != series.invalidSelectionPosition) { - selectedSeries = series - } + if (position !== series.invalidSelectionPosition) + selectedSeries = series; // Set tableView current row to selected bar var rowRole = series.dataProxy.rowLabels[position.x]; - var colRole - if (barGraph.columnAxis === graphAxes.total) + var colRole; + if (barGraph.columnAxis == graphAxes.total) colRole = "01"; else colRole = series.dataProxy.columnLabels[position.y]; - var checkTimestamp = rowRole + "-" + colRole - var currentRow = tableView.currentRow + var checkTimestamp = rowRole + "-" + colRole; + if (currentRow === -1 || checkTimestamp !== graphData.model.get(currentRow).timestamp) { - var totalRows = tableView.rowCount; + var totalRows = tableView.rows; for (var i = 0; i < totalRows; i++) { - var modelTimestamp = graphData.model.get(i).timestamp + var modelTimestamp = graphData.model.get(i).timestamp; if (modelTimestamp === checkTimestamp) { - tableView.currentRow = i - // Workaround to 5.2 row selection issue - if (typeof tableView.selection != "undefined") { - tableView.selection.clear() - tableView.selection.select(i) - } - break + currentRow = i; + break; } } } @@ -86,17 +56,16 @@ Rectangle { Item { id: dataView - anchors.right: mainview.right; + anchors.right: mainview.right anchors.bottom: mainview.bottom Bars3D { id: barGraph - width: dataView.width - height: dataView.height - shadowQuality: AbstractGraph3D.ShadowQualityMedium + anchors.fill: parent + shadowQuality: AbstractGraph3D.ShadowQualitySoftHigh selectionMode: AbstractGraph3D.SelectionItem theme: Theme3D { - type: Theme3D.ThemeRetro + type: Theme3D.ThemeEbony labelBorderEnabled: true font.pointSize: 35 labelBackgroundEnabled: true @@ -145,7 +114,8 @@ Rectangle { ColorGradientStop { position: 0.0; color: "#600000" } } - onSelectedBarChanged: handleSelectionChange(secondarySeries, position) + onSelectedBarChanged: (position) => mainview.handleSelectionChange(secondarySeries, + position); } //! [3] @@ -174,71 +144,117 @@ Rectangle { ColorGradientStop { position: 0.0; color: "#006000" } } - onSelectedBarChanged: handleSelectionChange(barSeries, position) + onSelectedBarChanged: (position) => mainview.handleSelectionChange(barSeries, + position); } } } - TableView { - id: tableView + ColumnLayout { + id: tableViewLayout + anchors.top: parent.top anchors.left: parent.left - TableViewColumn{ role: "timestamp" ; title: "Month" ; width: tableView.width / 2 } - TableViewColumn{ role: "expenses" ; title: "Expenses" ; width: tableView.width / 4 } - TableViewColumn{ role: "income" ; title: "Income" ; width: tableView.width / 4 } - itemDelegate: Item { - Text { - id: delegateText - anchors.verticalCenter: parent.verticalCenter - width: parent.width - anchors.leftMargin: 4 - anchors.left: parent.left - anchors.right: parent.right - color: styleData.textColor - elide: styleData.elideMode - text: customText - horizontalAlignment: styleData.textAlignment - - property string originalText: styleData.value - property string customText - - onOriginalTextChanged: { - if (styleData.column === 0) { - if (delegateText.originalText !== "") { - var pattern = /(\d\d\d\d)-(\d\d)/ - var matches = pattern.exec(delegateText.originalText) - var colIndex = parseInt(matches[2], 10) - 1 - delegateText.customText = matches[1] + " - " + graphAxes.column.labels[colIndex] + + 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.gridLineColor + : barGraph.theme.windowColor + border.color: row === mainview.currentRow ? barGraph.theme.labelTextColor + : barGraph.theme.gridLineColor + border.width: 1 + MouseArea { + anchors.fill: parent + onClicked: mainview.currentRow = delegateRoot.row; + } + + 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; } - } else { - delegateText.customText = originalText } + color: barGraph.theme.labelTextColor + horizontalAlignment: delegateRoot.column === 0 ? Text.AlignLeft + : Text.AlignHCenter + elide: Text.ElideRight } } } + } - model: graphData.model - - //! [2] - onCurrentRowChanged: { - var timestamp = graphData.model.get(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] + //! [2] + 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); } + //! [2] ColumnLayout { id: controlLayout @@ -248,38 +264,55 @@ Rectangle { id: changeDataButton Layout.fillWidth: true Layout.fillHeight: true - text: "Show 2010 - 2012" + 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" + 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 2010 - 2012" - } else { // text === "Show 2010 - 2012" + 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 = ["2010", "2011", "2012"] - secondaryProxy.rowCategories = ["2010", "2011", "2012"] - text = "Show yearly totals" + 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.gridLineColor : barGraph.theme.windowColor + border.color: changeDataButton.down ? barGraph.theme.labelTextColor : barGraph.theme.gridLineColor + border.width: 1 + radius: 2 + } } Button { @@ -291,13 +324,29 @@ Rectangle { enabled: barGraph.shadowsSupported onClicked: { if (barGraph.shadowQuality == AbstractGraph3D.ShadowQualityNone) { - barGraph.shadowQuality = AbstractGraph3D.ShadowQualityMedium; - text = "Hide Shadows" + barGraph.shadowQuality = AbstractGraph3D.ShadowQualitySoftHigh; + text = "Hide Shadows"; } else { barGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone; - text = "Show Shadows" + 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.gridLineColor : barGraph.theme.windowColor + border.color: shadowToggle.down ? barGraph.theme.labelTextColor : barGraph.theme.gridLineColor + border.width: 1 + radius: 2 + } } Button { @@ -309,22 +358,74 @@ Rectangle { //! [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" + 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" + 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" + 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.gridLineColor : barGraph.theme.windowColor + border.color: seriesToggle.down ? barGraph.theme.labelTextColor : barGraph.theme.gridLineColor + 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.gridLineColor : barGraph.theme.windowColor + border.color: marginToggle.down ? barGraph.theme.labelTextColor : barGraph.theme.gridLineColor + border.width: 1 + radius: 2 + } } } @@ -337,7 +438,7 @@ Rectangle { height: mainview.height } PropertyChanges { - target: tableView + target: tableViewLayout height: mainview.height - buttonLayoutHeight anchors.right: dataView.left anchors.left: mainview.left @@ -347,7 +448,7 @@ Rectangle { target: controlLayout width: mainview.width / 4 height: buttonLayoutHeight - anchors.top: tableView.bottom + anchors.top: tableViewLayout.bottom anchors.bottom: mainview.bottom anchors.left: mainview.left anchors.right: dataView.left @@ -357,11 +458,11 @@ Rectangle { name: "portrait" PropertyChanges { target: dataView - width: mainview.height / 4 * 3 + width: mainview.width height: mainview.width } PropertyChanges { - target: tableView + target: tableViewLayout height: mainview.width anchors.right: controlLayout.left anchors.left: mainview.left |