Пример #1
0
    def InitGui(self):
        self.setWindowTitle("Line Chart")
        self.setGeometry(100,200,800,600)

        series = QLineSeries()
        series.setColor(QColor('red'))

        seriesA = QLineSeries()
        seriesA.setColor(QColor('green'))



        for i in range(1,20):
            series.append(10*i,20+i*i*8-3*i)
            seriesA.append(10*i, 6-i*i*2+5*i)


        chart = QChart()
        chart.addSeries(series)
        chart.addSeries(seriesA)
        chart.setAnimationOptions(chart.SeriesAnimations)
        chart.setAnimationDuration(1000)
        chart.setTitle("Line Chart")
        chart.legend().setVisible(True)
        chart.legend().setAlignment(Qt.AlignBottom)



        view = QChartView(chart)
        view.setRenderHint(QPainter.Antialiasing)




        vbox = QVBoxLayout()
        vbox.addWidget(view)
        root = QWidget()
        root.setLayout(vbox)

        self.setCentralWidget(root)
        pass
Пример #2
0
class ChartView(QChartView):
    def __init__(self, file, parent=None):
        super(ChartView, self).__init__(parent)
        self._chart = QChart()
        self._chart.setAcceptHoverEvents(True)
        self.setChart(self._chart)
        self.initUi(file)

    def initUi(self, file):
        if isinstance(file, dict):
            return self.__analysis(file)
        if isinstance(file, str):
            if not os.path.isfile(file):
                return self.__analysis(json.loads(file))
            with open(file, "rb") as fp:
                data = fp.read()
                encoding = chardet.detect(data) or {}
                data = data.decode(encoding.get("encoding") or "utf-8")
            self.__analysis(json.loads(data))

    #     def onSeriesHoverd(self, point, state):
    #         print(point, state)

    def mouseMoveEvent(self, event):
        super(ChartView, self).mouseMoveEvent(event)
        # 获取x和y轴的最小最大值
        axisX, axisY = self._chart.axisX(), self._chart.axisY()
        min_x, max_x = axisX.min(), axisX.max()
        min_y, max_y = axisY.min(), axisY.max()
        # 把鼠标位置所在点转换为对应的xy值
        x = self._chart.mapToValue(event.pos()).x()
        y = self._chart.mapToValue(event.pos()).y()
        index = round(x)  # 四舍五入
        print(x, y, index)
        # 得到在坐标系中的所有series的类型和点
        points = [(s.type(), s.at(index)) for s in self._chart.series()
                  if min_x <= x <= max_x and min_y <= y <= max_y]
        print(points)

    def __getColor(self, color=None, default=Qt.white):
        '''
        :param color: int|str|[r,g,b]|[r,g,b,a]
        '''
        if not color:
            return QColor(default)
        if isinstance(color, QBrush):
            return color
        # 比如[r,g,b]或[r,g,b,a]
        if isinstance(color, list) and 3 <= len(color) <= 4:
            return QColor(*color)
        else:
            return QColor(color)

    def __getPen(self,
                 pen=None,
                 default=QPen(Qt.white, 1, Qt.SolidLine, Qt.SquareCap,
                              Qt.BevelJoin)):
        '''
        :param pen: pen json
        '''
        if not pen or not isinstance(pen, dict):
            return default
        return QPen(self.__getColor(pen.get("color", None) or default.color()),
                    pen.get("width", 1) or 1,
                    pen.get("style", 0) or 0,
                    pen.get("capStyle", 16) or 16,
                    pen.get("joinStyle", 64) or 64)

    def __getAlignment(self, alignment):
        '''
        :param alignment: left|top|right|bottom
        '''
        try:
            return getattr(Qt, "Align" + alignment.capitalize())
        except:
            return Qt.AlignTop

    #         if alignment == "left":
    #             return Qt.AlignLeft
    #         if alignment == "right":
    #             return Qt.AlignRight
    #         if alignment == "bottom":
    #             return Qt.AlignBottom
    #         return Qt.AlignTop

    def __setTitle(self, title=None):
        '''
        :param title: title json
        '''
        if not title or not isinstance(title, dict):
            return
        # 设置标题
        self._chart.setTitle(title.get("text", "") or "")
        # 设置标题颜色
        self._chart.setTitleBrush(
            self.__getColor(
                title.get("color", self._chart.titleBrush())
                or self._chart.titleBrush()))
        # 设置标题字体
        font = QFont(title.get("font", "") or self._chart.titleFont())
        pointSize = title.get("pointSize", -1) or -1
        if pointSize > 0:
            font.setPointSize(pointSize)
        font.setWeight(title.get("weight", -1) or -1)
        font.setItalic(title.get("italic", False) or False)
        self._chart.setTitleFont(font)

    def __setAnimation(self, animation=None):
        '''
        :param value: animation json
        '''
        if not animation or not isinstance(animation, dict):
            return
        # 动画持续时间
        self._chart.setAnimationDuration(
            animation.get("duration", 1000) or 1000)
        # 设置动画曲线
        self._chart.setAnimationEasingCurve(
            EasingCurve.get(animation.get("curve", 10) or 10, None)
            or QEasingCurve.OutQuart)
        # 设置开启何种动画
        self._chart.setAnimationOptions(
            AnimationOptions.get(animation.get("options", 0) or 0, None)
            or QChart.NoAnimation)

    def __setBackground(self, background=None):
        '''
        :param background:background json
        '''
        if not background or not isinstance(background, dict):
            return
        # 设置是否背景可用
        self._chart.setBackgroundVisible(
            background.get("visible", True) or True)
        # 设置背景矩形的圆角
        self._chart.setBackgroundRoundness(background.get("radius", 0) or 0)
        # 设置下拉阴影
        self._chart.setDropShadowEnabled(
            background.get("dropShadow", True) or True)
        # 设置pen
        self._chart.setBackgroundPen(
            self.__getPen(background.get("pen", None),
                          self._chart.backgroundPen()))
        # 设置背景
        image = background.get("image", None)
        color = background.get("color", None)
        if image:
            self._chart.setBackgroundBrush(QBrush(QPixmap(image)))
        elif color:
            self._chart.setBackgroundBrush(
                self.__getColor(color, self._chart.backgroundBrush()))

    def __setMargins(self, margins=None):
        '''
        :param margins: margins json
        '''
        if not margins or not isinstance(margins, dict):
            return
        left = margins.get("left", 20) or 20
        top = margins.get("top", 20) or 20
        right = margins.get("right", 20) or 20
        bottom = margins.get("bottom", 20) or 20
        self._chart.setMargins(QMargins(left, top, right, bottom))

    def __setLegend(self, legend=None):
        '''
        :param legend: legend json
        '''
        if not legend or not isinstance(legend, dict):
            return
        _legend = self._chart.legend()
        _legend.setAlignment(self.__getAlignment(legend.get("alignment",
                                                            None)))
        _legend.setShowToolTips(legend.get("showToolTips", True) or True)

    def __getSerie(self, serie=None):
        if not serie or not isinstance(serie, dict):
            return None
        types = serie.get("type", "") or ""
        data = serie.get("data", []) or []
        if not data or not isinstance(data, list):
            return None
        if types == "line":
            _series = QLineSeries(self._chart)
        else:
            return None
        # 设置series名字
        _series.setName(serie.get("name", "") or "")
        # 添加数据到series中
        for index, value in enumerate(data):
            # 保证vlaue必须是数字
            _series.append(index, value if type(value) in (int, float) else 0)
        return _series

    def __setSeries(self, series=None):
        if not series or not isinstance(series, list):
            return
        for serie in series:
            _serie = self.__getSerie(serie)
            if _serie:
                #                 _serie.hovered.connect(self.onSeriesHoverd)
                self._chart.addSeries(_serie)
        # 创建默认的xy轴
        self._chart.createDefaultAxes()

    def __setAxisX(self, axisx=None):
        if not axisx or not isinstance(axisx, dict):
            return
        series = self._chart.series()
        if not series:
            return
        types = axisx.get("type", None)
        data = axisx.get("data", []) or []
        if not data or not isinstance(data, list):
            return None
        minx = self._chart.axisX().min()
        maxx = self._chart.axisX().max()
        if types == "category":
            xaxis = QCategoryAxis(
                self._chart,
                labelsPosition=QCategoryAxis.AxisLabelsPositionOnValue)
            # 隐藏网格
            xaxis.setGridLineVisible(False)
            # 刻度条数
            tickc_d = len(data)
            tickc = tickc_d if tickc_d > 1 else self._chart.axisX().tickCount()
            xaxis.setTickCount(tickc)
            # 强制x轴刻度与新刻度条数一致
            self._chart.axisX().setTickCount(tickc)
            step = (maxx - minx) / (tickc - 1)
            for i in range(min(tickc_d, tickc)):
                xaxis.append(data[i], minx + i * step)
            self._chart.setAxisX(xaxis, series[-1])

    def __analysis(self, datas):
        '''
        analysis json data
        :param datas: json data
        '''
        # 标题
        self.__setTitle(datas.get("title", None))
        # 抗锯齿
        if (datas.get("antialiasing", False) or False):
            self.setRenderHint(QPainter.Antialiasing)
        # 主题
        self._chart.setTheme(datas.get("theme", 0) or 0)
        # 动画
        self.__setAnimation(datas.get("animation", None))
        # 背景设置
        self.__setBackground(datas.get("background", None))
        # 边距设置
        self.__setMargins(datas.get("margins", None))
        # 设置图例
        self.__setLegend(datas.get("legend", None))
        # 设置series
        self.__setSeries(datas.get("series", None))
        # 自定义的x轴
        self.__setAxisX(datas.get("axisx", None))
Пример #3
0
class LeftBarBarChart(QTabWidget):

    chart = None
    tabs = []
    bar_sets = []
    inputs = []
    main_tab = None

    def __init__(self, parent):
        super(LeftBarBarChart, self).__init__()
        self.setParent(parent)
        self.setStyleSheet("""
            color: white;
            border-radius: 4px;
            background:rgb(37,43,52,220);
        """)
        self.init_ui()

    def init_ui(self):
        # Tab Bar
        self.tab_bar = TabBarPlus(self)
        self.setTabBar(self.tab_bar)
        # Properties
        # self.setMovable(True)
        # Signals
        self.tab_bar.plusClicked.connect(self.add_tab)
        self.tab_bar.tabMoved.connect(self.tab_bar.movePlusButton)
        self.tabCloseRequested.connect(self.removeTab)
        #######
        self.chart = QChart()
        self.serie = QBarSeries()
        self.chart.addSeries(self.serie)
        self.chart.setTitle("Bar Chart")

        self.main_tab = MainTab(self)
        self.addTab(self.main_tab, self.main_tab.name)

        self.chart.createDefaultAxes()

        self.chart.setAnimationDuration(2000)
        self.chart.setAnimationOptions(QChart.AllAnimations)

    def add_tab(self):
        if self.count() >= 0:
            self.setTabsClosable(True)
        else:
            self.setTabsClosable(False)

        tab = Tab(self, "New Tab", len(self.main_tab.all_inputs))
        self.tabs.append(tab)
        self.addTab(tab, tab.name)

    def removeTab(self, p_int):
        if self.count() > 1:
            super(LeftBarBarChart, self).removeTab(p_int)
            del self.tabs[p_int - 1]

        if self.count() >= 2:
            self.setTabsClosable(True)
        else:
            self.setTabsClosable(False)

    def update_all_tabs(self, amount):
        for tab in self.tabs:
            tab.update_tab(amount)

    def update_axes(self):
        self.chart.removeSeries(self.serie)
        self.chart.addSeries(self.serie)
        self.chart.createDefaultAxes()
Пример #4
0
class GraphicsScene(QGraphicsScene):
    def __init__(self):
        super(GraphicsScene, self).__init__()

        self.line_series = QLineSeries()
        self.chart = QChart()
        self.chart_view = QChartView(self.chart)
        self.chart_view.setMinimumSize(640, 480)

        self.model = ItemModel()
        self.model.signal_update_models.connect(self.update_axes)

        self.table_view = TableView()

        self.table_view.setModel(self.model)
        self.table_view.horizontalHeader().setSectionResizeMode(
            QHeaderView.Stretch)
        self.table_view.verticalHeader().setSectionResizeMode(
            QHeaderView.Stretch)

        self.chart.setAnimationOptions(QChart.AllAnimations)
        self.chart.setAnimationDuration(2000)

        self.line_series.setName("Line 1")

        self.mapper = QVXYModelMapper(self)
        self.mapper.setXColumn(0)
        self.mapper.setYColumn(1)
        self.mapper.setSeries(self.line_series)
        self.mapper.setModel(self.model)
        self.chart.addSeries(self.line_series)

        seriesColorHex = self.line_series.pen().color().name()
        self.model.add_mapping(seriesColorHex,
                               QRect(0, 0, 2, self.model.rowCount()))

        self.line_series2 = QLineSeries()
        self.line_series2.setName("Line 2")

        self.mapper2 = QVXYModelMapper(self)
        self.mapper2.setXColumn(2)
        self.mapper2.setYColumn(3)
        self.mapper2.setSeries(self.line_series2)
        self.mapper2.setModel(self.model)
        self.chart.addSeries(self.line_series2)

        seriesColorHex = self.line_series2.pen().color().name()
        self.model.add_mapping(seriesColorHex,
                               QRect(2, 0, 2, self.model.rowCount()))

        self.chart.createDefaultAxes()

        self.chart_view.setRenderHint(QPainter.Antialiasing)
        self.chart.resize(500, 400)
        self.chart.setFlag(QGraphicsItem.ItemIsMovable)
        self.chart.setFlag(QGraphicsItem.ItemIsSelectable)
        self.addItem(self.chart)

    @pyqtSlot()
    def update_axes(self):
        self.chart.removeSeries(self.line_series)
        self.chart.removeSeries(self.line_series2)
        self.chart.addSeries(self.line_series)
        self.chart.addSeries(self.line_series2)
        self.chart.createDefaultAxes()
Пример #5
0
class LeftBarPieChart(QWidget):
    def __init__(self, parent):
        super(LeftBarPieChart, self).__init__()
        self.parent = parent
        self.setParent(parent)

        self.chart = None
        self.inputs = []
        self.layout = None
        self.layout_inp = None
        self.btn_add = None
        self.w_inp = None
        self.header = None

        self.init_ui()

    def init_ui(self):

        self.chart = QChart()
        self.chart.setTheme(QChart.ChartThemeBlueIcy)
        self.chart.setAnimationDuration(1000)
        self.chart.setAnimationOptions(QChart.AllAnimations)
        self.serie = QPieSeries()

        self.layout = QVBoxLayout()
        self.layout_inp = QVBoxLayout()
        self.w_inp = QWidget()
        self.w_inp.setStyleSheet("""
            .QWidget{
                background-color: transparent;
            }
        """)

        self.w_inp.setLayout(self.layout_inp)

        self.setLayout(self.layout)
        self.inputs.append(InputPieChart(self))

        self.btn_add = QPushButton("+")
        self.btn_remove = QPushButton("-")
        self.btn_add.clicked.connect(self.add_input)
        self.btn_remove.clicked.connect(self.remove_input)
        self.btn_add.setStyleSheet("""
            border: 0px;
            background: green;
            color: white;
        """)
        self.btn_remove.setStyleSheet("""
            border: 0px;
            background: red;
            color: white;
        """)
        self.header = HeaderPieChartInput()
        self.layout.addWidget(self.header)
        self.layout.addWidget(self.w_inp)
        self.layout.addStretch(-1)
        self.layout.addWidget(self.btn_remove)
        self.layout.addWidget(self.btn_add)
        self.layout_inp.addWidget(self.inputs[0])

        self.serie.append(self.inputs[0].name.text(), 2)

        # self.slice.setExploded()
        # self.slice.setLabelVisible()
        # self.slice.setPen(QPen(Qt.darkGreen,2))
        # self.slice.setBrush(Qt.green)

        self.chart.addSeries(self.serie)
        self.chart.setTitle("Pie Chart")

    def add_input(self):
        if len(self.inputs) < 10:
            self.inputs.append(InputPieChart(self))
            self.layout_inp.addWidget(self.inputs[-1])
            self.serie.append(self.inputs[-1].name.text(),
                              int(self.inputs[-1].value.text()))
            # for slice in self.serie.slices():
            #     slice.setBrush(Qt.green)

    def remove_input(self):
        if len(self.inputs) >= 1:
            self.layout_inp.removeWidget(self.inputs[-1])
            self.inputs[-1].hide()
            self.inputs.remove(self.inputs[-1])
            self.slc = self.serie.slices()[-1]
            self.serie.remove(self.slc)

            # for slice in self.serie.slices():
            #     slice.setBrush(Qt.green)

    def input_changed(self, txt):
        if self.serie in self.chart.series():
            self.chart.removeSeries(self.serie)
            self.serie = QPieSeries()
            for inp in self.inputs:
                self.serie.append(inp.name.text(), int(inp.value.text()))
            self.chart.addSeries(self.serie)
Пример #6
0
class MainWindow(QMainWindow):

    def __init__(self):
        super(MainWindow, self).__init__()
        self.init_ui()

    def init_ui(self):



        self.line_series = QLineSeries()
        self.chart = QChart()
        self.chart_view = QChartView(self.chart)
        self.chart_view.setMinimumSize(640,480)

        self.model = ItemModel()
        self.model.signal_update_models.connect(self.update_axes)

        self.table_view = TableView()

        self.table_view.setModel(self.model)
        self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.table_view.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)

        self.chart.setAnimationOptions(QChart.AllAnimations)
        self.chart.setAnimationDuration(2000)

        self.line_series.setName("Line 1")

        self.mapper = QVXYModelMapper(self)
        self.mapper.setXColumn(0)
        self.mapper.setYColumn(1)
        self.mapper.setSeries(self.line_series)
        self.mapper.setModel(self.model)
        self.chart.addSeries(self.line_series)

        seriesColorHex = self.line_series.pen().color().name()
        self.model.add_mapping(seriesColorHex,
                               QRect(0,0,2, self.model.rowCount()))

        self.line_series2 = QLineSeries()
        self.line_series2.setName("Line 2")

        self.mapper2 = QVXYModelMapper(self)
        self.mapper2.setXColumn(2)
        self.mapper2.setYColumn(3)
        self.mapper2.setSeries(self.line_series2)
        self.mapper2.setModel(self.model)
        self.chart.addSeries(self.line_series2)


        seriesColorHex = self.line_series2.pen().color().name()
        self.model.add_mapping(seriesColorHex,
                               QRect(2, 0, 2, self.model.rowCount()))

        self.chart.createDefaultAxes()

        self.grid = QGridLayout()
        self.grid.addWidget(self.table_view,0,0)
        self.grid.addWidget(self.chart_view,0,1)

        self.chart_view.setRenderHint(QPainter.Antialiasing)
        self.cw = QWidget()
        self.cw.setLayout(self.grid)
        self.setCentralWidget(self.cw)
        self.resize(400,300)

    @pyqtSlot()
    def update_axes(self):
        self.chart.removeSeries(self.line_series)
        self.chart.removeSeries(self.line_series2)
        self.chart.addSeries(self.line_series)
        self.chart.addSeries(self.line_series2)
        self.chart.createDefaultAxes()