QML
← 전체 컴포넌트

Sparkline Chart

수치 옆이나 표 안에 작은 차트를 넣어 데이터의 추세를 보여 줍니다.

import Syidax.Core.SparklineChart

지원 QML 타입

타입정의 / 역할
추세·비교·비율을 짧게 보여주는 인라인 차트입니다.

예제로 보기

미리보기는 Qt 실행 화면의 이미지입니다. 아래 버튼으로 결과를 전환하세요.

01 기본 구성

숫자 또는 OHLC 데이터를 표시하는 작은 차트입니다.

Qt 실행 화면 · 이미지
기본 구성 · 기본
기본 실행 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story

    readonly property alias chartControl: trend
    property int tick: 0
    readonly property var numbers: [12, 18, 9, 22, 15, 27, 19, 31, 24, 28]
    readonly property var candles: [[10, 14, 9, 13], [13, 15, 11, 12], [12, 16, 12, 15], [15, 15, 10, 11], [11, 14, 10, 14], [14, 18, 13, 17]]
    property QtObject settings: QtObject {
        id: storyArgs
        property string type: "line"
        property string values: ""
        property int width: 160
        property int height: 40
        property string min: ""
        property string max: ""
        property bool smooth: false
        property bool showPoints: false
        property bool showValue: false
        property string textPosition: "top"
        property bool interactive: true
        property string label: "Sparkline chart"
        property string emptyText: "No data"
        property string formatter: "default"
        property string color: ""
        property string fontColor: "#000000"
        property string fontSize: ""
        property string referenceLine: ""
        property real thickness: 2
        property string stockColorScheme: "us"
        property bool stream: false
        property bool animated: true
        property int streamDuration: 1000
        property bool showTooltip: true
    }

    function initialValues() { return storyArgs.values.length ? storyArgs.values : (storyArgs.type === "stock" ? story.candles : story.numbers) }

    function pushValue() {
        story.tick += 1
        const next = Math.round(22 + Math.sin(story.tick * 0.7) * 10)
        if (storyArgs.type === "stock") {
            const current = trend.getValues()
            const open = current.length ? current[current.length - 1].close : 20
            trend.addValue({ open: open, high: Math.max(open, next) + 2, low: Math.min(open, next) - 2, close: next })
        } else trend.addValue(next)
    }

    Connections {
        target: storyArgs

        
    }
    Timer { interval: 500; running: storyArgs.stream; repeat: true; onTriggered: story.pushValue() }
    Column {
        spacing: 12
        Item {
            width: trend.width; height: trend.height + 28
            SySparklineChart {
                id: trend
                y: 28
                width: Math.max(20, storyArgs.width); height: Math.max(20, storyArgs.height)
                type: storyArgs.type
                min: storyArgs.min.trim().length ? Number(storyArgs.min) : Number.NaN
                max: storyArgs.max.trim().length ? Number(storyArgs.max) : Number.NaN
                smooth: storyArgs.smooth; showPoints: storyArgs.showPoints; showValue: storyArgs.showValue
                textPosition: storyArgs.textPosition; interactive: storyArgs.interactive
                label: storyArgs.label; emptyText: storyArgs.emptyText
                formatter: storyArgs.formatter === "default" ? null : (value) => storyArgs.formatter === "fixed2" ? value.toFixed(2) : value.toFixed(1) + "%"
                color: storyArgs.color; fontColor: storyArgs.fontColor; fontSize: storyArgs.fontSize
                referenceLine: storyArgs.referenceLine; thickness: storyArgs.thickness
                stockColorScheme: storyArgs.stockColorScheme
                stream: storyArgs.stream; animated: storyArgs.animated; streamDuration: storyArgs.streamDuration
                showTooltip: storyArgs.showTooltip
                values: story.initialValues()
                onPointSelected: (detail) => output.log(detail.value)
            }
        }
        EventLog { id: output }
    }

}

02 type

다섯 가지 type은 같은 values를 각각 다르게 그립니다.

Qt 실행 화면 · 이미지
type · 기본
기본 실행 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story
    readonly property var numbers: [12, 18, 9, 22, 15, 27, 19, 31, 24, 28]
    readonly property var candles: [[10, 14, 9, 13], [13, 15, 11, 12], [12, 16, 12, 15], [15, 15, 10, 11], [11, 14, 10, 14], [14, 18, 13, 17]]

    Flow {
        width: 560
        spacing: 24
        Column { spacing: 4; SySparklineChart { type: "line"; curved: true; showPoints: true; values: story.numbers } Text { text: "line"; font.family: Theme.monoFontFamily; font.pixelSize: 11; color: Theme.semantic.textSubtle } }
        Column { spacing: 4; SySparklineChart { type: "area"; values: story.numbers } Text { text: "area"; font.family: Theme.monoFontFamily; font.pixelSize: 11; color: Theme.semantic.textSubtle } }
        Column { spacing: 4; SySparklineChart { type: "column"; referenceLine: "20"; values: story.numbers } Text { text: "column"; font.family: Theme.monoFontFamily; font.pixelSize: 11; color: Theme.semantic.textSubtle } }
        Column { spacing: 4; SySparklineChart { type: "pie"; width: 40; height: 40; values: [40, 25, 20, 15] } Text { text: "pie"; font.family: Theme.monoFontFamily; font.pixelSize: 11; color: Theme.semantic.textSubtle } }
        Column { spacing: 4; SySparklineChart { type: "stock"; values: story.candles } Text { text: "stock"; font.family: Theme.monoFontFamily; font.pixelSize: 11; color: Theme.semantic.textSubtle } }
    }
}

03 stream · animated · streamDuration

현재 값 옆에 표시하는 160 × 40 px 스파크라인입니다.

Qt 실행 화면 · 이미지
stream · animated · streamDuration · 기본
QML 코드
import QtQuick
import Syidax.Core

Item {
    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.

    id: story
    readonly property alias chartControl: feed
    readonly property alias feedTimer: timer
    property bool playing: false
    property int tick: 0
    property QtObject settings: QtObject {
        id: storyArgs
        property string type: "line"
        property bool stream: true
        property bool animated: true
        property int streamDuration: 1000
        property int timeInterval: 1500
        property alias interval: storyArgs.timeInterval
        property bool smooth: false
        property bool showPoints: false
        property bool showValue: false
        property string stockColorScheme: "us"
    }

    function seed() {
        const values = [22, 27, 24, 30, 25, 20, 24, 28, 23, 19, 24, 26]
        return storyArgs.type === "stock" ? values.map((close, i) => {
            const open = i > 0 ? values[i - 1] : 20
            return { open: open, high: Math.max(open, close) + 2, low: Math.min(open, close) - 2, close: close }
        }) : values
    }
    function resetFeed() { story.tick = 0; feed.values = story.seed(); feed.activeIndex = -1 }
    function pushValue() {
        story.tick += 1
        const close = Math.round(24 + Math.sin(story.tick * 0.65) * 8 + Math.cos(story.tick * 0.3) * 3)
        const values = feed.getValues()
        if (storyArgs.type === "stock") {
            const open = values.length ? values[values.length - 1].close : 24
            feed.addValue({ open: open, high: Math.max(open, close) + 2, low: Math.min(open, close) - 2, close: close })
        } else feed.addValue(close)
    }
    Connections { target: storyArgs;   }
    Timer {
        id: timer
        interval: Math.max(16, storyArgs.timeInterval)
        running: story.playing
        repeat: true
        onTriggered: story.pushValue()
    }

    Column {
        spacing: 12
        Row {
            spacing: 16
            Text {
                anchors.verticalCenter: parent.verticalCenter
                text: "현재 값"
                font.family: Theme.fontFamily; font.pixelSize: 13; color: Theme.semantic.textSubtle
            }
            Text {
                anchors.verticalCenter: parent.verticalCenter
                width: 36
                text: feed.hasData ? feed.formatValue(feed.valueAt(feed.series.length - 1), feed.series.length - 1) : "—"
                font.family: Theme.monoFontFamily; font.pixelSize: 16; font.weight: Font.Medium
                color: Theme.semantic.textDefault
            }
            SySparklineChart {
                id: feed
                width: 160; height: 40
                type: storyArgs.type; values: story.seed()
                stream: storyArgs.stream; animated: storyArgs.animated; streamDuration: storyArgs.streamDuration
                smooth: storyArgs.smooth; showPoints: storyArgs.showPoints; showValue: storyArgs.showValue
                fontColor: Theme.semantic.textDefault
                stockColorScheme: storyArgs.stockColorScheme
            }
        }
        Row {
            spacing: 8
            SyButton { objectName: "sparkline-stream-toggle"; size: "small"; text: story.playing ? "일시정지" : "재생"; variant: "primary"; onClicked: story.playing = !story.playing }
            SyButton { objectName: "sparkline-stream-push"; size: "small"; text: "값 1개 추가"; onClicked: story.pushValue() }
            SyButton { objectName: "sparkline-stream-reset"; size: "small"; text: "초기화"; onClicked: story.resetFeed() }
        }
        Text {
            visible: "" !== "stream"
            text: ("입력 주기: %1 ms   최대 전환: %2 ms   최근 전환: %3 ms").arg(storyArgs.timeInterval).arg(storyArgs.streamDuration).arg(feed.lastStreamAddTime < 0 ? "—" : !storyArgs.animated || Theme.reducedMotion ? "0" : String(feed.transitionDuration))
            font.family: Theme.monoFontFamily; font.pixelSize: 12; color: Theme.semantic.textSubtle
        }
        Text {
            text: ("값: %1 / %2   추가: %3").arg(feed.series.length).arg(feed.streamCap).arg(story.tick)
            font.family: Theme.monoFontFamily; font.pixelSize: 12; color: Theme.semantic.textSubtle
        }
    }
}

04 pointFocused · pointSelected · valueAdded · valueUpdated · valueRemoved

호버, 클릭, 방향키와 Home / End로 점을 선택합니다.

Qt 실행 화면 · 이미지
pointFocused · pointSelected · valueAdded · valueUpdated · valueRemoved · 기본
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.

    id: story

    

    Column {
        spacing: 12
        Item {
            width: 160
            height: 56
            SySparklineChart {
                id: trend
                y: 16
                width: 160; height: 40
                showPoints: true
                values: [12, 18, 9, 22, 15, 27]
                onPointFocused: (detail) => { if (true) { output.log(("pointFocused: %1 = %2").arg(detail.index).arg(detail.value)) } }
                onPointSelected: (detail) => { if (true) { output.log(("pointSelected: %1 = %2").arg(detail.index).arg(detail.value)) } }
                onValueAdded: (detail) => { if (true) { output.log(("valueAdded: %1").arg(detail.value)) } }
                onValueUpdated: (detail) => { if (true) { output.log("valueUpdated: " + JSON.stringify(detail)) } }
                onValueRemoved: (detail) => { if (true) { output.log("valueRemoved: " + JSON.stringify(detail)) } }
            }
        }
        Row {
            spacing: 8
            SyButton { id: exampleControl1;  visible: true; text: "값 추가"; onClicked: trend.addValue(Math.round(Math.random() * 30)) }
            SyButton { id: exampleControl2;  visible: true; text: "updateValue(0, 5)"; onClicked: trend.updateValue(0, 5) }
            SyButton { id: exampleControl3;  visible: true; text: "removeValue(0)"; onClicked: trend.removeValue(0) }
        }
        EventLog { id: output }
    }
}

05 addValue · updateValue · removeValue · setActiveIndex · getValues · setStockColorScheme

- addValue(value)는 숫자 또는 OHLC 캔들을 추가하고 valueAdded를 발생시킵니다.

Qt 실행 화면 · 이미지
addValue · updateValue · removeValue · setActiveIndex · getValues · setStockColorScheme · 기본
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    // Focused Gallery routes: keep only the selected API and its prerequisites.
    id: featureStory

    readonly property bool stockExample: "" === "setStockColorScheme"
    readonly property var exampleValues: stockExample ? [[10,14,9,13],[13,15,11,12],[12,16,12,15],[15,15,10,11]] : [12,18,9,22,15,27,19,31]

    Column {
        spacing: 24
        Item {
            width: 160
            height: 56
            SySparklineChart { id: feed; y: 16; width: 160; height: 40; stream: true; showValue: true; type: featureStory.stockExample ? "stock" : "line"; values: featureStory.exampleValues }
        }
        Flow {
            width: 560
            spacing: 8
            SyButton { id: exampleControl1;  visible: true; text: "feed.addValue(25)"; variant: "secondary"; size: "small"; onClicked: feed.addValue(25) }
            SyButton { id: exampleControl2;  visible: true; text: "feed.updateValue(0, 5)"; variant: "secondary"; size: "small"; onClicked: feed.updateValue(0, 5) }
            SyButton { id: exampleControl3;  visible: true; text: "feed.removeValue(feed.series.length - 1)"; variant: "secondary"; size: "small"; onClicked: feed.removeValue(feed.series.length - 1) }
            SyButton { visible: true; text: "feed.setActiveIndex(2)"; variant: "secondary"; size: "small"; onClicked: feed.setActiveIndex(2) }
            SyButton { visible: true; text: "console.log(feed.getValues().join(\", \"))"; variant: "secondary"; size: "small"; onClicked: output.log(feed.getValues().join(", ")) }
            SyButton { visible: true; text: "feed.setStockColorScheme(\"kr\")"; variant: "secondary"; size: "small"; onClicked: { feed.setStockColorScheme("kr"); output.log("stockColorScheme: " + feed.stockColorScheme) } }
        }
        Text {
            text: "feed.series.length === " + feed.series.length + "   feed.activeIndex === " + feed.activeIndex
            font.family: Theme.monoFontFamily
            font.pixelSize: 12
            color: Theme.semantic.textSubtle
        }
        EventLog { id: output }
    }
}

06 막대 미니 차트

type · showValue 설정을 적용한 막대 미니 차트 예제입니다.

Qt 실행 화면 · 이미지
막대 미니 차트 · 실행 결과
기본 실행 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story

    readonly property alias chartControl: trend
    property int tick: 0
    readonly property var numbers: [12, 18, 9, 22, 15, 27, 19, 31, 24, 28]
    readonly property var candles: [[10, 14, 9, 13], [13, 15, 11, 12], [12, 16, 12, 15], [15, 15, 10, 11], [11, 14, 10, 14], [14, 18, 13, 17]]
    property QtObject settings: QtObject {
        id: storyArgs
        property string type: "column"
        property string values: ""
        property int width: 160
        property int height: 40
        property string min: ""
        property string max: ""
        property bool smooth: false
        property bool showPoints: false
        property bool showValue: true
        property string textPosition: "top"
        property bool interactive: true
        property string label: "Sparkline chart"
        property string emptyText: "No data"
        property string formatter: "default"
        property string color: ""
        property string fontColor: "#000000"
        property string fontSize: ""
        property string referenceLine: ""
        property real thickness: 2
        property string stockColorScheme: "us"
        property bool stream: false
        property bool animated: true
        property int streamDuration: 1000
        property bool showTooltip: true
    }

    function initialValues() { return storyArgs.values.length ? storyArgs.values : (storyArgs.type === "stock" ? story.candles : story.numbers) }

    function pushValue() {
        story.tick += 1
        const next = Math.round(22 + Math.sin(story.tick * 0.7) * 10)
        if (storyArgs.type === "stock") {
            const current = trend.getValues()
            const open = current.length ? current[current.length - 1].close : 20
            trend.addValue({ open: open, high: Math.max(open, next) + 2, low: Math.min(open, next) - 2, close: next })
        } else trend.addValue(next)
    }

    Connections {
        target: storyArgs

        
    }
    Timer { interval: 500; running: storyArgs.stream; repeat: true; onTriggered: story.pushValue() }
    Column {
        spacing: 12
        Item {
            width: trend.width; height: trend.height + 28
            SySparklineChart {
                id: trend
                y: 28
                width: Math.max(20, storyArgs.width); height: Math.max(20, storyArgs.height)
                type: storyArgs.type
                min: storyArgs.min.trim().length ? Number(storyArgs.min) : Number.NaN
                max: storyArgs.max.trim().length ? Number(storyArgs.max) : Number.NaN
                smooth: storyArgs.smooth; showPoints: storyArgs.showPoints; showValue: storyArgs.showValue
                textPosition: storyArgs.textPosition; interactive: storyArgs.interactive
                label: storyArgs.label; emptyText: storyArgs.emptyText
                formatter: storyArgs.formatter === "default" ? null : (value) => storyArgs.formatter === "fixed2" ? value.toFixed(2) : value.toFixed(1) + "%"
                color: storyArgs.color; fontColor: storyArgs.fontColor; fontSize: storyArgs.fontSize
                referenceLine: storyArgs.referenceLine; thickness: storyArgs.thickness
                stockColorScheme: storyArgs.stockColorScheme
                stream: storyArgs.stream; animated: storyArgs.animated; streamDuration: storyArgs.streamDuration
                showTooltip: storyArgs.showTooltip
                values: story.initialValues()
                onPointSelected: (detail) => output.log(detail.value)
            }
        }
        EventLog { id: output }
    }

}

07 원형 미니 차트

type 설정을 적용한 원형 미니 차트 예제입니다.

Qt 실행 화면 · 이미지
원형 미니 차트 · 실행 결과
기본 실행 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story

    readonly property alias chartControl: trend
    property int tick: 0
    readonly property var numbers: [12, 18, 9, 22, 15, 27, 19, 31, 24, 28]
    readonly property var candles: [[10, 14, 9, 13], [13, 15, 11, 12], [12, 16, 12, 15], [15, 15, 10, 11], [11, 14, 10, 14], [14, 18, 13, 17]]
    property QtObject settings: QtObject {
        id: storyArgs
        property string type: "pie"
        property string values: ""
        property int width: 160
        property int height: 40
        property string min: ""
        property string max: ""
        property bool smooth: false
        property bool showPoints: false
        property bool showValue: false
        property string textPosition: "top"
        property bool interactive: true
        property string label: "Sparkline chart"
        property string emptyText: "No data"
        property string formatter: "default"
        property string color: ""
        property string fontColor: "#000000"
        property string fontSize: ""
        property string referenceLine: ""
        property real thickness: 2
        property string stockColorScheme: "us"
        property bool stream: false
        property bool animated: true
        property int streamDuration: 1000
        property bool showTooltip: true
    }

    function initialValues() { return storyArgs.values.length ? storyArgs.values : (storyArgs.type === "stock" ? story.candles : story.numbers) }

    function pushValue() {
        story.tick += 1
        const next = Math.round(22 + Math.sin(story.tick * 0.7) * 10)
        if (storyArgs.type === "stock") {
            const current = trend.getValues()
            const open = current.length ? current[current.length - 1].close : 20
            trend.addValue({ open: open, high: Math.max(open, next) + 2, low: Math.min(open, next) - 2, close: next })
        } else trend.addValue(next)
    }

    Connections {
        target: storyArgs

        
    }
    Timer { interval: 500; running: storyArgs.stream; repeat: true; onTriggered: story.pushValue() }
    Column {
        spacing: 12
        Item {
            width: trend.width; height: trend.height + 28
            SySparklineChart {
                id: trend
                y: 28
                width: Math.max(20, storyArgs.width); height: Math.max(20, storyArgs.height)
                type: storyArgs.type
                min: storyArgs.min.trim().length ? Number(storyArgs.min) : Number.NaN
                max: storyArgs.max.trim().length ? Number(storyArgs.max) : Number.NaN
                smooth: storyArgs.smooth; showPoints: storyArgs.showPoints; showValue: storyArgs.showValue
                textPosition: storyArgs.textPosition; interactive: storyArgs.interactive
                label: storyArgs.label; emptyText: storyArgs.emptyText
                formatter: storyArgs.formatter === "default" ? null : (value) => storyArgs.formatter === "fixed2" ? value.toFixed(2) : value.toFixed(1) + "%"
                color: storyArgs.color; fontColor: storyArgs.fontColor; fontSize: storyArgs.fontSize
                referenceLine: storyArgs.referenceLine; thickness: storyArgs.thickness
                stockColorScheme: storyArgs.stockColorScheme
                stream: storyArgs.stream; animated: storyArgs.animated; streamDuration: storyArgs.streamDuration
                showTooltip: storyArgs.showTooltip
                values: story.initialValues()
                onPointSelected: (detail) => output.log(detail.value)
            }
        }
        EventLog { id: output }
    }

}

08 고정 값 범위

min · max · showValue 설정을 적용한 고정 값 범위 예제입니다.

Qt 실행 화면 · 이미지
고정 값 범위 · 실행 결과
기본 실행 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story

    readonly property alias chartControl: trend
    property int tick: 0
    readonly property var numbers: [12, 18, 9, 22, 15, 27, 19, 31, 24, 28]
    readonly property var candles: [[10, 14, 9, 13], [13, 15, 11, 12], [12, 16, 12, 15], [15, 15, 10, 11], [11, 14, 10, 14], [14, 18, 13, 17]]
    property QtObject settings: QtObject {
        id: storyArgs
        property string type: "line"
        property string values: ""
        property int width: 160
        property int height: 40
        property string min: "0"
        property string max: "100"
        property bool smooth: false
        property bool showPoints: false
        property bool showValue: true
        property string textPosition: "top"
        property bool interactive: true
        property string label: "Sparkline chart"
        property string emptyText: "No data"
        property string formatter: "default"
        property string color: ""
        property string fontColor: "#000000"
        property string fontSize: ""
        property string referenceLine: ""
        property real thickness: 2
        property string stockColorScheme: "us"
        property bool stream: false
        property bool animated: true
        property int streamDuration: 1000
        property bool showTooltip: true
    }

    function initialValues() { return storyArgs.values.length ? storyArgs.values : (storyArgs.type === "stock" ? story.candles : story.numbers) }

    function pushValue() {
        story.tick += 1
        const next = Math.round(22 + Math.sin(story.tick * 0.7) * 10)
        if (storyArgs.type === "stock") {
            const current = trend.getValues()
            const open = current.length ? current[current.length - 1].close : 20
            trend.addValue({ open: open, high: Math.max(open, next) + 2, low: Math.min(open, next) - 2, close: next })
        } else trend.addValue(next)
    }

    Connections {
        target: storyArgs

        
    }
    Timer { interval: 500; running: storyArgs.stream; repeat: true; onTriggered: story.pushValue() }
    Column {
        spacing: 12
        Item {
            width: trend.width; height: trend.height + 28
            SySparklineChart {
                id: trend
                y: 28
                width: Math.max(20, storyArgs.width); height: Math.max(20, storyArgs.height)
                type: storyArgs.type
                min: storyArgs.min.trim().length ? Number(storyArgs.min) : Number.NaN
                max: storyArgs.max.trim().length ? Number(storyArgs.max) : Number.NaN
                smooth: storyArgs.smooth; showPoints: storyArgs.showPoints; showValue: storyArgs.showValue
                textPosition: storyArgs.textPosition; interactive: storyArgs.interactive
                label: storyArgs.label; emptyText: storyArgs.emptyText
                formatter: storyArgs.formatter === "default" ? null : (value) => storyArgs.formatter === "fixed2" ? value.toFixed(2) : value.toFixed(1) + "%"
                color: storyArgs.color; fontColor: storyArgs.fontColor; fontSize: storyArgs.fontSize
                referenceLine: storyArgs.referenceLine; thickness: storyArgs.thickness
                stockColorScheme: storyArgs.stockColorScheme
                stream: storyArgs.stream; animated: storyArgs.animated; streamDuration: storyArgs.streamDuration
                showTooltip: storyArgs.showTooltip
                values: story.initialValues()
                onPointSelected: (detail) => output.log(detail.value)
            }
        }
        EventLog { id: output }
    }

}

09 값 표시 형식

formatter · showValue 설정을 적용한 값 표시 형식 예제입니다.

Qt 실행 화면 · 이미지
값 표시 형식 · 실행 결과
기본 실행 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story

    readonly property alias chartControl: trend
    property int tick: 0
    readonly property var numbers: [12, 18, 9, 22, 15, 27, 19, 31, 24, 28]
    readonly property var candles: [[10, 14, 9, 13], [13, 15, 11, 12], [12, 16, 12, 15], [15, 15, 10, 11], [11, 14, 10, 14], [14, 18, 13, 17]]
    property QtObject settings: QtObject {
        id: storyArgs
        property string type: "line"
        property string values: ""
        property int width: 160
        property int height: 40
        property string min: ""
        property string max: ""
        property bool smooth: false
        property bool showPoints: false
        property bool showValue: true
        property string textPosition: "top"
        property bool interactive: true
        property string label: "Sparkline chart"
        property string emptyText: "No data"
        property string formatter: "percent"
        property string color: ""
        property string fontColor: "#000000"
        property string fontSize: ""
        property string referenceLine: ""
        property real thickness: 2
        property string stockColorScheme: "us"
        property bool stream: false
        property bool animated: true
        property int streamDuration: 1000
        property bool showTooltip: true
    }

    function initialValues() { return storyArgs.values.length ? storyArgs.values : (storyArgs.type === "stock" ? story.candles : story.numbers) }

    function pushValue() {
        story.tick += 1
        const next = Math.round(22 + Math.sin(story.tick * 0.7) * 10)
        if (storyArgs.type === "stock") {
            const current = trend.getValues()
            const open = current.length ? current[current.length - 1].close : 20
            trend.addValue({ open: open, high: Math.max(open, next) + 2, low: Math.min(open, next) - 2, close: next })
        } else trend.addValue(next)
    }

    Connections {
        target: storyArgs

        
    }
    Timer { interval: 500; running: storyArgs.stream; repeat: true; onTriggered: story.pushValue() }
    Column {
        spacing: 12
        Item {
            width: trend.width; height: trend.height + 28
            SySparklineChart {
                id: trend
                y: 28
                width: Math.max(20, storyArgs.width); height: Math.max(20, storyArgs.height)
                type: storyArgs.type
                min: storyArgs.min.trim().length ? Number(storyArgs.min) : Number.NaN
                max: storyArgs.max.trim().length ? Number(storyArgs.max) : Number.NaN
                smooth: storyArgs.smooth; showPoints: storyArgs.showPoints; showValue: storyArgs.showValue
                textPosition: storyArgs.textPosition; interactive: storyArgs.interactive
                label: storyArgs.label; emptyText: storyArgs.emptyText
                formatter: storyArgs.formatter === "default" ? null : (value) => storyArgs.formatter === "fixed2" ? value.toFixed(2) : value.toFixed(1) + "%"
                color: storyArgs.color; fontColor: storyArgs.fontColor; fontSize: storyArgs.fontSize
                referenceLine: storyArgs.referenceLine; thickness: storyArgs.thickness
                stockColorScheme: storyArgs.stockColorScheme
                stream: storyArgs.stream; animated: storyArgs.animated; streamDuration: storyArgs.streamDuration
                showTooltip: storyArgs.showTooltip
                values: story.initialValues()
                onPointSelected: (detail) => output.log(detail.value)
            }
        }
        EventLog { id: output }
    }

}

10 영역 미니 차트

type · smooth 설정을 적용한 영역 미니 차트 예제입니다.

Qt 실행 화면 · 이미지
영역 미니 차트 · 실행 결과
기본 실행 화면
QML 코드
import QtQuick
import Syidax.Core

Item {
    component EventLog: Rectangle {
        id: logBox
        property var lines: []
        implicitWidth: 440
        implicitHeight: Math.max(56, logText.implicitHeight + 24)
        radius: 4; color: Theme.semantic.backgroundBold
        function log(value) { lines = lines.slice(-3).concat([String(value)]) }
        Text {
            id: logText; x: 12; y: 12; width: parent.width - 24
            text: logBox.lines.length ? logBox.lines.join("\n") : "컨트롤을 조작하면 이벤트 결과가 표시됩니다."
            wrapMode: Text.Wrap; color: Theme.semantic.textDefault
            font.family: Theme.monoFontFamily; font.pixelSize: 12
        }
    }

    implicitWidth: Math.max(360, childrenRect.width)
    implicitHeight: childrenRect.height
    id: story

    readonly property alias chartControl: trend
    property int tick: 0
    readonly property var numbers: [12, 18, 9, 22, 15, 27, 19, 31, 24, 28]
    readonly property var candles: [[10, 14, 9, 13], [13, 15, 11, 12], [12, 16, 12, 15], [15, 15, 10, 11], [11, 14, 10, 14], [14, 18, 13, 17]]
    property QtObject settings: QtObject {
        id: storyArgs
        property string type: "area"
        property string values: ""
        property int width: 160
        property int height: 40
        property string min: ""
        property string max: ""
        property bool smooth: true
        property bool showPoints: false
        property bool showValue: false
        property string textPosition: "top"
        property bool interactive: true
        property string label: "Sparkline chart"
        property string emptyText: "No data"
        property string formatter: "default"
        property string color: ""
        property string fontColor: "#000000"
        property string fontSize: ""
        property string referenceLine: ""
        property real thickness: 2
        property string stockColorScheme: "us"
        property bool stream: false
        property bool animated: true
        property int streamDuration: 1000
        property bool showTooltip: true
    }

    function initialValues() { return storyArgs.values.length ? storyArgs.values : (storyArgs.type === "stock" ? story.candles : story.numbers) }

    function pushValue() {
        story.tick += 1
        const next = Math.round(22 + Math.sin(story.tick * 0.7) * 10)
        if (storyArgs.type === "stock") {
            const current = trend.getValues()
            const open = current.length ? current[current.length - 1].close : 20
            trend.addValue({ open: open, high: Math.max(open, next) + 2, low: Math.min(open, next) - 2, close: next })
        } else trend.addValue(next)
    }

    Connections {
        target: storyArgs

        
    }
    Timer { interval: 500; running: storyArgs.stream; repeat: true; onTriggered: story.pushValue() }
    Column {
        spacing: 12
        Item {
            width: trend.width; height: trend.height + 28
            SySparklineChart {
                id: trend
                y: 28
                width: Math.max(20, storyArgs.width); height: Math.max(20, storyArgs.height)
                type: storyArgs.type
                min: storyArgs.min.trim().length ? Number(storyArgs.min) : Number.NaN
                max: storyArgs.max.trim().length ? Number(storyArgs.max) : Number.NaN
                smooth: storyArgs.smooth; showPoints: storyArgs.showPoints; showValue: storyArgs.showValue
                textPosition: storyArgs.textPosition; interactive: storyArgs.interactive
                label: storyArgs.label; emptyText: storyArgs.emptyText
                formatter: storyArgs.formatter === "default" ? null : (value) => storyArgs.formatter === "fixed2" ? value.toFixed(2) : value.toFixed(1) + "%"
                color: storyArgs.color; fontColor: storyArgs.fontColor; fontSize: storyArgs.fontSize
                referenceLine: storyArgs.referenceLine; thickness: storyArgs.thickness
                stockColorScheme: storyArgs.stockColorScheme
                stream: storyArgs.stream; animated: storyArgs.animated; streamDuration: storyArgs.streamDuration
                showTooltip: storyArgs.showTooltip
                values: story.initialValues()
                onPointSelected: (detail) => output.log(detail.value)
            }
        }
        EventLog { id: output }
    }

}

API 76

항목을 가리키거나 선택하면 QML 예제와 복사 버튼이 나타납니다.

속성

속성타입기본값설명
var[]데이터: 배열, "1, 2, 3" 문자열, JSON 문자열. stock은 { open, high, low, close } 또는 [o, h, l, c] 캔들. 메서드 호출 뒤에는 파싱된 배열로 교체됨.
string"line""line" · "area" · "column" · "pie" · "stock".
realNaN세로 범위 고정(NaN = 데이터에서). pie에는 없음.
realNaN세로 범위 고정(NaN = 데이터에서). pie에는 없음.
boolfalse선/영역의 곡선. curved는 기존 이름 호환용 별칭입니다.
boolfalse모든 점에 점 표시. 끄면 활성 점만(그리고 단 하나뿐인 점).
boolfalse활성(없으면 마지막) 점의 라벨.
string"top""top"(자리가 없으면 아래로) 또는 "bottom".
string""숫자/px, pt, em/rem, %. 기본 12 px.
string"#000000"라벨 색.
var (function)null라벨과 툴팁을 위한 (value, index) => string.
string""시리즈 색("" = Theme.semantic.borderBrandBold).
real2선 굵기와 점 반지름.
string""글자로 된 숫자: 점선, 위 / 아래 색, 막대와 영역의 기준.
string"us""us"(상승 초록, 하락 빨강) 또는 "kr"(상승 빨강, 하락 파랑).
booltrue호버, 클릭, 키, 툴팁.
booltrue점이 활성인 동안 차트 위에 뜨는 값.
int-1강조된 점. -1 = 없음. 대입하면 시그널 없이 그려짐.
boolfalseaddValue가 streamCap개의 굴러가는 창을 유지.
int10첫 스트림의 값 개수로 초기화하고 유지합니다. 비어 있으면 10. QML 확장입니다.
string"No data"시리즈가 비어 있을 때 표시.
booltruefalse면 데이터 상태 사이의 변형 애니메이션을 건너뜀 — 값이 바로 바뀜.
int1000stream이 켜진 동안의 변형 시간(ms). 아니면 빠른 100 ms 전환.
string"Sparkline chart"차트의 접근성 이름(Accessible.name).
var (읽기 전용)—파싱된 숫자 또는 캔들.
bool (읽기 전용)—시리즈가 비어 있지 않음 · type === "stock" · 유효한 referenceLine.
bool (읽기 전용)—시리즈가 비어 있지 않음 · type === "stock" · 유효한 referenceLine.
bool (읽기 전용)—시리즈가 비어 있지 않음 · type === "stock" · 유효한 referenceLine.
real (읽기 전용)—파싱된 기준값(없으면 NaN).
var (읽기 전용)—아이템 좌표의 계산 결과 { points, rects, candles, slices, baselineY }.
color (읽기 전용)—결정된 색.
color (읽기 전용)—결정된 색.
color (읽기 전용)—결정된 색.
color (읽기 전용)—결정된 색.
color (읽기 전용)—결정된 색.
color (읽기 전용)—결정된 색.

추가 속성

이름타입 / 기본값설명
real (px) · 160인라인 스파크라인의 논리 너비입니다. 높이 40을 유지하고 너비를 바꿔 데이터 밀도를 비교하세요. 축은 추가되지 않습니다.
real (px) · 40인라인 스파크라인의 논리 높이입니다. 너비 160을 유지하고 높이를 바꿔 보세요. 데이터 범위가 주어진 높이에 대응합니다.

메서드

메서드설명
항목 하나를 파싱해 덧붙이고, stream이면 streamCap에 맞춰 자르고, valueAdded를 냄. 잘못된 입력은 무시.
index의 항목을 교체하고 valueUpdated를 냄. 범위 밖이거나 잘못되면 무시.
항목을 지우고, activeIndex를 범위 안에 두고, valueRemoved를 냄. 범위 밖이면 무시.
반올림·범위 제한 후 변경 시 pointFocused를 발생시킵니다. activeIndex = -1로 해제합니다.
activeIndex를 설정하고 pointFocused를 냄(호버와 키가 호출하는 것).
독립 배열을 반환하며 주가 객체도 복사합니다.
stockColorScheme을 설정.
인덱스의 숫자(캔들 → close) · 형식화된 글자 · values에 쓰이는 파서.
인덱스의 숫자(캔들 → close) · 형식화된 글자 · values에 쓰이는 파서.
인덱스의 숫자(캔들 → close) · 형식화된 글자 · values에 쓰이는 파서.

시그널

시그널인자시점
detail: { index, value }포인터·키보드·setActiveIndex로 새 점/조각에 포커스가 이동할 때.
detail: { index, value }차트 클릭, 또는 활성 점이 있을 때 Return / Space. interactive가 꺼져 있으면 없음.
detail: { index, value, values }유효한 항목으로 addValue()한 뒤.
detail: { index, value, oldValue, values }유효한 인덱스와 항목으로 updateValue()한 뒤.
detail: { index, value, values }유효한 인덱스로 removeValue()한 뒤.

시그널

항목동작 / 조건
values를 대입하면 속성 자체의 valuesChanged / seriesChanged만 발생합니다.
values를 대입하면 속성 자체의 valuesChanged / seriesChanged만 발생합니다.

동작

항목동작 / 조건
시리즈가 비어 있을 때 표시.
min / max로 세로 범위를 고정하며 단일 값 범위는 ±1로 넓힙니다.
min / max로 세로 범위를 고정하며 단일 값 범위는 ±1로 넓힙니다.
글자로 된 숫자: 점선, 위 / 아래 색, 막대와 영역의 기준.
차트 클릭, 또는 활성 점이 있을 때 Return / Space. interactive가 꺼져 있으면 없음.
반올림·범위 제한 후 변경 시 pointFocused를 발생시킵니다. activeIndex = -1로 해제합니다.
포인터·키보드·setActiveIndex로 새 점/조각에 포커스가 이동할 때.
호버, 클릭, 키, 툴팁.
점이 활성인 동안 차트 위에 뜨는 값.
활성(없으면 마지막) 점의 라벨.
"top"(자리가 없으면 아래로) 또는 "bottom".
숫자/px, pt, em/rem, %. 기본 12 px.
라벨과 툴팁을 위한 (value, index) => string.
addValue가 streamCap개의 굴러가는 창을 유지.
항목 하나를 파싱해 덧붙이고, stream이면 streamCap에 맞춰 자르고, valueAdded를 냄. 잘못된 입력은 무시.
false면 데이터 상태 사이의 변형 애니메이션을 건너뜀 — 값이 바로 바뀜.
stream이 켜진 동안의 변형 시간(ms). 아니면 빠른 100 ms 전환.
시리즈 색("" = Theme.semantic.borderBrandBold).
"us"(상승 초록, 하락 빨강) 또는 "kr"(상승 빨강, 하락 파랑).
차트의 접근성 이름(Accessible.name).

키보드

항목동작 / 조건
SyProgressBar / SyProgressCircular(시리즈 대신 값 하나), SyCard와 SyTable(스파크라인이 주로 놓이는 곳).