Skip to content

Commit

Permalink
[#823] [3.0] Stack차트 데이터 null대응 (#830)
Browse files Browse the repository at this point in the history
* [#823] [3.0] Stack Chart 데이터 배열 속 null 값 예외처리
- data 배열 속 null이 존재 할 경우 canvas의 lineTo 메소드에 null값이 그대로 들어가 이상현상 발생하여 0으로 치환하는 로직 넣음
-  Tooltip에서 StackChart의 경우 original데이터를 참조하는데 첫번째 시리즈만 original데이터를 넘기지 않아 추가함

* [#823] [3.0] Stack Chart 데이터 배열 속 null 값 예외처리
- stack 차트만 데이터 null에 대해서 0으로 치환하는 로직 수행하도록 수정
- Stack에서 값이 null인 series는 tooltip에 표시되지 않도록 수정

* [#823] [3.0] Stack Chart 데이터 배열 속 null 값 예외처리
### line chart
- Fill을 채우는 로직이 2번 수행되는 현상 제거
- 데이터가 null값일 경우 Fill을 정상적으로 수행하지 않는 로직 개선
- Stack 예제 코드 수정
### 공통
- Stack Series의 y포지션을 계산하는 로직에서 바로 직전 series만 참조하는 로직 개선
- label타입이 'step'일 경우 null을 처리 하니 못하는 현상 제거

Co-authored-by: jinhee park <jinhee@ex-em.com>
  • Loading branch information
jhee564 and jhee564 authored Jun 15, 2021
1 parent 1b25261 commit 76f4254
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 38 deletions.
8 changes: 4 additions & 4 deletions docs/views/barChart/example/Stack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
],
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
data: {
series1: [100, 150, 51, 40, 50],
series2: [110, 100, 151, 50, 250],
series3: [200, 40, 50, 100, 250],
series4: [80, 100, 151, 150, 250],
series1: [null, 150, 51, 40, 50],
series2: [110, null, 151, 50, 250],
series3: [200, 40, null, 100, 250],
series4: [80, 100, 151, null, 250],
},
};
Expand Down
30 changes: 22 additions & 8 deletions docs/views/lineChart/example/Stack.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,12 @@
const time = dayjs().format('YYYY-MM-DD HH:mm:ss');
const chartData = {
series: {
series1: { name: 'series#1', fill: true, point: false },
series2: { name: 'series#2', fill: true, point: false },
series1: { name: 'series#1', fill: true, point: true },
series2: { name: 'series#2', fill: true, point: true },
series3: { name: 'series#3', fill: true, point: true },
},
groups: [
['series1', 'series2'],
['series1', 'series2', 'series3'],
],
labels: [
dayjs(time),
Expand All @@ -29,8 +30,9 @@
dayjs(time).add(6, 'day'),
],
data: {
series1: [100, 25, 36, 47, 0, 50, 80],
series2: [80, 36, 25, 47, 15, 100, 0],
series1: [100, 25, 47, 47, 40, 50, 100],
series2: [100, 25, 47, 47, null, null, null],
series3: [100, 50, 50, 50, null, 50, 100],
},
};
Expand All @@ -45,18 +47,30 @@
show: true,
position: 'right',
},
tooltip: {
use: true,
},
axesX: [{
type: 'time',
showGrid: true,
categoryMode: true,
showGrid: false,
timeFormat: 'MM/DD',
interval: 'day',
labelStyle: {
color: '#A4A4A4',
fontSize: '11px',
fontFamily: 'Roboto',
},
}],
axesY: [{
type: 'linear',
showGrid: false,
showGrid: true,
startToZero: true,
autoScaleRatio: 0.1,
labelStyle: {
color: '#A4A4A4',
fontSize: '11px',
fontFamily: 'Roboto',
},
}],
};
Expand Down
35 changes: 27 additions & 8 deletions src/components/chart/element/element.line.js
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,21 @@ class Line {
const xsp = chartRect.x1 + labelOffset.left + (barAreaByCombo / 2);
const ysp = chartRect.y2 - labelOffset.bottom;

const getXPos = val => Canvas.calculateX(val, minmaxX.graphMin, minmaxX.graphMax, xArea, xsp);
const getYPos = val => Canvas.calculateY(val, minmaxY.graphMin, minmaxY.graphMax, yArea, ysp);

this.data.reduce((prev, curr, ix, item) => {
x = Canvas.calculateX(curr.x, minmaxX.graphMin, minmaxX.graphMax, xArea, xsp);
y = Canvas.calculateY(curr.y, minmaxY.graphMin, minmaxY.graphMax, yArea, ysp);
x = getXPos(curr.x);
y = getYPos(curr.y);

if (x !== null) {
x += Util.aliasPixel(x);
}

if (y === null || x === null) {
if (ix - 1 > -1) {
if (this.fill && prev.y !== null) {
// draw fill(area) series not stacked
if (this.fill && prev.y !== null && !this.stackIndex) {
ctx.stroke();
ctx.lineTo(prev.xp, endPoint);
ctx.lineTo(item[startFillIndex].xp, endPoint);
Expand Down Expand Up @@ -132,12 +136,27 @@ class Line {

if (this.fill && dataLen) {
ctx.fillStyle = Util.colorStringToRgba(mainColor, fillOpacity);
if (this.stackIndex) {
this.data.slice().reverse().forEach((curr) => {
x = Canvas.calculateX(curr.x, minmaxX.graphMin, minmaxX.graphMax, xArea, xsp);
y = Canvas.calculateY(curr.b, minmaxY.graphMin, minmaxY.graphMax, yArea, ysp);

ctx.lineTo(x, y);
if (this.stackIndex) {
const reversedDataList = this.data.slice().reverse();
reversedDataList.forEach((curr, ix) => {
x = getXPos(curr.x);
y = getYPos(curr.b);

const prev = reversedDataList[ix - 1];
if (curr.o !== null) {
if (prev && prev.o == null) {
ctx.moveTo(x, getYPos(curr.b + curr.o));
}

ctx.lineTo(x, y);

if (ix === reversedDataList.length - 1) {
ctx.lineTo(x, getYPos(curr.b + curr.o));
}
} else if (prev && prev.o) {
ctx.lineTo(getXPos(prev.x), getYPos(prev.b + prev.o));
}
});
} else if (startFillIndex < dataLen) {
ctx.lineTo(this.data[dataLen - 1].xp, endPoint);
Expand Down
4 changes: 2 additions & 2 deletions src/components/chart/helpers/helpers.util.js
Original file line number Diff line number Diff line change
Expand Up @@ -213,11 +213,11 @@ export default {
};

array.forEach((item) => {
if (minMax.max.length < item.length) {
if (minMax?.max?.length < item?.length) {
minMax.max = item;
}

if (minMax.min.length > item.length) {
if (minMax?.min?.length > item?.length) {
minMax.min = item;
}
});
Expand Down
1 change: 1 addition & 0 deletions src/components/chart/model/model.series.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ const modules = {
series.groupIndex = gIdx;
series.isExistGrp = true;
series.bsId = prev;
series.bsIds = group.filter((item, idx) => item !== curr && sIdx > idx);

if (!series.show) {
interpolation--;
Expand Down
52 changes: 38 additions & 14 deletions src/components/chart/model/model.store.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ const modules = {
} else {
type.forEach((sId) => {
const series = this.seriesList[sId];
const sData = data[sId];

if (series && data[sId]) {
if (series && sData) {
if (series.isExistGrp && series.stackIndex) {
const bs = this.seriesList[series.bsId];
series.data = this.addSeriesStackDS(data[sId], label, bs.data, series.stackIndex);
series.data = this.addSeriesStackDS(sData, label, series.bsIds, series.stackIndex);
} else {
series.data = this.addSeriesDS(data[sId], label);
series.data = this.addSeriesDS(sData, label);
}
series.minMax = this.getSeriesMinMax(series.data);
}
Expand Down Expand Up @@ -173,33 +173,57 @@ const modules = {
* Take data and label to create stack data for each series
* @param {object} data chart series info
* @param {object} label chart label
* @param {array} base stacked base data
* @param {array} bsIds stacked base data ID List
* @param {number} sIdx series ordered index
*
* @returns {array} data for each series
*/
addSeriesStackDS(data, label, base, sIdx = 0) {
addSeriesStackDS(data, label, bsIds, sIdx = 0) {
const isHorizontal = this.options.horizontal;
const sdata = [];

const getBaseDataPosition = (baseIndex, dataIndex) => {
const nextBaseSeriesIndex = baseIndex - 1;
const baseSeries = this.seriesList[bsIds[baseIndex]];
const baseDataList = baseSeries.data;
const baseData = baseDataList[dataIndex];
const position = isHorizontal ? baseData?.x : baseData?.y;

if (position == null || !baseSeries.show) {
if (nextBaseSeriesIndex > -1) {
return getBaseDataPosition(nextBaseSeriesIndex, dataIndex);
}

return 0;
}

return position;
};

data.forEach((curr, index) => {
let bdata = base[index];
let odata = curr;
let ldata = label[index];
let gdata = curr;
const baseIndex = bsIds.length - 1 < 0 ? 0 : bsIds.length - 1;
let bdata = getBaseDataPosition(baseIndex, index); // base(previous) series data
let odata = curr; // current series original data
let ldata = label[index]; // label data
let gdata = curr; // current series data which added previous series's value

if (bdata != null && ldata != null) {
if (gdata && typeof gdata === 'object' && (curr.x || curr.y)) {
odata = isHorizontal ? curr.x : curr.y;
ldata = isHorizontal ? curr.y : curr.x;
}

const oData = odata?.value ?? odata;
if (sIdx > 0) {
bdata = isHorizontal ? bdata.x : bdata.y;
gdata = bdata + (odata?.value ?? odata);
if (oData != null) {
gdata = bdata + oData;
} else {
gdata = null;
bdata = 0;
}
} else {
bdata = 0;
gdata = odata;
gdata = oData;
}

sdata.push(this.addData(gdata, ldata, odata, bdata));
Expand Down Expand Up @@ -230,7 +254,7 @@ const modules = {
}

if (ldata !== null) {
sdata.push(this.addData(gdata, ldata));
sdata.push(this.addData(gdata, ldata, gdata));
}
});

Expand Down
6 changes: 4 additions & 2 deletions src/components/chart/plugins/plugins.interaction.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,9 +309,11 @@ const modules = {
let gdata;

if (item.data.o === null) {
gdata = isHorizontal ? item.data.x : item.data.y;
if (!series.isExistGrp) {
gdata = isHorizontal ? item.data.x : item.data.y;
}
} else if (!isNaN(item.data.o)) {
gdata = isHorizontal ? item.data.x : item.data.y;
gdata = item.data.o;
}

if (gdata !== null && gdata !== undefined) {
Expand Down

0 comments on commit 76f4254

Please sign in to comment.