diff options
Diffstat (limited to 'examples/datavisualization/graphgallery/variantbardataproxy.py')
-rw-r--r-- | examples/datavisualization/graphgallery/variantbardataproxy.py | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/examples/datavisualization/graphgallery/variantbardataproxy.py b/examples/datavisualization/graphgallery/variantbardataproxy.py new file mode 100644 index 000000000..f69ebaf80 --- /dev/null +++ b/examples/datavisualization/graphgallery/variantbardataproxy.py @@ -0,0 +1,100 @@ +# Copyright (C) 2023 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +from PySide6.QtCore import Slot +from PySide6.QtDataVisualization import QBarDataProxy, QBarDataItem + + +class VariantBarDataProxy(QBarDataProxy): + + def __init__(self): + super().__init__() + self._dataSet = None + self._mapping = None + + def setDataSet(self, newSet): + if self._dataSet: + self._dataSet.itemsAdded.disconnect(self.handleItemsAdded) + self._dataSet.dataCleared.disconnect(self.handleDataCleared) + + self._dataSet = newSet + + if self._dataSet: + self._dataSet.itemsAdded.connect(self.handleItemsAdded) + self._dataSet.dataCleared.connect(self.handleDataCleared) + self.resolveDataSet() + + def dataSet(self): + return self._dataSet.data() + + # Map key (row, column, value) to value index in data item (VariantItem). + # Doesn't gain ownership of mapping, but does connect to it to listen for + # mapping changes. Modifying mapping that is set to proxy will trigger + # dataset re-resolving. + def setMapping(self, mapping): + if self._mapping: + self._mapping.mappingChanged.disconnect(self.handleMappingChanged) + + self._mapping = mapping + + if self._mapping: + self._mapping.mappingChanged.connect(self.handleMappingChanged) + + self.resolveDataSet() + + def mapping(self): + return self._mapping.data() + + @Slot(int, int) + def handleItemsAdded(self, index, count): + # Resolve new items + self.resolveDataSet() + + @Slot() + def handleDataCleared(self): + # Data cleared, reset array + self.resetArray(None) + + @Slot() + def handleMappingChanged(self): + self.resolveDataSet() + + # Resolve entire dataset into QBarDataArray. + def resolveDataSet(self): + # If we have no data or mapping, or the categories are not defined, + # simply clear the array + if (not self._dataSet or not self._mapping + or not self._mapping.rowCategories() + or not self._mapping.columnCategories()): + self.resetArray() + return + + itemList = self._dataSet.itemList() + + rowIndex = self._mapping.rowIndex() + columnIndex = self._mapping.columnIndex() + valueIndex = self._mapping.valueIndex() + rowList = self._mapping.rowCategories() + columnList = self._mapping.columnCategories() + + # Sort values into rows and columns + itemValueMap = {} + for item in itemList: + key = str(item[rowIndex]) + v = itemValueMap.get(key) + if not v: + v = {} + itemValueMap[key] = v + v[str(item[columnIndex])] = float(item[valueIndex]) + + # Create a new data array in format the parent class understands + newProxyArray = [] + for rowKey in rowList: + newProxyRow = [] + for i in range(0, len(columnList)): + item = QBarDataItem(itemValueMap[rowKey][columnList[i]]) + newProxyRow.append(item) + newProxyArray.append(newProxyRow) + + # Finally, reset the data array in the parent class + self.resetArray(newProxyArray) |