push
와 addPoint
는 각각 JavaScript 배열 메서드와 Highcharts 라이브러리의 메서드로, 사용 목적과 동작 방식이 다릅니다.push
는 JavaScript 배열 메서드로, 배열의 끝에 하나 이상의 요소를 추가합니다.
사용 예시
let arr = [1, 2, 3];
arr.push(4); // arr은 이제 [1, 2, 3, 4]
특징
배열의 길이를 반환합니다.
배열의 상태를 직접 변경합니다.
DOM이나 UI에 직접적인 영향을 주지 않습니다. 단순히 데이터 구조를 변경할 뿐입니다.
addPoint
는 Highcharts 라이브러리의 메서드로, 차트의 시리즈에 새로운 데이터를 추가합니다.
사용 예시
chart.series[0].addPoint([x, y], true, true);
특징
첫 번째 인자는 추가할 데이터 포인트입니다.
두 번째 인자는 차트를 즉시 갱신할지 여부를 결정합니다. true
로 설정하면 차트가 즉시 다시 그려집니다.
세 번째 인자는 시리즈의 데이터 포인트가 일정 개수를 초과할 경우, 가장 오래된 데이터를 제거할지 여부를 결정합니다.
차트의 UI에 직접적인 영향을 미칩니다. 데이터를 추가하면 차트가 업데이트됩니다.
목적: push
는 배열에 데이터를 추가하는 데 사용되며, addPoint
는 차트에 데이터를 추가하고 즉시 갱신하는 데 사용됩니다.
영향 범위: push
는 데이터 구조에만 영향을 미치고, addPoint
는 차트의 시각적 표현에 영향을 미칩니다.
사용 환경: push
는 일반적인 JavaScript 배열 조작에 사용되며, addPoint
는 Highcharts와 같은 차트 라이브러리에서 사용됩니다.
따라서, 차트의 시각적 업데이트가 필요한 경우 addPoint
를 사용하고, 단순히 데이터 배열을 조작할 때는 push
를 사용합니다.
<script src="https://code.jquery.com/jquery-3.7.0.js" integrity="sha256-JlqSTELeR4TLqP0OG9dxM7yDPqX1ox/HfgiSLBj8+kM=" crossorigin="anonymous"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<div class="chart" id="useChart"></div>
body{
background: #282d3a;
}
.chart1{
width: 300px;
height: 300px;
border: 1px solid;
box-sizing: border-box;
padding: 10px;
}
.chart2{
width: 900px;
height: 600px;
border: 1px solid;
box-sizing: border-box;
padding: 10px;
}
.MAT20{
margin-top: 20px;
}
.highcharts-tooltip-box {
fill: black;
fill-opacity: 0.4;
stroke-width: 0;
}
.blockChart {
width: 500px;
height: 250px;
border: 1px solid;
box-sizing: border-box;
padding: 10px;
}
var operChart;
var has = false; // 시간 동기화 구분 값
$(document).ready(function() {
// setTimeout으로 1초 뒤 차트 생성
setTimeout(function() {
init();
chartData();
has = true;
}, 1000);
// 이후 차트가 생성 되면 데이터 1초 단위로 갱신
setInterval(function() {
if (has) {
upd();
}
}, 1000);
});
// 1. 차트 생성
function init() {
var oprnOpts = {
target: 'useChart',
tickInterval: 150,
data: [{
name: '아이템1',
color: '#f7a35c',
data: []
}, {
name: '아이템2',
color: '#fdfefe',
data: []
}]
};
operChart = Graphds(oprnOpts);
}
// 2. 초기 셋팅
function chartData() {
var a = getAixArr();
var b = getAixArr();
operChart.series[0].setData(a);
operChart.series[1].setData(b);
}
// 2-1. 시간 변수
var setOprn = {
beforeT: 60000, // 1분전부터
count: 60, // 60개
interval: 1000 // 1초
}
// 2-2. 차트 초기값 데이터
function getAixArr() {
var ts = [];
var setDate = new Date;
var obj = setOprn;
var d = Date.parse(setDate) - obj.beforeT;
var t;
for (var i = 0; i < obj.count; i++) {
// 분 : 초
t = new Date(d + (i * obj.interval));
// 데이터 예시 { x : 1684193617136, y : 30 ~ 60}
ts[i] = {
x: t.getTime(),
y: Math.floor(30 + Math.random() * 30)
};
}
return ts;
}
// 3. 데이터 갱신
function upd() {
var currTime = new Date().getTime();
var data1 = Math.floor(30 + Math.random() * 30);
var data2 = Math.floor(30 + Math.random() * 30);
operChart.series[0].addPoint([currTime, data1], false, true); // false로 지정해야 부드럽게 넘어감
operChart.series[1].addPoint([currTime, data2], true, true);
}
// 차트 옵션
function Graphds(opts) {
var chart;
var _opts = opts || {};
return Highcharts.chart(_opts.target, { // _opts = { target }
chart: {
marginTop: 10,
type: 'spline',
animation: Highcharts.svg,
marginRight: 10,
backgroundColor: 'transparent'
},
title: {
text: null
},
credits: {
enabled: false
},
xAxis: {
type: 'datetime',
tickPixelInterval: _opts.tickInterval,
labels: {
format: '{value:%H:%M:%S}',
style: {
color: '#ccc'
}
}
},
yAxis: {
title: {
text: false
},
labels: {
style: {
color: '#ccc'
}
},
plotLines: [{
value: 0,
width: 1,
color: '#99ccff'
}]
},
plotOptions: {
spline: {
marker: {
enabled: false
}
}
},
tooltip: {
positioner: function() {
return {
x: 45,
y: 15
};
},
style: {
color: 'white'
},
shared: true,
crosshairs: true,
xDateFormat: '%H:%M:%S',
valueDecimals: 2,
valueSuffix: ' kW'
},
legend: {
enabled: true,
y: 20,
itemStyle: {
color: '#ccc'
}
},
exporting: {
enabled: false
},
series: _opts.data,
time: {
useUTC: false
}
});
}
var operChart;
var has = false; // 시간 동기화 구분 값
document.addEventListener('DOMContentLoaded', function() {
// setTimeout으로 1초 뒤 차트 생성
setTimeout(function() {
init();
chartData();
has = true;
}, 1000);
// 이후 차트가 생성 되면 데이터 1초 단위로 갱신
setInterval(function() {
if (has) {
upd();
}
}, 1000);
});
// 1. 차트 생성
function init() {
var oprnOpts = {
target: 'useChart',
tickInterval: 150,
data: [{
name: '아이템1',
color: '#f7a35c',
data: []
}, {
name: '아이템2',
color: '#fdfefe',
data: []
}]
};
operChart = Graphds(oprnOpts);
}
// 2. 초기 셋팅
function chartData() {
var a = getAixArr();
var b = getAixArr();
operChart.series[0].setData(a);
operChart.series[1].setData(b);
}
// 2-1. 시간 변수
var setOprn = {
beforeT: 60000, // 1분전부터
count: 60, // 60개
interval: 1000 // 1초
}
// 2-2. 차트 초기값 데이터
function getAixArr() {
var ts = [];
var setDate = new Date();
var obj = setOprn;
var d = Date.parse(setDate) - obj.beforeT;
var t;
for (var i = 0; i < obj.count; i++) {
// 분 : 초
t = new Date(d + (i * obj.interval));
// 데이터 예시 { x : 1684193617136, y : 30 ~ 60}
ts[i] = {
x: t.getTime(),
y: Math.floor(30 + Math.random() * 30)
};
}
return ts;
}
// 3. 데이터 갱신
function upd() {
var currTime = new Date().getTime();
var data1 = Math.floor(30 + Math.random() * 30);
var data2 = Math.floor(30 + Math.random() * 30);
operChart.series[0].addPoint([currTime, data1], false, true); // false로 지정해야 부드럽게 넘어감
operChart.series[1].addPoint([currTime, data2], true, true);
}
// 차트 옵션
function Graphds(opts) {
var chart;
var _opts = opts || {};
return Highcharts.chart(_opts.target, { // _opts = { target }
chart: {
marginTop: 10,
type: 'spline',
animation: Highcharts.svg,
marginRight: 10,
backgroundColor: 'transparent'
},
title: {
text: null
},
credits: {
enabled: false
},
xAxis: {
type: 'datetime',
tickPixelInterval: _opts.tickInterval,
labels: {
format: '{value:%H:%M:%S}',
style: {
color: '#ccc'
}
}
},
yAxis: {
title: {
text: false
},
labels: {
style: {
color: '#ccc'
}
},
plotLines: [{
value: 0,
width: 1,
color: '#99ccff'
}]
},
plotOptions: {
spline: {
marker: {
enabled: false
}
}
},
tooltip: {
positioner: function() {
return {
x: 45,
y: 15
};
},
style: {
color: 'white'
},
shared: true,
crosshairs: true,
xDateFormat: '%H:%M:%S',
valueDecimals: 2,
valueSuffix: ' kW'
},
legend: {
enabled: true,
y: 20,
itemStyle: {
color: '#ccc'
}
},
exporting: {
enabled: false
},
series: _opts.data,
time: {
useUTC: false
}
});
}
...
updateChartData(newDatas, isActual) {
...
const existingSeriesIndex = this.chartSeries.findIndex(s => s.name === chartName);
if (existingSeriesIndex !== -1) {
let newData = processedData.filter(item1 => {
return !this.chartSeries[existingSeriesIndex].data.some(item2 => {
if(item1.length !== item2.length) return false;
for(let i = 0; i< item1.length; i++) {
if(item1[i] !== item2[i]) return false;
}
return true;
})
})
newData.forEach((newItem) => {
this.$refs.highcharts.chart.series.filter(obj => obj.name === chartName)[0].addPoint({
x: newItem[0],
y: newItem[1],
marker: {enabled: true, radius: 3}
}, true);
})
this.chartSeries[existingSeriesIndex].data = processedData;
} else {
this.chartSeries.push(seriesData);
this.lineOption.series = JSON.parse(JSON.stringify(this.chartSeries));
}
},
...