本页内容

使用 QML Gallery 制作图表

通过 qml 演示如何使用不同的图表类型。

该截图展示了来自三个不同国家的NHL全明星队球员人数,以面积图的形式呈现:绿色区域代表瑞典球员,蓝色区域代表俄罗斯球员,橙色区域代表芬兰球员。左侧提供了多种选项,可用于将图表切换为不同类型的图表。

运行示例

您可以通过以下方式运行示例:

这是一个Qt Quick 应用程序,每种图表类型的文件都位于示例文件夹的qml目录中,并由位于该示例目录中的main.qml文件加载并组织到ListView 中。

本文档不会重点介绍顶级布局或加载过程,而是侧重于Qt Charts QML API的使用。

包含依赖项

所有 .qml 文件均以以下内容开头:

import QtQuick
import QtCharts

使用 QML 创建图表

创建每种图表类型都从创建一个 ChartView 开始。

要创建饼图,我们需结合使用 PieSeries API 以及若干 PieSlices:

一张截图,以饼图形式展示了芬兰前五大汽车品牌的市场份额

ChartView {
    id: chart
    title: "Top-5 car brand shares in Finland"
    anchors.fill: parent
    legend.alignment: Qt.AlignBottom
    antialiasing: true

    property variant othersSlice: 0

    PieSeries {
        id: pieSeries
        PieSlice { label: "Volkswagen"; value: 13.5 }
        PieSlice { label: "Toyota"; value: 10.9 }
        PieSlice { label: "Ford"; value: 8.6 }
        PieSlice { label: "Skoda"; value: 8.2 }
        PieSlice { label: "Volvo"; value: 6.8 }
    }

    Component.onCompleted: {
        // You can also manipulate slices dynamically, like append a slice or set a slice exploded
        othersSlice = pieSeries.append("Others", 52.0);
        pieSeries.find("Volkswagen").exploded = true;
    }
}

您可以创建一个包含折线系列的图表:

显示折线图示例的屏幕截图

ChartView {
    title: "Line Chart"
    anchors.fill: parent
    antialiasing: true

    LineSeries {
        name: "Line"
        XYPoint { x: 0; y: 0 }
        XYPoint { x: 1.1; y: 2.1 }
        XYPoint { x: 1.9; y: 3.3 }
        XYPoint { x: 2.1; y: 2.1 }
        XYPoint { x: 2.9; y: 4.9 }
        XYPoint { x: 3.4; y: 3.0 }
        XYPoint { x: 4.1; y: 3.3 }
    }
}

以及样条线系列:

显示样条图示例的屏幕截图

ChartView {
    title: "Spline Chart"
    anchors.fill: parent
    antialiasing: true

    SplineSeries {
        name: "Spline"
        XYPoint { x: 0; y: 0.0 }
        XYPoint { x: 1.1; y: 3.2 }
        XYPoint { x: 1.9; y: 2.4 }
        XYPoint { x: 2.1; y: 2.1 }
        XYPoint { x: 2.9; y: 2.6 }
        XYPoint { x: 3.4; y: 2.3 }
        XYPoint { x: 4.1; y: 3.1 }
    }
}

您可以使用三个面积系列创建一个图表,以展示NHL全明星球员的入选情况:

一张截图,展示了来自三个不同国家的NHL全明星队球员人数,以面积图的形式呈现:绿色区域代表瑞典球员,蓝色区域代表俄罗斯球员,橙色区域代表芬兰球员。

ChartView {
    title: "NHL All-Star Team Players"
    anchors.fill: parent
    antialiasing: true

    // Define x-axis to be used with the series instead of default one
    ValueAxis {
        id: valueAxis
        min: 2000
        max: 2011
        tickCount: 12
        labelFormat: "%.0f"
    }

    AreaSeries {
        name: "Russian"
        axisX: valueAxis
        upperSeries: LineSeries {
            XYPoint { x: 2000; y: 1 }
            XYPoint { x: 2001; y: 1 }
            XYPoint { x: 2002; y: 1 }
            XYPoint { x: 2003; y: 1 }
            XYPoint { x: 2004; y: 1 }
            XYPoint { x: 2005; y: 0 }
            XYPoint { x: 2006; y: 1 }
            XYPoint { x: 2007; y: 1 }
            XYPoint { x: 2008; y: 4 }
            XYPoint { x: 2009; y: 3 }
            XYPoint { x: 2010; y: 2 }
            XYPoint { x: 2011; y: 1 }
        }
    }
    ...

接着是几个散点系列:

截图显示图表中堆叠了两个散点图系列,其中“scatter1”的点为蓝色,“scatter2”的点为绿色

ChartView {
    title: "Scatter Chart"
    anchors.fill: parent
    antialiasing: true

    ScatterSeries {
        id: scatter1
        name: "Scatter A"
        XYPoint { x: 1.5; y: 1.5 }
        XYPoint { x: 1.5; y: 1.6 }
        XYPoint { x: 1.57; y: 1.55 }
        XYPoint { x: 1.8; y: 1.8 }
        XYPoint { x: 1.9; y: 1.6 }
        XYPoint { x: 2.1; y: 1.3 }
        XYPoint { x: 2.5; y: 2.1 }
    }

    ScatterSeries {
        name: "Scatter B"
        XYPoint { x: 2.0; y: 2.0 }
        XYPoint { x: 2.0; y: 2.1 }
        XYPoint { x: 2.07; y: 2.05 }
        XYPoint { x: 2.2; y: 2.9 }
        XYPoint { x: 2.4; y: 2.7 }
        XYPoint { x: 2.67; y: 2.65 }
    }
}
    ...

以及几个不同的柱形系列:

截图显示了三个人各自的贡献以柱状图形式呈现,其中鲍勃的柱状图为蓝色,苏珊的为绿色,詹姆斯的为橙色

ChartView {
    title: "Bar Chart"
    anchors.fill: parent
    legend.alignment: Qt.AlignBottom
    antialiasing: true

    BarSeries {
        id: mySeries
        axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] }
        BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] }
        BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] }
        BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] }
    }
}

显示同一批人贡献情况的截图,但以堆叠柱形图的形式呈现

ChartView {
    title: "Stacked Bar Chart"
    anchors.fill: parent
    legend.alignment: Qt.AlignBottom
    antialiasing: true

    StackedBarSeries {
        axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] }
        BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] }
        BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] }
        BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] }
    }
}

显示同一群人贡献情况的截图,但以百分比条形图的形式呈现

ChartView {
    title: "Percent Bar Chart"
    anchors.fill: parent
    legend.alignment: Qt.AlignBottom
    antialiasing: true

    PercentBarSeries {
        axisX: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] }
        BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] }
        BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] }
        BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] }
    }
}

显示同一群人贡献情况的截图,但以水平条形图形式呈现

ChartView {
    title: "Horizontal Bar Chart"
    anchors.fill: parent
    legend.alignment: Qt.AlignBottom
    antialiasing: true

    HorizontalBarSeries {
        axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] }
        BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] }
        BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] }
        BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] }
    }
}

显示同一组人员贡献情况的截图,但以水平堆叠条形图的形式呈现

ChartView {
    title: "Horizontal Stacked Bar Chart"
    anchors.fill: parent
    legend.alignment: Qt.AlignBottom
    antialiasing: true

    HorizontalStackedBarSeries {
        axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] }
        BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] }
        BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] }
        BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] }
    }
}

显示同一批人贡献情况的截图,但采用水平百分比条形图形式呈现

ChartView {
    title: "Horizontal Percent Bar Chart"
    anchors.fill: parent
    legend.alignment: Qt.AlignBottom
    antialiasing: true

    HorizontalPercentBarSeries {
        axisY: BarCategoryAxis { categories: ["2007", "2008", "2009", "2010", "2011", "2012" ] }
        BarSet { label: "Bob"; values: [2, 2, 3, 4, 5, 6] }
        BarSet { label: "Susan"; values: [5, 1, 2, 4, 1, 7] }
        BarSet { label: "James"; values: [3, 5, 8, 13, 5, 8] }
    }
}

以下演示了如何创建一个包含两个饼图系列的环形图:

截图显示了以环形图形式呈现的生产成本,各主要部分下设子主题

ChartView {
    id: chart
    title: "Production Costs"
    anchors.fill: parent
    legend.visible: false
    antialiasing: true

    PieSeries {
        id: pieOuter
        size: 0.96
        holeSize: 0.7
        PieSlice { id: slice; label: "Alpha"; value: 19511; color: "#99CA53" }
        PieSlice { label: "Epsilon"; value: 11105; color: "#209FDF" }
        PieSlice { label: "Psi"; value: 9352; color: "#F6A625" }
    }

    PieSeries {
        size: 0.7
        id: pieInner
        holeSize: 0.25

        PieSlice { label: "Materials"; value: 10334; color: "#B9DB8A" }
        PieSlice { label: "Employee"; value: 3066; color: "#DCEDC4" }
        PieSlice { label: "Logistics"; value: 6111; color: "#F3F9EB" }

        PieSlice { label: "Materials"; value: 7371; color: "#63BCE9" }
        PieSlice { label: "Employee"; value: 2443; color: "#A6D9F2" }
        PieSlice { label: "Logistics"; value: 1291; color: "#E9F5FC" }

        PieSlice { label: "Materials"; value: 4022; color: "#F9C36C" }
        PieSlice { label: "Employee"; value: 3998; color: "#FCE1B6" }
        PieSlice { label: "Logistics"; value: 1332; color: "#FEF5E7" }
    }

    Component.onCompleted: {
        // Set the common slice properties dynamically for convenience
        for (var i = 0; i < pieOuter.count; i++) {
            pieOuter.at(i).labelPosition = PieSlice.LabelOutside;
            pieOuter.at(i).labelVisible = true;
            pieOuter.at(i).borderWidth = 3;
        }
        for (var i = 0; i < pieInner.count; i++) {
            pieInner.at(i).labelPosition = PieSlice.LabelInsideNormal;
            pieInner.at(i).labelVisible = true;
            pieInner.at(i).borderWidth = 2;
        }
    }
}

此外,在Qt Quick 2中,通过qml属性设置了抗锯齿效果。

更多图表

请参阅以下链接,了解此示例应用中其余图表的详细操作指南。

Customizing Chart Views with QML

向您展示如何自定义 ChartView 和系列的不同视觉属性。

Customizing Legends

向您展示如何创建自己的自定义图例。

Using Axes with QML

演示了如何在 QML 应用程序中使用坐标轴。

Using List Models as Data Sources in QML

实现了一个 F1 图例图表,以演示列表模型作为数据源。

Using Polar Charts with QML

演示如何在 QML 应用程序中制作几种不同的极坐标图。

示例项目 @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.