ApexCharts
Modern & Interactive Open-source Charts. JS, Angular, Vue, React 지원.
Vue Realtime chart
<template>
<vue-apex-charts
type="line"
height="350"
ref="chart"
:options="chartOptions"
:series="series">
</vue-apex-charts>
</template>
<script lang="ts">
import {Vue, Component} from 'vue-property-decorator';
import VueApexCharts from 'vue-apexcharts';
const UPDATE_INTERVAL_MILLISECONDS = 1000;
const Y_AXIS_COUNTER = 10;
const Y_AXIS_RANGE = UPDATE_INTERVAL_MILLISECONDS * Y_AXIS_COUNTER;
const MAX_SERIES = 1000;
@Component({
components: {
VueApexCharts,
}
})
export default class MainA4yLive extends Vue {
chartOptions = {
theme: {
mode: this.$vuetify.theme.dark ? 'dark' : 'light',
},
chart: {
id: 'realtime',
type: 'line',
animations: {
enabled: true,
easing: 'linear',
dynamicAnimation: {
speed: UPDATE_INTERVAL_MILLISECONDS,
}
},
toolbar: {
show: false
},
zoom: {
enabled: false
}
},
dataLabels: {
enabled: false
},
stroke: {
curve: 'smooth'
},
xaxis: {
type: 'datetime',
range: Y_AXIS_RANGE,
},
yaxis: {
},
legend: {
show: true
},
};
series = [{
name: '',
data: [
{x: new Date(Date.now()), y: 0}
]
}];
intervalHandle = -1;
mounted() {
this.intervalHandle = window.setInterval(() => {
this.series[0].data.push({x: new Date(Date.now()), y: getRandomInt(0, 100)})
if (this.series[0].data.length > 100) {
this.series[0].data.splice(0, this.series[0].data.length);
}
// this.$refs.chart.updateSeries([{data: this.series[0].data}])
this.$refs.chart.updateSeries(this.series);
}, UPDATE_INTERVAL_MILLISECONDS);
}
}
</script>
가장 중요한 옵션은, chartOptions.xaxis.range
의 값 범위를 적절히 구해야 한다. 참고로 datetime
는 JavaScript 에서 Date 이며, 단위는 milliseconds 이다.
또한, 데이터를 계속 푸시하기 때문에, 일정 시간 주기로 계속 clear 해야 한다. 안그럼 오버플로 난다.
vue example
<template>
<div class="example">
<apexchart width="500" height="350" type="line" :options="chartOptions" :series="series"></apexchart>
<div>
<button @click="updateChart">Update!</button>
</div>
</div>
</template>
<script>
export default {
name: 'LineExample',
data: function() {
return {
chartOptions: {
xaxis: {
type: 'datetime',
categories: ['01/01/2003', '02/01/2003','03/01/2003','04/01/2003','05/01/2003','06/01/2003','07/01/2003','08/01/2003'],
},
},
series: [{
name: 'Series A',
data: [30, 40, 45, 50, 49, 60, 70, 91]
}, {
name: 'Series B',
data: [23, 43, 54, 12, 44, 52, 32, 11]
}]
}
},
methods: {
generateDayWiseTimeSeries(baseval, count, yrange) {
var i = 0;
var series = [];
while (i < count) {
var x = baseval;
var y = Math.floor(Math.random() * (yrange.max - yrange.min + 1)) + yrange.min;
series.push([x, y]);
baseval += 86400000;
i++;
}
return series;
},
updateChart() {
let series = [
{
name: 'South',
data: this.generateDayWiseTimeSeries(new Date('11 Feb 2017').getTime(), 20, {
min: 10,
max: 60
})
},
{
name: 'North',
data: this.generateDayWiseTimeSeries(new Date('11 Feb 2017').getTime(), 20, {
min: 10,
max: 20
})
},
{
name: 'Central',
data: this.generateDayWiseTimeSeries(new Date('11 Feb 2017').getTime(), 20, {
min: 10,
max: 15
})
}
]
this.series = series
}
}
}
</script>
Datetime formatting
xaxis: {
type: 'datetime',
labels: {
formatter: function(val) {
const n = Date.parse(val)
const d = new Date(n);
const s = d.toLocaleString();
return s;
}
}
},