간단한 분산형 그래프

QML 애플리케이션에서 Scatter3D 사용.

단순 분산형 그래 프는 Scatter3D 및 QML을 사용하여 간단한 분산형 그래프 시각화를 만드는 방법을 보여줍니다.

그래프와 상호 작용하는 방법에 대한 지침은 이 페이지를 참조하세요.

직접 Qt Quick 애플리케이션을 새로 만드는 방법에 대한 지침은 Qt Creator 도움말을 참조하세요.

예제 실행하기

에서 예제를 실행하려면 Qt Creator에서 Welcome 모드를 열고 Examples 에서 예제를 선택합니다. 자세한 내용은 예제 빌드 및 실행하기를 참조하세요.

애플리케이션 기본 사항

QML 코드를 살펴보기 전에 애플리케이션 main.cpp 을 살펴보세요.

이 애플리케이션은 UI에 '종료' 버튼을 구현하므로 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>

또한 리소스(qrc:)에서 읽을 main.qml 을 설정해야 합니다:

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 항목에는 이 예제에서 사용된 세 가지 시리즈의 데이터 모델이 모두 포함되어 있습니다.

Data.qml 에 데이터를 보관하는 컴포넌트입니다. Item 을 메인 컴포넌트로 사용합니다.

주 컴포넌트에서 데이터 자체를 ListModel 에 추가하고 이름을 dataModel 으로 지정합니다:

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

다른 두 시리즈에 이 두 개를 더 추가하고 dataModelTwodataModelThree 으로 이름을 지정합니다.

그런 다음 main.qml 에서 사용할 수 있도록 데이터 모델을 노출합니다. 이렇게 하려면 주 데이터 컴포넌트에서 별칭으로 정의하면 됩니다:

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

이제 Data.qml 의 데이터를 main.qml 에서 scatterGraph 과 함께 사용할 수 있습니다. 먼저 Scatter3DSeries 을 추가하고 scatterSeries 이라고 부릅니다:

Scatter3DSeries {
    id: scatterSeries

그런 다음 시리즈의 선택 레이블 형식을 설정합니다:

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

마지막으로 시리즈 1에 대한 데이터를 ItemModelScatterDataProxy 에 추가하고 데이터 자체를 프록시에 대한 itemModel 으로 설정합니다:

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

다른 두 시리즈도 같은 방법으로 추가하되, 시리즈별 세부 정보를 약간 수정합니다:

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.