DoughnutChart3D Example

import sys, os
sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/../shared")

from DevMachines import __pyside2__, __pyside6__
from DevMachines.QtitanBase import Qtitan
from DevMachines.QtitanChart import (Chart, ChartPieSeriesLabel, ChartDoughnutSeries3D, ChartLegend)

if __pyside2__:
    from PySide2 import QtCore
    from PySide2.QtCore import Qt
    from PySide2.QtGui import QBrush, QIcon, QPixmap, QColor
    from PySide2.QtWidgets import (QApplication, QComboBox, QCheckBox, QSlider, QSpinBox, QLabel)

if __pyside6__:
    from PySide6 import QtCore
    from PySide6.QtCore import Qt
    from PySide6.QtGui import QBrush, QIcon, QPixmap, QColor
    from PySide6.QtWidgets import (QApplication, QComboBox, QCheckBox, QSlider, QSpinBox, QLabel)

from DemoChartWindow import DemoChartWindow

def createPiePoint(series, legendText, value, special = False):
    strValue = ", {:f}".format(value)
    s = legendText + strValue
    point = series.add(value, special)
    point.setLabel(s)
    point.setLegendText(legendText)

class MainWindow(DemoChartWindow):
    def __init__(self):
        DemoChartWindow.__init__(self, "Doughnut Chart 3D")
        self.setChart(None)
        self.createSeriesParametrs()
        self.createDoughnutSeries()
        self.updateValueParameters()

    def createSeriesParametrs(self):
        # Option Series
        seriesTypeGroup = self.createGroupParameters(self.tr("Series"))
        localLayout = seriesTypeGroup.layout()

        self.explodedCheckBox = QCheckBox(self.tr("Exploded"), seriesTypeGroup)
        self.connect(self.explodedCheckBox, QtCore.SIGNAL("stateChanged(int)"), self, QtCore.SLOT("explodedSeriesChanged(int)"))

        self.rotateSlider = QSlider(Qt.Horizontal, seriesTypeGroup)
        self.rotateSlider.setRange(-180, 180)
        self.rotateSlider.setSliderPosition(0)
        self.rotateSlider.setSingleStep(1)
        self.connect(self.rotateSlider, QtCore.SIGNAL("valueChanged(int)"), self, QtCore.SLOT("rotateSeriesChanged(int)"))

        self.aspectAngleSlider = QSlider(Qt.Horizontal, seriesTypeGroup)
        self.aspectAngleSlider.setRange(1, 90)
        self.aspectAngleSlider.setSingleStep(1)
        self.connect(self.aspectAngleSlider, QtCore.SIGNAL("valueChanged(int)"), self, QtCore.SLOT("aspectAngleChanged(int)"))

        self.editorHole = QSpinBox(seriesTypeGroup)
        self.editorHole.setMinimumWidth(60)
        self.editorHole.setRange(0, 100)
        self.editorHole.setValue(60)
        self.connect(self.editorHole, QtCore.SIGNAL("valueChanged(int)"), self, QtCore.SLOT("holeSeriesChanged(int)"))

        # Layouts Series
        localLayout.addRow(self.explodedCheckBox)
        localLayout.addRow(QLabel(self.tr("Pie Rotation Angle:"), seriesTypeGroup))
        localLayout.addRow(self.rotateSlider)
        self.captionAspectAngle = QLabel(self.tr("Pie Aspect Angle:"), seriesTypeGroup)
        localLayout.addRow(self.captionAspectAngle)
        localLayout.addRow(self.aspectAngleSlider)

        self.captionEditorHole = QLabel(self.tr("Hole Radius:"), seriesTypeGroup)
        localLayout.addRow(self.captionEditorHole)
        localLayout.addRow(self.editorHole)

        # Option Labels
        self.dataLabelsGroup = self.createGroupParameters(self.tr("Show Data Labels"), True)
        localLayout = self.dataLabelsGroup.layout()

        self.connect(self.dataLabelsGroup, QtCore.SIGNAL("toggled(bool)"), self, QtCore.SLOT("showDataLabels(bool)"))
        self.posDataLabelsSwitcher = QComboBox(self.dataLabelsGroup)

        self.posDataLabelsSwitcher.addItem(self.tr("Label Outside"), ChartPieSeriesLabel.PieLabelOutside)
        self.posDataLabelsSwitcher.addItem(self.tr("Label Inside"),  ChartPieSeriesLabel.PieLabelInside)
        self.posDataLabelsSwitcher.setCurrentIndex(0)
        self.connect(self.posDataLabelsSwitcher, QtCore.SIGNAL("currentIndexChanged(int)"), self, QtCore.SLOT("labelsPositionChanged(int)"))
        # Layouts Series
        localLayout.addRow(self.posDataLabelsSwitcher)

    def createDoughnutSeries(self):
        self.createTitle(self.tr("Travel"))
        self.chart.legend().setVisible(True)
        self.chart.legend().setVerticalAlignment(ChartLegend.LegendFar)

        series = ChartDoughnutSeries3D()
        self.chart.appendSeries(series)
        createPiePoint(series, self.tr("Other"), 1131, True)
        createPiePoint(series, self.tr("USA"), 1139, True)
        createPiePoint(series, self.tr("Taiwan"), 823, True)
        createPiePoint(series, self.tr("France"), 423)
        createPiePoint(series, self.tr("China"), 223)
        createPiePoint(series, self.tr("Australia"), 523)
        createPiePoint(series, self.tr("Germany"), 724)
        createPiePoint(series, self.tr("Italy"), 1025)
        self.setValueHole(60)
        self.aspectAngleSlider.setSliderPosition(series.aspectAngle())

    def setValueHole(self, value):
        series2D = self.chart.series()[0]
        series2D.setHolePercent(value)

    def updateValueParameters(self):
        DemoChartWindow.updateValueParameters(self)
        self.labelsPositionChanged(self.posDataLabelsSwitcher.currentIndex())
        self.explodedSeriesChanged(self.explodedCheckBox.checkState())
        self.rotateSeriesChanged(self.rotateSlider.value())
        if self.editorHole.isEnabled():
            self.holeSeriesChanged(self.editorHole.value())

    def labelsPositionChanged(self, index):
        v = self.posDataLabelsSwitcher.itemData(index)
        listSeries = self.chart.series()
        for series in listSeries:
            label = series.label()
            label.setPosition(ChartPieSeriesLabel.PieLabelPosition(v))

    def explodedSeriesChanged(self, state):
        listSeries = self.chart.series()
        for series in listSeries:
            if state == Qt.Checked:
                series.setExplodeRelativeSizePercent(15)
            else:
                series.setExplodeRelativeSizePercent(0)

    def rotateSeriesChanged(self, value):
        listSeries = self.chart.series()
        for series in listSeries:
            series.setRotation(value)

    def aspectAngleChanged(self, value):
        listSeries = self.chart.series()
        for series in listSeries:
            series.setAspectAngle(value)

    def holeSeriesChanged(self, value):
        listSeries = self.chart.series()
        for series in listSeries:
            series.setHolePercent(value)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())