This is an automated email from the ASF dual-hosted git repository. shenyi pushed a commit to branch feature/clip in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
commit 0b2b5e65b9d7b56a8bcac80a4d795aef8d097fa7 Author: pissang <bm2736...@gmail.com> AuthorDate: Tue Sep 17 00:10:03 2019 +0800 feat: add clip option on scatter series --- src/chart/line/LineView.js | 53 ++++------- src/chart/scatter/ScatterSeries.js | 6 +- src/chart/scatter/ScatterView.js | 11 ++- src/coord/cartesian/Cartesian2D.js | 31 +++++++ src/coord/polar/Polar.js | 33 +++++++ test/clip.html | 177 +++++++++++++++++++++++++++++++++++++ 6 files changed, 272 insertions(+), 39 deletions(-) diff --git a/src/chart/line/LineView.js b/src/chart/line/LineView.js index 501f026..725e21a 100644 --- a/src/chart/line/LineView.js +++ b/src/chart/line/LineView.js @@ -49,18 +49,6 @@ function getSmooth(smooth) { return typeof (smooth) === 'number' ? smooth : (smooth ? 0.5 : 0); } -function getAxisExtentWithGap(axis) { - var extent = axis.getGlobalExtent(); - if (axis.onBand) { - // Remove extra 1px to avoid line miter in clipped edge - var halfBandWidth = axis.getBandWidth() / 2 - 1; - var dir = extent[1] > extent[0] ? 1 : -1; - extent[0] += dir * halfBandWidth; - extent[1] -= dir * halfBandWidth; - } - return extent; -} - /** * @param {module:echarts/coord/cartesian/Cartesian2D|module:echarts/coord/polar/Polar} coordSys * @param {module:echarts/data/List} data @@ -81,14 +69,13 @@ function getStackedOnPoints(coordSys, data, dataCoordInfo) { } function createGridClipShape(cartesian, hasAnimation, forSymbol, seriesModel) { - var xExtent = getAxisExtentWithGap(cartesian.getAxis('x')); - var yExtent = getAxisExtentWithGap(cartesian.getAxis('y')); + var rect = cartesian.getArea(); var isHorizontal = cartesian.getBaseAxis().isHorizontal(); - var x = Math.min(xExtent[0], xExtent[1]); - var y = Math.min(yExtent[0], yExtent[1]); - var width = Math.max(xExtent[0], xExtent[1]) - x; - var height = Math.max(yExtent[0], yExtent[1]) - y; + var x = rect.x; + var y = rect.y; + var width = rect.width; + var height = rect.height; // Avoid float number rounding error for symbol on the edge of axis extent. // See #7913 and `test/dataZoom-clip.html`. @@ -135,38 +122,30 @@ function createGridClipShape(cartesian, hasAnimation, forSymbol, seriesModel) { } function createPolarClipShape(polar, hasAnimation, forSymbol, seriesModel) { - var angleAxis = polar.getAngleAxis(); - var radiusAxis = polar.getRadiusAxis(); - - var radiusExtent = radiusAxis.getExtent().slice(); - radiusExtent[0] > radiusExtent[1] && radiusExtent.reverse(); - var angleExtent = angleAxis.getExtent(); - - var RADIAN = Math.PI / 180; - + var sectorArea = polar.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent. if (forSymbol) { - radiusExtent[0] -= 0.5; - radiusExtent[1] += 0.5; + sectorArea.r0 -= 0.5; + sectorArea.r1 += 0.5; } var clipPath = new graphic.Sector({ shape: { cx: round(polar.cx, 1), cy: round(polar.cy, 1), - r0: round(radiusExtent[0], 1), - r: round(radiusExtent[1], 1), - startAngle: -angleExtent[0] * RADIAN, - endAngle: -angleExtent[1] * RADIAN, - clockwise: angleAxis.inverse + r0: round(sectorArea.r0, 1), + r: round(sectorArea.r1, 1), + startAngle: sectorArea.startAngle, + endAngle: sectorArea.endAngle, + clockwise: sectorArea.clockwise } }); if (hasAnimation) { - clipPath.shape.endAngle = -angleExtent[0] * RADIAN; + clipPath.shape.endAngle = sectorArea.startAngle; graphic.initProps(clipPath, { shape: { - endAngle: -angleExtent[1] * RADIAN + endAngle: sectorArea.endAngle } }, seriesModel); } @@ -446,7 +425,7 @@ export default ChartView.extend({ ) { showSymbol && symbolDraw.updateData(data, { isIgnore: isIgnoreFunc, - clipShape: createClipShape(coordSys, false, true, seriesModel) + clipShape: coordSys.getArea() }); if (step) { diff --git a/src/chart/scatter/ScatterSeries.js b/src/chart/scatter/ScatterSeries.js index c04e7d8..395f00a 100644 --- a/src/chart/scatter/ScatterSeries.js +++ b/src/chart/scatter/ScatterSeries.js @@ -87,7 +87,11 @@ export default SeriesModel.extend({ itemStyle: { opacity: 0.8 // color: 各异 - } + }, + + // If clip the overflow graphics + // Works on cartesian / polar series + clip: true // progressive: null } diff --git a/src/chart/scatter/ScatterView.js b/src/chart/scatter/ScatterView.js index 2ec0b10..6c24bf2 100644 --- a/src/chart/scatter/ScatterView.js +++ b/src/chart/scatter/ScatterView.js @@ -29,9 +29,18 @@ echarts.extendChartView({ render: function (seriesModel, ecModel, api) { var data = seriesModel.getData(); + var coordSys = seriesModel.coordinateSystem; + var clipArea = coordSys && coordSys.getArea && coordSys.getArea(); var symbolDraw = this._updateSymbolDraw(data, seriesModel); - symbolDraw.updateData(data); + + symbolDraw.updateData(data, { + // TODO + // If this parameter should be a shape or a bounding volume + // shape will be more general. + // But bounding volume like bounding rect will be much faster in the contain calculation + clipShape: seriesModel.get('clip') ? clipArea : null + }); this._finished = true; }, diff --git a/src/coord/cartesian/Cartesian2D.js b/src/coord/cartesian/Cartesian2D.js index 186b603..74eb442 100644 --- a/src/coord/cartesian/Cartesian2D.js +++ b/src/coord/cartesian/Cartesian2D.js @@ -19,8 +19,22 @@ import * as zrUtil from 'zrender/src/core/util'; +import BoundingRect from 'zrender/src/core/BoundingRect'; import Cartesian from './Cartesian'; +// A helper function to calculate extent of axis. +function getAxisExtentWithGap(axis) { + var extent = axis.getGlobalExtent(); + if (axis.onBand) { + // Remove extra 1px to avoid line miter in clipped edge + var halfBandWidth = axis.getBandWidth() / 2 - 1; + var dir = extent[1] > extent[0] ? 1 : -1; + extent[0] += dir * halfBandWidth; + extent[1] -= dir * halfBandWidth; + } + return extent; +} + function Cartesian2D(name) { Cartesian.call(this, name); @@ -130,6 +144,23 @@ Cartesian2D.prototype = { */ getOtherAxis: function (axis) { return this.getAxis(axis.dim === 'x' ? 'y' : 'x'); + }, + + /** + * Get rect area of cartesian. + * Area will have a contain function to determine if a point is in the coordinate system. + * @return {BoundingRect} + */ + getArea: function () { + var xExtent = getAxisExtentWithGap(this.getAxis('x')); + var yExtent = getAxisExtentWithGap(this.getAxis('y')); + var x = Math.min(xExtent[0], xExtent[1]); + var y = Math.min(yExtent[0], yExtent[1]); + var width = Math.max(xExtent[0], xExtent[1]) - x; + var height = Math.max(yExtent[0], yExtent[1]) - y; + + let rect = new BoundingRect(x, y, width, height); + return rect; } }; diff --git a/src/coord/polar/Polar.js b/src/coord/polar/Polar.js index e5391da..0f11e58 100644 --- a/src/coord/polar/Polar.js +++ b/src/coord/polar/Polar.js @@ -254,6 +254,39 @@ Polar.prototype = { var y = -Math.sin(radian) * radius + this.cy; return [x, y]; + }, + + /** + * Get sector area of cartesian. + * Area will have a contain function to determine if a point is in the coordinate system. + * @return {Sector} + */ + getArea: function () { + + var angleAxis = this.getAngleAxis(); + var radiusAxis = this.getRadiusAxis(); + + var radiusExtent = radiusAxis.getExtent().slice(); + radiusExtent[0] > radiusExtent[1] && radiusExtent.reverse(); + var angleExtent = angleAxis.getExtent(); + + var RADIAN = Math.PI / 180; + + var pt = [0, 0]; + return { + cx: this.cx, + cy: this.cy, + r0: radiusExtent[0], + r: radiusExtent[1], + startAngle: -angleExtent[0] * RADIAN, + endAngle: -angleExtent[1] * RADIAN, + clockwise: angleAxis.inverse, + contain: function (x, y) { + pt[0] = x; + pt[1] = y; + return this.containPoint(pt); + } + }; } }; diff --git a/test/clip.html b/test/clip.html new file mode 100644 index 0000000..062662f --- /dev/null +++ b/test/clip.html @@ -0,0 +1,177 @@ + +<!-- +Licensed to the Apache Software Foundation (ASF) under one +or more contributor license agreements. See the NOTICE file +distributed with this work for additional information +regarding copyright ownership. The ASF licenses this file +to you under the Apache License, Version 2.0 (the +"License"); you may not use this file except in compliance +with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, +software distributed under the License is distributed on an +"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, either express or implied. See the License for the +specific language governing permissions and limitations +under the License. +--> + +<html> + <head> + <meta charset="utf-8"> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <script src="./lib/esl.js"></script> + <script src="./lib/config.js"></script> + <script src="./lib/facePrint.js"></script> + <script src="lib/testHelper.js"></script> + <link rel="stylesheet" href="lib/reset.css" /> + </head> + <body> + <style> + h1 { + line-height: 60px; + height: 60px; + background: #ddd; + text-align: center; + font-weight: bold; + font-size: 14px; + } + .chart { + height: 500px; + } + </style> + + <h1>Scatter Clip on Cartesian</h1> + <div class="chart" id="scatter-clip-cartesian"></div> + <h1>Scatter Clip on Polar</h1> + <div class="chart" id="scatter-clip-polar"></div> + <h1>Large Scatter Clip</h1> + <div class="chart" id="large-scatter-clip"></div> + <h1>Scatter Clip on Cartesian with DataZoom</h1> + <div class="chart" id="scatter-clip-cartesian"></div> + <h1>Scatter Clip on Polar with DataZoom</h1> + <div class="chart" id="scatter-clip-polar"></div> + + <h1>Lines</h1> + <div class="chart" id="lines-clip"></div> + <h1>Bar</h1> + <div class="chart" id="bar-clip"></div> + + <script> + function makeToggleChartButtons(toggleClip) { + return [{ + text: 'Set Clip', + onclick: function () { + toggleClip(true); + } + }, { + text: 'Set Visible', + onclick: function () { + toggleClip(false); + } + }]; + } + </script> + + <script> + require([ + 'echarts' + ], function (echarts) { + var option = { + xAxis: {}, + yAxis: { + min: 5, + max: 10 + }, + series: [{ + symbolSize: 20, + data: [ + [10.0, 8.04], + [8.0, 6.95], + [13.0, 7.58], + [9.0, 8.81], + [11.0, 8.33], + [14.0, 9.96], + [6.0, 7.24], + [4.0, 4.26], + [12.0, 10.84], + [7.0, 4.82], + [5.0, 5.68] + ], + type: 'scatter' + }] + }; + var chart = testHelper.create(echarts, 'scatter-clip-cartesian', { + option: option, + height: 400, + buttons: makeToggleChartButtons(function (clip) { + chart.setOption({ + series: [{ + clip: clip + }] + }) + }) + }); + }) + </script> + + + + + + <script> + require([ + 'echarts' + ], function (echarts) { + var option = { + xAxis: {}, + yAxis: { + min: 5, + max: 10 + }, + series: [{ + symbolSize: 20, + data: [ + [10.0, 8.04], + [8.0, 6.95], + [13.0, 7.58], + [9.0, 8.81], + [11.0, 8.33], + [14.0, 9.96], + [6.0, 7.24], + [4.0, 4.26], + [12.0, 10.84], + [7.0, 4.82], + [5.0, 5.68] + ], + type: 'scatter' + }] + }; + var chart = testHelper.create(echarts, 'scatter-clip-cartesian', { + option: option, + height: 400, + buttons: makeToggleChartButtons(function (clip) { + chart.setOption({ + series: [{ + clip: clip + }] + }) + }) + }); + }) + </script> + + + <script> + require([ + 'echarts' + ], function (echarts) { + + // testHelper.createChart(echarts, 'zoom-shift', option); + }) + </script> + + </body> +</html> \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@echarts.apache.org For additional commands, e-mail: commits-h...@echarts.apache.org