From 2fdf69b09ca3911f29e93e55dab4c3c8f92c321c Mon Sep 17 00:00:00 2001 From: sushuang Date: Thu, 20 Jun 2019 00:29:39 +0800 Subject: [PATCH] Support click and tooltip in bar large mode. Fix #10699 --- src/chart/bar/BarView.js | 63 +++++++++++-- src/layout/barGrid.js | 14 ++- test/bar-large.html | 190 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 245 insertions(+), 22 deletions(-) diff --git a/src/chart/bar/BarView.js b/src/chart/bar/BarView.js index 1d8eaeac65..3d9db418fe 100644 --- a/src/chart/bar/BarView.js +++ b/src/chart/bar/BarView.js @@ -25,8 +25,10 @@ import {setLabel} from './helper'; import Model from '../../model/Model'; import barItemStyle from './barItemStyle'; import Path from 'zrender/src/graphic/Path'; +import {throttle} from '../../util/throttle'; var BAR_BORDER_WIDTH_QUERY = ['itemStyle', 'barBorderWidth']; +var _eventPos = [0, 0]; // FIXME // Just for compatible with ec2. @@ -349,10 +351,10 @@ var LargePath = Path.extend({ // a whole line or drawing rects. var points = shape.points; var startPoint = this.__startPoint; - var valueIdx = this.__valueIdx; + var baseDimIdx = this.__baseDimIdx; for (var i = 0; i < points.length; i += 2) { - startPoint[this.__valueIdx] = points[i + valueIdx]; + startPoint[baseDimIdx] = points[i + baseDimIdx]; ctx.moveTo(startPoint[0], startPoint[1]); ctx.lineTo(points[i], points[i + 1]); } @@ -363,17 +365,68 @@ function createLarge(seriesModel, group, incremental) { // TODO support polar var data = seriesModel.getData(); var startPoint = []; - var valueIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0; - startPoint[1 - valueIdx] = data.getLayout('valueAxisStart'); + var baseDimIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0; + startPoint[1 - baseDimIdx] = data.getLayout('valueAxisStart'); var el = new LargePath({ shape: {points: data.getLayout('largePoints')}, incremental: !!incremental, __startPoint: startPoint, - __valueIdx: valueIdx + __baseDimIdx: baseDimIdx, + __largeDataIndices: data.getLayout('largeDataIndices'), + __barWidth: data.getLayout('barWidth') }); group.add(el); setLargeStyle(el, seriesModel, data); + + // Enable tooltip and user mouse/touch event handlers. + el.seriesIndex = seriesModel.seriesIndex; + + if (!seriesModel.get('silent')) { + el.on('mousedown', largePathUpdateDataIndex); + el.on('mousemove', largePathUpdateDataIndex); + } +} + +// Use throttle to avoid frequently traverse to find dataIndex. +var largePathUpdateDataIndex = throttle(function (event) { + var largePath = this; + var dataIndex = largePathFindDataIndex(largePath, event.offsetX, event.offsetY); + largePath.dataIndex = dataIndex >= 0 ? dataIndex : null; +}, 30, false); + +function largePathFindDataIndex(largePath, x, y) { + var baseDimIdx = largePath.__baseDimIdx; + var valueDimIdx = 1 - baseDimIdx; + var points = largePath.shape.points; + var largeDataIndices = largePath.__largeDataIndices; + var barWidthHalf = Math.abs(largePath.__barWidth / 2); + var startValueVal = largePath.__startPoint[valueDimIdx]; + + _eventPos[0] = x; + _eventPos[1] = y; + var pointerBaseVal = _eventPos[baseDimIdx]; + var pointerValueVal = _eventPos[1 - baseDimIdx]; + var baseLowerBound = pointerBaseVal - barWidthHalf; + var baseUpperBound = pointerBaseVal + barWidthHalf; + + for (var i = 0, len = points.length / 2; i < len; i++) { + var ii = i * 2; + var barBaseVal = points[ii + baseDimIdx]; + var barValueVal = points[ii + valueDimIdx]; + if ( + barBaseVal >= baseLowerBound && barBaseVal <= baseUpperBound + && ( + startValueVal <= barValueVal + ? (pointerValueVal >= startValueVal && pointerValueVal <= barValueVal) + : (pointerValueVal >= barValueVal && pointerValueVal <= startValueVal) + ) + ) { + return largeDataIndices[i]; + } + } + + return -1; } function setLargeStyle(el, seriesModel, data) { diff --git a/src/layout/barGrid.js b/src/layout/barGrid.js index a2d7976b3b..94d8333029 100644 --- a/src/layout/barGrid.js +++ b/src/layout/barGrid.js @@ -390,23 +390,29 @@ export var largeLayout = { return {progress: progress}; function progress(params, data) { - var largePoints = new LargeArr(params.count * 2); + var count = params.count; + var largePoints = new LargeArr(count * 2); + var largeDataIndices = new LargeArr(count); var dataIndex; var coord = []; var valuePair = []; - var offset = 0; + var pointsOffset = 0; + var idxOffset = 0; while ((dataIndex = params.next()) != null) { valuePair[valueDimIdx] = data.get(valueDim, dataIndex); valuePair[1 - valueDimIdx] = data.get(baseDim, dataIndex); coord = cartesian.dataToPoint(valuePair, null, coord); - largePoints[offset++] = coord[0]; - largePoints[offset++] = coord[1]; + // Data index might not be in order, depends on `progressiveChunkMode`. + largePoints[pointsOffset++] = coord[0]; + largePoints[pointsOffset++] = coord[1]; + largeDataIndices[idxOffset++] = dataIndex; } data.setLayout({ largePoints: largePoints, + largeDataIndices: largeDataIndices, barWidth: barWidth, valueAxisStart: getValueAxisStart(baseAxis, valueAxis, false), valueAxisHorizontal: valueAxisHorizontal diff --git a/test/bar-large.html b/test/bar-large.html index eeebb8e71c..c8c292dcd2 100644 --- a/test/bar-large.html +++ b/test/bar-large.html @@ -21,9 +21,13 @@ + - + + + + -
+ +
+
+
+ + + + + + + + + + + + + + + + + + \ No newline at end of file