簡単な散布図

QMLアプリケーションでScatter3D

Simple Scatter Graphでは、Scatter3D と QML を使って簡単な散布図グラフを視覚化する方法を示しています。

グラフの操作方法については、このページを参照してください。

新しいQt Quick アプリケーションの作成方法については、Qt Creator ヘルプを参照してください。

例を実行する

からサンプルを実行するには Qt Creatorからサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Qt Creator:Tutorialを参照してください:ビルドと実行を参照してください。

アプリケーションの基本

QMLのコードに入る前に、アプリケーションmain.cpp を見てください。

このアプリケーションはUIに'Quit'ボタンを実装しているので、QQmlEngine::quit()シグナルをアプリケーションのQWindow::close()スロットに接続します:

QObject::connect(viewer.engine(), &QQmlEngine::quit, &viewer, &QWindow::close);

デプロイを少し簡単にするために、アプリケーションの.qml ファイルをすべてリソースファイル (qmlscatter.qrc) に集めてください:

<RCC>
    <qresource prefix="/">
        <file>qml/qmlscatter/Data.qml</file>
        <file>qml/qmlscatter/main.qml</file>
    </qresource>
</RCC>

また、main.qml をリソースから読み込むように設定する必要があります (qrc:):

viewer.setSource(QUrl("qrc:/qml/qmlscatter/main.qml"));

qmakeの代わりにcmakeを使う場合、.qml ファイルはCMakeLists.txt のQMLモジュールに追加されます:

qt6_add_qml_module(qmlscatter
    URI Scatter
    VERSION 1.0
    NO_RESOURCE_TARGET_PATH
    QML_FILES
        qml/qmlscatter/Data.qml
        qml/qmlscatter/main.qml
)

最後に、アプリケーションを最大化されたウィンドウで実行するようにします:

viewer.showMaximized();

グラフのセットアップ

まず、必要なQMLモジュールをすべてインポートします:

import QtQuick
import QtQuick.Controls
import QtDataVisualization

次に、メインのItem を作成し、mainView と呼びます:

Item {
    id: mainView

次に、メインのItem の中にもう一つItem を追加し、dataView と呼びます。これがScatter3D グラフを保持するアイテムとなります。これを親の下にアンカーします:

Item {
    id: dataView
    anchors.bottom: parent.bottom

次に、Scatter3D グラフそのものを追加する。これをdataView の中に追加し、名前をscatterGraph とします。dataView を埋めるようにします:

Scatter3D {
    id: scatterGraph
    anchors.fill: parent

これでグラフは使えるようになったが、データはない。また、デフォルトの軸とビジュアル・プロパティを持っています。

次に、scatterGraph の中に以下を追加して、まずいくつかのビジュアル・プロパティを変更します:

theme: themeQt
shadowQuality: AbstractGraph3D.ShadowQualityHigh
scene.activeCamera.cameraPreset: Camera3D.CameraPresetFront

カスタマイズしたテーマを追加し、影の質を変更し、カメラの位置を調整しました。他のビジュアルプロパティは問題ないので、変更する必要はありません。

カスタム・テーマは事前定義されたテーマTheme3D.ThemeQt をベースにしていますが、その中のフォントは変更されています:

Theme3D {
    id: themeQt
    type: Theme3D.ThemeQt
    font.pointSize: 40
}

次に、グラフにデータを与え始めます。

グラフへのデータの追加

mainView の中にData アイテムを作成し、seriesData と名づける:

Data {
    id: seriesData
}

seriesData 項目には、この例で使用する3つの系列すべてのデータモデルが含まれています。

これは、Data.qml のデータを保持するコンポーネントです。Item をメイン・コンポーネントとして持ちます。

メイン・コンポーネントのListModel にデータそのものを追加し、dataModel と名付けます:

ListModel {
    id: dataModel
    ListElement{ xPos: -10.0; yPos: 5.0; zPos: -5.0 }
    ...

他の2つの系列にもこれを追加し、dataModelTwodataModelThree と名付ける。

そして、main.qml から使えるようにデータモデルを公開する。これは、メインのデータ・コンポーネントでエイリアスとして定義することで行います:

property alias model: dataModel
property alias modelTwo: dataModelTwo
property alias modelThree: dataModelThree

これで、Data.qml のデータをscatterGraph と一緒にmain.qml で使うことができます。まず、Scatter3DSeries を追加し、scatterSeries と呼びます:

Scatter3DSeries {
    id: scatterSeries

次に、シリーズの選択ラベル・フォーマットを設定する:

itemLabelFormat: "Series 1: X:@xLabel Y:@yLabel Z:@zLabel"

そして最後に、ItemModelScatterDataProxy に系列1のデータを追加する。プロキシ用のitemModel として、データそのものを設定する:

ItemModelScatterDataProxy {
    itemModel: seriesData.model
    xPosRole: "xPos"
    yPosRole: "yPos"
    zPosRole: "zPos"
}

他の2つの系列も同じように追加するが、系列固有の詳細を少し修正する:

Scatter3DSeries {
    id: scatterSeriesTwo
    itemLabelFormat: "Series 2: X:@xLabel Y:@yLabel Z:@zLabel"
    itemSize: 0.05
    mesh: Abstract3DSeries.MeshCube
    ...

それから、scatterGraph のデフォルト軸のプロパティを少し修正する:

axisX.segmentCount: 3
axisX.subSegmentCount: 2
axisX.labelFormat: "%.2f"
axisZ.segmentCount: 2
axisZ.subSegmentCount: 2
axisZ.labelFormat: "%.2f"
axisY.segmentCount: 2
axisY.subSegmentCount: 2
axisY.labelFormat: "%.2f"

その後、mainView にグラフをコントロールするためのボタンをいくつか追加する:

Button {
    id: shadowToggle
    width: mainView.buttonWidth // Calculated elsewhere based on screen orientation
    anchors.left: parent.left
    anchors.top: parent.top
    anchors.margins: 5
    text: scatterGraph.shadowsSupported ? "Hide Shadows" : "Shadows not supported"
    enabled: scatterGraph.shadowsSupported
    onClicked: {
        if (scatterGraph.shadowQuality === AbstractGraph3D.ShadowQualityNone) {
            scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityHigh;
            text = "Hide Shadows";
        } else {
            scatterGraph.shadowQuality = AbstractGraph3D.ShadowQualityNone;
            text = "Show Shadows";
        }
    }
}

次に、dataView を修正し、上部にボタン用のスペースを作る:

Item {
    id: dataView
    anchors.bottom: parent.bottom
    width: parent.width
    // Adjust the space based on screen orientation:
    // If we're in portrait mode, we have 3 rows of buttons, otherwise they are all in one row.
    height: parent.height - (mainView.portraitMode ? shadowToggle.implicitHeight * 3 + 25
                                                   : shadowToggle.implicitHeight + 10)
    ...

これで完成だ!

コンテンツ例

サンプルプロジェクト @ code.qt.io

© 2025 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.