TOAST UI Chart
Spread your data on TOAST UI Chart. TOAST UI Chart is Beautiful Statistical Data Visualization library.
Auto Size
chart.width
또는 chart.height
옵션을 auto
로 설정하면 차트 컨테이너의 크기로 자동으로 설정된다. 만약 차트 컨테이너의 크기를 상댓값으로 설정하면 차트의 크기가 브라우저 창 크기에 따라 자동으로 변경될 것이다. 또한 responsive
옵션과 함께 사용하면 창 크기가 변경될 때마다 updateOptions
API를 따로 호출하지 않아도 차트 크기에 맞는 옵션을 자유롭게 설정해줄 수 있다.
const options = {
chart: { width: 'auto', height:'auto' }
responsive: {
rules: [
...
]
}
};
const el = document.getElementById('chart');
const chart = toastui.Chart.areaChart({ el, data, options });
Vue.js LineChart Component
<template>
<div ref="el" :style="style"></div>
</template>
<script lang="ts">
import {Vue, Component, Prop, Ref, Watch, Emit} from 'vue-property-decorator';
import ToastChart, {
LineChart as ToastLineChart,
LineChartOptions,
LineSeriesData,
} from '@toast-ui/chart';
import type {LineSeriesDataType} from '@toast-ui/chart/types/options';
import '@toast-ui/chart/dist/toastui-chart.min.css';
const CLICK_LEGEND_LABEL = 'clickLegendLabel';
const CLICK_LEGEND_CHECKBOX = 'clickLegendCheckbox';
const SELECT_SERIES = 'selectSeries';
const UNSELECT_SERIES = 'unselectSeries';
const HOVER_SERIES = 'hoverSeries';
const UNHOVER_SERIES = 'unhoverSeries';
const ZOOM = 'zoom';
const RESET_ZOOM = 'resetZoom';
@Component
export default class LineChart extends Vue {
@Prop({type: Object, required: true})
readonly data!: LineSeriesData;
@Prop({type: Object, default: () => new Object()})
readonly options!: LineChartOptions;
@Prop({type: [Number, String], default: '100%'})
readonly width?: number | string;
@Prop({type: [Number, String], default: '40vh'})
readonly height?: number | string;
@Prop({type: [Number, String], default: '12%'})
readonly minWidth?: number | string;
@Prop({type: [Number, String], default: '12vh'})
readonly minHeight?: number | string;
@Prop({type: [Number, String]})
readonly maxWidth?: number | string;
@Prop({type: [Number, String]})
readonly maxHeight?: number | string;
@Ref()
readonly el!: HTMLDivElement;
chart!: ToastLineChart;
@Watch('data', {deep: true})
watchData(newData) {
this.chart.setData(newData);
}
@Watch('options', {deep: true})
watchOptions(newOptions) {
this.chart.setOptions(newOptions);
}
mounted() {
this.chart = ToastChart.lineChart({
el: this.el,
data: this.data,
options: this.options,
});
this.chart.on(CLICK_LEGEND_LABEL, e => this.clickLegendLabel(e));
this.chart.on(CLICK_LEGEND_CHECKBOX, e => this.clickLegendCheckbox(e));
this.chart.on(SELECT_SERIES, e => this.selectSeries(e));
this.chart.on(UNSELECT_SERIES, e => this.unselectSeries(e));
this.chart.on(HOVER_SERIES, e => this.hoverSeries(e));
this.chart.on(UNHOVER_SERIES, e => this.unhoverSeries(e));
this.chart.on(ZOOM, e => this.zoom(e));
this.chart.on(RESET_ZOOM, e => this.resetZoom(e));
}
beforeDestroy() {
this.chart.destroy();
}
get style() {
let result = '';
if (this.width) {
result += `width: ${this.width};`;
}
if (this.height) {
result += `height: ${this.height};`;
}
if (this.minWidth) {
result += `min-width: ${this.minWidth};`;
}
if (this.minHeight) {
result += `min-height: ${this.minHeight};`;
}
if (this.maxWidth) {
result += `max-width: ${this.maxWidth};`;
}
if (this.maxHeight) {
result += `max-height: ${this.maxHeight};`;
}
return result;
}
@Emit(CLICK_LEGEND_LABEL)
clickLegendLabel(event) {
return event;
}
@Emit(CLICK_LEGEND_CHECKBOX)
clickLegendCheckbox(event) {
return event;
}
@Emit(SELECT_SERIES)
selectSeries(event) {
return event;
}
@Emit(UNSELECT_SERIES)
unselectSeries(event) {
return event;
}
@Emit(HOVER_SERIES)
hoverSeries(event) {
return event;
}
@Emit(UNHOVER_SERIES)
unhoverSeries(event) {
return event;
}
@Emit(ZOOM)
zoom(event) {
return event;
}
@Emit(RESET_ZOOM)
resetZoom(event) {
return event;
}
addData(data: Array<LineSeriesDataType>, category?: string) {
this.chart.addData(data, category);
}
}
</script>
Live chart usage
<i18n lang="yaml">
en:
title: 'ANSWER PLUGIN'
ko:
title: '엔서 플러그인'
</i18n>
<template>
<v-container>
<v-row>
<line-chart
ref="chart"
:data="chartProps.data"
:options="chartProps.options"
></line-chart>
</v-row>
</v-container>
</template>
<script lang="ts">
import {Vue, Component, Ref} from 'vue-property-decorator';
import LineChart from '@/chart/LineChart.vue';
@Component({
components: {
LineChart,
},
})
export default class SensorView extends Vue {
@Ref()
chart!: LineChart;
chartProps = {
options: {
usageStatistics: false,
chart: {
width: 'auto',
height: 'auto',
title: '24-hr Average Temperature',
},
yAxis: {
title: 'Temperature (Celsius)',
pointOnColumn: true,
},
xAxis: {
title: 'Years',
},
series: {
shift: true,
showDot: false,
// zoomable: true,
spline: true,
},
},
data: {
categories: ['2020', '2021', '2022', '2023'],
series: [
{
name: 'Seoul',
data: [-3.5, -1.1, 4.0, 11.3],
},
{
name: 'Seattle',
data: [3.8, 5.6, 7.0, 9.1],
},
{
name: 'Sydney',
data: [22.1, 22.0, 20.9, 18.3],
},
{
name: 'Moskva',
data: [-10.3, -9.1, -4.1, 4.4],
},
{
name: 'Jungfrau',
data: [-13.2, -13.7, -13.1, -10.3],
},
],
},
};
category = 2024;
created() {
window.setInterval(() => {
const seoul = Math.round(Math.random() * 100);
const seattle = Math.round(Math.random() * 100);
const sydney = Math.round(Math.random() * 100);
const moskva = Math.round(Math.random() * 100);
const jungfrau = Math.round(Math.random() * 100);
const data = [seoul, seattle, sydney, moskva, jungfrau];
const category = this.category.toString();
this.chart.addData(data, category);
this.category++;
}, 1000);
}
}
</script>
Troubleshooting
라이브 차트 에서 addData
X축이 하나씩 사라지는 현상
최초에 다음과 같은 코드로 차트 다이어 그램을 생성할 것이다:
이 때, 세 번째 줄에 해당되는 data
가 있는데, 이 값을 변경하면 안된다. 값을 추가할 경우에만 addData
로 추가해야 한다.
See also
- TOAST UI Chart (tui.chart)
- TOAST UI Editor (tui.editor)
- TOAST UI Grid (tui.grid)
- TOAST UI Calendar (tui.calendar)
- TOAST UI Image-editor (tui.image-editor)