diff --git a/src/chart/bar/BarSeries.js b/src/chart/bar/BarSeries.js index 0f34f9c6c4f188d5b5b9f4f88ed28a737ed02620..9535a8a7c7a0f8d6fe90919e12d07bd9fd958652 100644 --- a/src/chart/bar/BarSeries.js +++ b/src/chart/bar/BarSeries.js @@ -57,6 +57,20 @@ export default BaseBarSeries.extend({ // If use caps on two sides of bars // Only available on tangential polar bar - roundCap: false + roundCap: false, + + showBackground: false, + backgroundStyle: { + color: 'rgba(180, 180, 180, 0.2)', + borderColor: null, + borderWidth: 0, + borderType: 'solid', + borderRadius: 0, + shadowBlur: 0, + shadowColor: null, + shadowOffsetX: 0, + shadowOffsetY: 0, + opacity: 1 + } } }); diff --git a/src/chart/bar/BarView.js b/src/chart/bar/BarView.js index c9d0d047ba5e5fcc17b747bfe224e6355c24ef32..18c5e2ac70748b653eecb05b055b845220acb69d 100644 --- a/src/chart/bar/BarView.js +++ b/src/chart/bar/BarView.js @@ -25,6 +25,7 @@ import {setLabel} from './helper'; import Model from '../../model/Model'; import barItemStyle from './barItemStyle'; import Path from 'zrender/src/graphic/Path'; +import Group from 'zrender/src/container/Group'; import {throttle} from '../../util/throttle'; import {createClipPath} from '../helper/createClipPathFromCoordSys'; import Sausage from '../../util/shape/sausage'; @@ -127,15 +128,27 @@ export default echarts.extendChartView({ var roundCap = seriesModel.get('roundCap', true); + var drawBackground = seriesModel.get('showBackground', true); + var backgroundModel = seriesModel.getModel('backgroundStyle'); + + var bgEls = []; + var oldBgEls = this._backgroundEls || []; + data.diff(oldData) .add(function (dataIndex) { + var itemModel = data.getItemModel(dataIndex); + var layout = getLayout[coord.type](data, dataIndex, itemModel); + + if (drawBackground) { + var bgEl = createBackgroundEl(coord, isHorizontalOrRadial, layout); + bgEl.useStyle(backgroundModel.getBarItemStyle()); + bgEls[dataIndex] = bgEl; + } + if (!data.hasValue(dataIndex)) { return; } - var itemModel = data.getItemModel(dataIndex); - var layout = getLayout[coord.type](data, dataIndex, itemModel); - if (needsClip) { // Clip will modify the layout params. // And return a boolean to determine if the shape are fully clipped. @@ -158,16 +171,24 @@ export default echarts.extendChartView({ ); }) .update(function (newIndex, oldIndex) { - var el = oldData.getItemGraphicEl(oldIndex); + var itemModel = data.getItemModel(newIndex); + var layout = getLayout[coord.type](data, newIndex, itemModel); + if (drawBackground) { + var bgEl = oldBgEls[oldIndex]; + bgEl.useStyle(backgroundModel.getBarItemStyle()); + bgEls[newIndex] = bgEl; + + var shape = createBackgroundShape(isHorizontalOrRadial, layout, coord); + graphic.updateProps(bgEl, { shape: shape }, animationModel, newIndex); + } + + var el = oldData.getItemGraphicEl(oldIndex); if (!data.hasValue(newIndex)) { group.remove(el); return; } - var itemModel = data.getItemModel(newIndex); - var layout = getLayout[coord.type](data, newIndex, itemModel); - if (needsClip) { var isClipped = clip[coord.type](coordSysClipArea, layout); if (isClipped) { @@ -205,6 +226,15 @@ export default echarts.extendChartView({ }) .execute(); + var bgGroup = this._backgroundGroup || (this._backgroundGroup = new Group()); + bgGroup.removeAll(); + + for (var i = 0; i < bgEls.length; ++i) { + bgGroup.add(bgEls[i]); + } + group.add(bgGroup); + this._backgroundEls = bgEls; + this._data = data; }, @@ -225,6 +255,7 @@ export default echarts.extendChartView({ }, _incrementalRenderLarge: function (params, seriesModel) { + this._removeBackground(); createLarge(seriesModel, this.group, true); }, @@ -238,6 +269,9 @@ export default echarts.extendChartView({ var group = this.group; var data = this._data; if (ecModel && ecModel.get('animation') && data && !this._isLargeDraw) { + this._removeBackground(); + this._backgroundEls = []; + data.eachItemGraphicEl(function (el) { if (el.type === 'sector') { removeSector(el.dataIndex, ecModel, el); @@ -251,6 +285,11 @@ export default echarts.extendChartView({ group.removeAll(); } this._data = null; + }, + + _removeBackground: function () { + this.group.remove(this._backgroundGroup); + this._backgroundGroup = null; } }); @@ -308,7 +347,12 @@ var elementCreator = { dataIndex, layout, isHorizontal, animationModel, isUpdate ) { - var rect = new graphic.Rect({shape: zrUtil.extend({}, layout)}); + var rect = new graphic.Rect({ + shape: zrUtil.extend({}, layout), + z2: 1 + }); + + rect.name = 'item'; // Animation if (animationModel) { @@ -338,9 +382,12 @@ var elementCreator = { var ShapeClass = (!isRadial && roundCap) ? Sausage : graphic.Sector; var sector = new ShapeClass({ - shape: zrUtil.defaults({clockwise: clockwise}, layout) + shape: zrUtil.defaults({clockwise: clockwise}, layout), + z2: 1 }); + sector.name = 'item'; + // Animation if (animationModel) { var sectorShape = sector.shape; @@ -460,7 +507,10 @@ function updateStyle( // In case width or height are too small. function getLineWidth(itemModel, rawLayout) { var lineWidth = itemModel.get(BAR_BORDER_WIDTH_QUERY) || 0; - return Math.min(lineWidth, Math.abs(rawLayout.width), Math.abs(rawLayout.height)); + // width or height may be NaN for empty data + var width = isNaN(rawLayout.width) ? Number.MAX_VALUE : Math.abs(rawLayout.width); + var height = isNaN(rawLayout.height) ? Number.MAX_VALUE : Math.abs(rawLayout.height); + return Math.min(lineWidth, width, height); } @@ -492,13 +542,38 @@ function createLarge(seriesModel, group, incremental) { var baseDimIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0; startPoint[1 - baseDimIdx] = data.getLayout('valueAxisStart'); + var largeDataIndices = data.getLayout('largeDataIndices'); + var barWidth = data.getLayout('barWidth'); + + var backgroundModel = seriesModel.getModel('backgroundStyle'); + var drawBackground = seriesModel.get('showBackground', true); + + if (drawBackground) { + var points = data.getLayout('largeBackgroundPoints'); + var backgroundStartPoint = []; + backgroundStartPoint[1 - baseDimIdx] = data.getLayout('backgroundStart'); + + var bgEl = new LargePath({ + shape: {points: points}, + incremental: !!incremental, + __startPoint: backgroundStartPoint, + __baseDimIdx: baseDimIdx, + __largeDataIndices: largeDataIndices, + __barWidth: barWidth, + silent: true, + z2: 0 + }); + setLargeBackgroundStyle(bgEl, backgroundModel, data); + group.add(bgEl); + } + var el = new LargePath({ shape: {points: data.getLayout('largePoints')}, incremental: !!incremental, __startPoint: startPoint, __baseDimIdx: baseDimIdx, - __largeDataIndices: data.getLayout('largeDataIndices'), - __barWidth: data.getLayout('barWidth') + __largeDataIndices: largeDataIndices, + __barWidth: barWidth }); group.add(el); setLargeStyle(el, seriesModel, data); @@ -563,3 +638,51 @@ function setLargeStyle(el, seriesModel, data) { el.style.lineWidth = data.getLayout('barWidth'); } +function setLargeBackgroundStyle(el, backgroundModel, data) { + var borderColor = backgroundModel.get('borderColor') || backgroundModel.get('color'); + var itemStyle = backgroundModel.getItemStyle(['color', 'borderColor']); + + el.useStyle(itemStyle); + el.style.fill = null; + el.style.stroke = borderColor; + el.style.lineWidth = data.getLayout('barWidth'); +} + +function createBackgroundShape(isHorizontalOrRadial, layout, coord) { + var coordLayout; + var isPolar = coord.type === 'polar'; + if (isPolar) { + coordLayout = coord.getArea(); + } + else { + coordLayout = coord.grid.getRect(); + } + + if (isPolar) { + return { + cx: coordLayout.cx, + cy: coordLayout.cy, + r0: isHorizontalOrRadial ? coordLayout.r0 : layout.r0, + r: isHorizontalOrRadial ? coordLayout.r : layout.r, + startAngle: isHorizontalOrRadial ? layout.startAngle : 0, + endAngle: isHorizontalOrRadial ? layout.endAngle : Math.PI * 2 + }; + } + else { + return { + x: isHorizontalOrRadial ? layout.x : coordLayout.x, + y: isHorizontalOrRadial ? coordLayout.y : layout.y, + width: isHorizontalOrRadial ? layout.width : coordLayout.width, + height: isHorizontalOrRadial ? coordLayout.height : layout.height + }; + } +} + +function createBackgroundEl(coord, isHorizontalOrRadial, layout) { + var ElementClz = coord.type === 'polar' ? graphic.Sector : graphic.Rect; + return new ElementClz({ + shape: createBackgroundShape(isHorizontalOrRadial, layout, coord), + silent: true, + z2: 0 + }); +} diff --git a/src/layout/barGrid.js b/src/layout/barGrid.js index 889e4a8afd199e2579d095970152afa23202cb22..e7947eb556bcd60603c529069ddd9a05fed0481c 100644 --- a/src/layout/barGrid.js +++ b/src/layout/barGrid.js @@ -420,11 +420,6 @@ export function layout(seriesType, ecModel) { var value = data.get(valueDim, idx); var baseValue = data.get(baseDim, idx); - // If dataZoom in filteMode: 'empty', the baseValue can be set as NaN in "axisProxy". - if (isNaN(value) || isNaN(baseValue)) { - continue; - } - var sign = value >= 0 ? 'p' : 'n'; var baseCoord = valueAxisStart; @@ -498,6 +493,7 @@ export var largeLayout = { var data = seriesModel.getData(); var cartesian = seriesModel.coordinateSystem; + var coordLayout = cartesian.grid.getRect(); var baseAxis = cartesian.getBaseAxis(); var valueAxis = cartesian.getOtherAxis(baseAxis); var valueDim = data.mapDimension(valueAxis.dim); @@ -517,6 +513,7 @@ export var largeLayout = { function progress(params, data) { var count = params.count; var largePoints = new LargeArr(count * 2); + var largeBackgroundPoints = new LargeArr(count * 2); var largeDataIndices = new LargeArr(count); var dataIndex; var coord = []; @@ -530,7 +527,9 @@ export var largeLayout = { coord = cartesian.dataToPoint(valuePair, null, coord); // Data index might not be in order, depends on `progressiveChunkMode`. + largeBackgroundPoints[pointsOffset] = valueAxisHorizontal ? coordLayout.x + coordLayout.width : coord[0]; largePoints[pointsOffset++] = coord[0]; + largeBackgroundPoints[pointsOffset] = valueAxisHorizontal ? coord[1] : coordLayout.y + coordLayout.height; largePoints[pointsOffset++] = coord[1]; largeDataIndices[idxOffset++] = dataIndex; } @@ -538,8 +537,10 @@ export var largeLayout = { data.setLayout({ largePoints: largePoints, largeDataIndices: largeDataIndices, + largeBackgroundPoints: largeBackgroundPoints, barWidth: barWidth, valueAxisStart: getValueAxisStart(baseAxis, valueAxis, false), + backgroundStart: valueAxisHorizontal ? coordLayout.x : coordLayout.y, valueAxisHorizontal: valueAxisHorizontal }); } diff --git a/src/layout/barPolar.js b/src/layout/barPolar.js index bb9c981c2b28b426223f6ee149a62300b606d5eb..2aebd930b048bdd660e307acefc2566ea8d7b80f 100644 --- a/src/layout/barPolar.js +++ b/src/layout/barPolar.js @@ -88,10 +88,6 @@ function barLayoutPolar(seriesType, ecModel, api) { var value = data.get(valueDim, idx); var baseValue = data.get(baseDim, idx); - if (isNaN(value)) { - continue; - } - var sign = value >= 0 ? 'p' : 'n'; var baseCoord = valueAxisStart; diff --git a/test/bar-background.html b/test/bar-background.html new file mode 100644 index 0000000000000000000000000000000000000000..49e582b8ebeee161420b10548d34e5db30b0a218 --- /dev/null +++ b/test/bar-background.html @@ -0,0 +1,511 @@ + + + + + + + + + + + + + + + + + +
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/bar-polar-basic-radial.html b/test/bar-polar-basic-radial.html index da70fa3b1a837d8d75d13325942fa0046ef67a37..e497c8c18b459ce84f2a0faf5d8cebe6309f090d 100644 --- a/test/bar-polar-basic-radial.html +++ b/test/bar-polar-basic-radial.html @@ -63,7 +63,7 @@ under the License. }, series: [{ type: 'bar', - data: [1, 2, 4, 3, 0, 5, 7], + data: [1, 2, '-', 3, 0, 5, 7], coordinateSystem: 'polar', barMaxWidth: '50%', barMinHeight: 10