diff --git a/docs/views/barChart/api/barChart.md b/docs/views/barChart/api/barChart.md index 7ac2115b6..a03faed02 100644 --- a/docs/views/barChart/api/barChart.md +++ b/docs/views/barChart/api/barChart.md @@ -58,7 +58,7 @@ const chartData = { data: { 'series1' : [1, 2, 3, 4], 'series2' : [5, 2, 0, 8], - 'series3' : [9, 2, 8, 2], + 'series3' : [{ value: 9, color: '#FF0000' }, 2, 8, 2], // 특정 값에 별도의 색상 지정 가능 }, labels: ['a', 'b', c', 'd'], } diff --git a/docs/views/barChart/example/Column.vue b/docs/views/barChart/example/Column.vue index 4625a0c0c..ca50819f6 100644 --- a/docs/views/barChart/example/Column.vue +++ b/docs/views/barChart/example/Column.vue @@ -21,7 +21,7 @@ 'value5', ], data: { - series1: [100, 150, 51, 150, 350], + series1: [100, 150, 51, 150, { value: 350, color: '#FF0000' }], series2: [150, 100, 151, 50, 250], }, }; diff --git a/docs/views/barChart/props.js b/docs/views/barChart/props.js index ac29e5ddf..fc688d59f 100644 --- a/docs/views/barChart/props.js +++ b/docs/views/barChart/props.js @@ -24,7 +24,7 @@ export default { parsedData: parseComponent(DefaultRaw), }, Column: { - description: '세로 형태로 사용할 수 있으며 각 Series별로 색상을 직접 지정할 수 있습니다.', + description: '세로 형태로 사용할 수 있으며 각 Series별, data별로 색상을 직접 지정할 수 있습니다.', component: Column, parsedData: parseComponent(ColumnRaw), }, diff --git a/docs/views/comboChart/example/LineBar.vue b/docs/views/comboChart/example/LineBar.vue index eb85dc5bf..4817daab5 100644 --- a/docs/views/comboChart/example/LineBar.vue +++ b/docs/views/comboChart/example/LineBar.vue @@ -5,6 +5,8 @@ :options="chartOptions" />
+ 막대 데이터값이 4500보다 큰 경우 빨간색으로 표시 +
데이터 자동 업데이트 4500) { + seriesData.push({ value: randomValue, color: '#FF0000' }); + } else { + seriesData.push(randomValue); + } }); }; diff --git a/src/components/chart/element/element.bar.js b/src/components/chart/element/element.bar.js index 7ea25a7d9..b251b1e4c 100644 --- a/src/components/chart/element/element.bar.js +++ b/src/components/chart/element/element.bar.js @@ -97,9 +97,11 @@ class Bar { let categoryPoint = null; - ctx.beginPath(); + this.data.forEach((dataItem, index) => { + ctx.beginPath(); + + const item = dataItem; - this.data.forEach((item, index) => { if (isHorizontal) { categoryPoint = ysp - (cArea * index) - cPad; } else { @@ -128,17 +130,19 @@ class Bar { h = Canvas.calculateY(item.y, minmaxY.graphMin, minmaxY.graphMax, yArea); } + const barColor = item.dataColor || this.color; const opacity = this.state === 'downplay' ? 0.1 : 1; - if (typeof this.color !== 'string') { + + if (typeof barColor !== 'string') { ctx.fillStyle = Canvas.createGradient( ctx, isHorizontal, { x, y, w, h }, - this.color, + barColor, opacity, ); } else { - ctx.fillStyle = `rgba(${Util.hexToRgb(this.color)},${opacity})` || ''; + ctx.fillStyle = `rgba(${Util.hexToRgb(barColor)},${opacity})` || ''; } this.drawBar({ @@ -190,13 +194,14 @@ class Bar { ctx.shadowOffsetY = 0; ctx.shadowBlur = 4; - if (typeof this.color !== 'string') { - const grd = Canvas.createGradient(ctx, this.isHorizontal, { x, y, w, h }, this.color); + const color = item.data.dataColor || this.color; + if (typeof color !== 'string') { + const grd = Canvas.createGradient(ctx, this.isHorizontal, { x, y, w, h }, color); ctx.fillStyle = grd; - ctx.shadowColor = this.color[this.color.length - 1][1]; + ctx.shadowColor = color[color.length - 1][1]; } else { - ctx.fillStyle = this.color; - ctx.shadowColor = this.color; + ctx.fillStyle = color; + ctx.shadowColor = color; } ctx.beginPath(); diff --git a/src/components/chart/element/element.bar.time.js b/src/components/chart/element/element.bar.time.js index fa3be4d60..c264396ea 100644 --- a/src/components/chart/element/element.bar.time.js +++ b/src/components/chart/element/element.bar.time.js @@ -59,13 +59,13 @@ class TimeBar extends Bar { this.size.bPad = bPad; this.size.w = w; this.size.ix = barSeriesX; - - ctx.beginPath(); - - const opacity = this.state === 'downplay' ? 0.1 : 1; - ctx.fillStyle = `rgba(${Util.hexToRgb(this.color)},${opacity})` || ''; + this.chartRect = chartRect; + this.labelOffset = labelOffset; + this.borderRadius = param.borderRadius; this.data.forEach((item) => { + ctx.beginPath(); + if (isHorizontal) { x = xsp; y = Canvas.calculateY(item.y, minmaxY.graphMin, minmaxY.graphMax, yArea, ysp); @@ -103,13 +103,47 @@ class TimeBar extends Bar { } if (x !== null && y !== null) { - ctx.fillRect(x, y, w !== subW ? subW : w, isHorizontal ? -h : h); + const barColor = item.dataColor || this.color; + const opacity = this.state === 'downplay' ? 0.1 : 1; + + if (typeof barColor !== 'string') { + w = w !== subW ? subW : w; + + ctx.fillStyle = Canvas.createGradient( + ctx, + isHorizontal, + { x, y, w, h }, + barColor, + opacity, + ); + } else { + ctx.fillStyle = `rgba(${Util.hexToRgb(barColor)},${opacity})` || ''; + } + + this.drawBar({ + ctx, + positions: { x, y, w, h }, + }); + + if (this.showValue.use) { + this.drawValueLabels({ + context: ctx, + data: item, + positions: { + x, + y, + h, + w, + }, + isHighlight: false, + }); + } } subW = w; item.xp = x; // eslint-disable-line item.yp = y; // eslint-disable-line - item.w = w !== subW ? subW : w; // eslint-disable-line + item.w = w; // eslint-disable-line item.h = isHorizontal ? -h : h; // eslint-disable-line }); } diff --git a/src/components/chart/model/model.store.js b/src/components/chart/model/model.store.js index 756bf9f9d..2c43e06ae 100644 --- a/src/components/chart/model/model.store.js +++ b/src/components/chart/model/model.store.js @@ -189,14 +189,14 @@ const modules = { let gdata = curr; if (bdata != null && ldata != null) { - if (gdata && typeof gdata === 'object') { + if (gdata && typeof gdata === 'object' && (curr.x || curr.y)) { odata = isHorizontal ? curr.x : curr.y; ldata = isHorizontal ? curr.y : curr.x; } if (sIdx > 0) { bdata = isHorizontal ? bdata.x : bdata.y; - gdata = bdata + odata; + gdata = bdata + (odata.value || odata); } else { bdata = 0; gdata = odata; @@ -224,7 +224,7 @@ const modules = { let gdata = curr; let ldata = label[index]; - if (gdata && typeof gdata === 'object') { + if (gdata && typeof gdata === 'object' && (curr.x || curr.y)) { gdata = isHorizontal ? curr.x : curr.y; ldata = isHorizontal ? curr.y : curr.x; } @@ -248,13 +248,22 @@ const modules = { */ addData(gdata, ldata, odata = null, bdata = null) { let data; + const gdataValue = gdata?.value || gdata; + const odataValue = odata?.value || odata; + const dataColor = gdata?.color || odata?.color; if (this.options.horizontal) { - data = { x: gdata, y: ldata, o: odata, b: bdata, xp: null, yp: null, w: null, h: null }; + data = { x: gdataValue, y: ldata, o: odataValue, b: bdata }; } else { - data = { x: ldata, y: gdata, o: odata, b: bdata, xp: null, yp: null, w: null, h: null }; + data = { x: ldata, y: gdataValue, o: odataValue, b: bdata }; } + data.xp = null; + data.yp = null; + data.w = null; + data.h = null; + data.dataColor = dataColor || null; + return data; }, @@ -271,25 +280,28 @@ const modules = { if (data.length) { return data.reduce((acc, p, index) => { const minmax = acc; - if (p.x <= minmax.minX) { - minmax.minX = (p.x === null) ? 0 : p.x; + const px = p.x?.value || p.x; + const py = p.y?.value || p.y; + + if (px <= minmax.minX) { + minmax.minX = (px === null) ? 0 : px; } - if (p.y <= minmax.minY) { - minmax.minY = (p.y === null) ? 0 : p.y; + if (py <= minmax.minY) { + minmax.minY = (py === null) ? 0 : py; } - if (p.x >= minmax.maxX) { - minmax.maxX = (p.x === null) ? 0 : p.x; + if (px >= minmax.maxX) { + minmax.maxX = (px === null) ? 0 : px; - if (isHorizontal && p.x !== null) { - minmax.maxDomain = p.y; + if (isHorizontal && px !== null) { + minmax.maxDomain = py; minmax.maxDomainIndex = index; } } - if (p.y >= minmax.maxY) { - minmax.maxY = (p.y === null) ? 0 : p.y; + if (py >= minmax.maxY) { + minmax.maxY = (py === null) ? 0 : py; - if (!isHorizontal && p.y !== null) { - minmax.maxDomain = p.x; + if (!isHorizontal && py !== null) { + minmax.maxDomain = px; minmax.maxDomainIndex = index; } } diff --git a/src/components/chart/plugins/plugins.interaction.js b/src/components/chart/plugins/plugins.interaction.js index 53020d060..c7b9e7f6b 100644 --- a/src/components/chart/plugins/plugins.interaction.js +++ b/src/components/chart/plugins/plugins.interaction.js @@ -110,6 +110,10 @@ const modules = { ({ label: args.label, value: args.value, sId: args.seriesId } = hitInfo); } + + if (typeof this.listeners.click === 'function') { + this.listeners.click(args); + } }; /**