簡単な散布図
QMLアプリケーションでScatter3D 。
Simple Scatter Graphでは、Scatter3D と QML を使って簡単な散布図グラフを視覚化する方法を示しています。
グラフの操作方法については、このページを参照してください。
新しい Qt Quick アプリケーションを作成する方法については、Qt Creator のヘルプを参照してください。
サンプルを実行する
Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。
アプリケーションの基本
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つの系列にもこれを追加し、dataModelTwo
とdataModelThree
と名付ける。
そして、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) ...
これで完成だ!
コンテンツ例
©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 ここで提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。