This is an automated email from the ASF dual-hosted git repository. shenyi pushed a commit to branch line-fix-memory-explode in repository https://gitbox.apache.org/repos/asf/incubator-echarts.git
commit e9a7b95585a74f02c55c22162d476c1c94651252 Author: pissang <[email protected]> AuthorDate: Fri Apr 10 11:37:55 2020 +0800 fix(line): fix memory explosion issue with gradient, shadow and animation. #12229 --- src/chart/line/LineView.js | 39 +++++++++++ test/line-crash.html | 131 +++++++++++++++++++++++++++++++++++ test/runTest/actions/__meta__.json | 1 + test/runTest/actions/line-crash.json | 1 + 4 files changed, 172 insertions(+) diff --git a/src/chart/line/LineView.js b/src/chart/line/LineView.js index 639cbf6..ae55ffb 100644 --- a/src/chart/line/LineView.js +++ b/src/chart/line/LineView.js @@ -21,6 +21,7 @@ import {__DEV__} from '../../config'; import * as zrUtil from 'zrender/src/core/util'; +import {fromPoints} from 'zrender/src/core/bbox'; import SymbolDraw from '../helper/SymbolDraw'; import SymbolClz from '../helper/Symbol'; import lineAnimationDiff from './lineAnimationDiff'; @@ -45,6 +46,26 @@ function isPointsSame(points1, points2) { return true; } +function getBoundingDiff(points1, points2) { + var min1 = []; + var max1 = []; + + var min2 = []; + var max2 = []; + + fromPoints(points1, min1, max1); + fromPoints(points2, min2, max2); + + // Get a max value from each corner of two boundings. + return Math.max( + Math.abs(min1[0] - min2[0]), + Math.abs(min1[1] - min2[1]), + + Math.abs(max1[0] - max2[0]), + Math.abs(max1[1] - max2[1]) + ); +} + function getSmooth(smooth) { return typeof (smooth) === 'number' ? smooth : (smooth ? 0.5 : 0); } @@ -657,6 +678,24 @@ export default ChartView.extend({ next = turnPointsIntoStep(diff.next, coordSys, step); stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step); } + // Don't apply animation if diff is large. + // For better result and avoid memory explosion problems like + // https://github.com/apache/incubator-echarts/issues/12229 + if (getBoundingDiff(current, next) > 5000 + || (polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 5000) + ) { + polyline.setShape({ + points: next + }); + if (polygon) { + polygon.setShape({ + points: next, + stackedOnPoints: stackedOnNext + }); + } + return; + } + // `diff.current` is subset of `current` (which should be ensured by // turnPointsIntoStep), so points in `__points` can be updated when // points in `current` are update during animation. diff --git a/test/line-crash.html b/test/line-crash.html new file mode 100644 index 0000000..8718521 --- /dev/null +++ b/test/line-crash.html @@ -0,0 +1,131 @@ +<!DOCTYPE html> +<!-- +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/jquery.min.js"></script> + <script src="lib/facePrint.js"></script> + <script src="lib/testHelper.js"></script> + <!-- <script src="ut/lib/canteen.js"></script> --> + <link rel="stylesheet" href="lib/reset.css" /> + </head> + <body> + <style> + </style> + + + + <div id="main0"></div> + + + <script> + require(['echarts'/*, 'map/js/china' */], function (echarts) { + var FIXED_IDX = -1; + + var xAxisDataRaw = ['05:15:43', '05:15:46', '05:15:48']; + var seriesDataRaw0 = [3547546, 3903750, 1628242]; + var seriesDataRaw1 = [-167033, -2092606, -1622461]; + + var xAxisData = ['05:15:41']; + var seriesData0 = [0]; + var seriesData1 = [0]; + + var option; + // $.getJSON('./data/nutrients.json', function (data) {}); + + option = { + xAxis: [{ + data: xAxisData + }], + yAxis: {}, + series: [{ + name: 'A', + type: 'line', + areaStyle: { + color: { + type: 'linear', x: 0, y: 0, x2: 0, y2: 1, + colorStops: [{offset: 0, color: 'green'}, {offset: 1, color: 'yellow'}], + global: false + }, + shadowColor: 'green', + shadowBlur: 10 + }, + data: seriesData0 + }, { + name: 'B', + type: 'line', + areaStyle: { + color: { + type: 'linear', x: 0, y: 0, x2: 0, y2: 1, + colorStops: [{offset: 0, color: 'green'}, {offset: 1, color: 'yellow'}], + global: false + }, + shadowColor: 'green', + shadowBlur: 10 + }, + data: seriesData1 + }] + }; + + var chart = testHelper.create(echarts, 'main0', { + title: [ + 'There should be no animation and won\'t crash in safari after addData' + ], + option: option, + // height: 300, + buttons: [{ + text: 'Add Data', onclick: function () { + FIXED_IDX++; + if (FIXED_IDX >= xAxisDataRaw.length) { + return; + } + + xAxisData.push(xAxisDataRaw[FIXED_IDX]); + seriesData0.push(seriesDataRaw0[FIXED_IDX]); + seriesData1.push(seriesDataRaw1[FIXED_IDX]); + + chart.setOption({ + xAxis: { + data: xAxisData + }, + series: [{ + animationDurationUpdate: 10000, + data: seriesData0 + }, { + animationDurationUpdate: 10000, + data: seriesData1 + }] + }); + } + }], + // recordCanvas: true, + }); + }); + </script> + + + </body> +</html> + diff --git a/test/runTest/actions/__meta__.json b/test/runTest/actions/__meta__.json index 4915a31..a9a4653 100644 --- a/test/runTest/actions/__meta__.json +++ b/test/runTest/actions/__meta__.json @@ -92,6 +92,7 @@ "legend-visualMapColor": 2, "line": 1, "line-animation": 1, + "line-crash": 1, "map": 3, "map-contour": 2, "map-default": 1, diff --git a/test/runTest/actions/line-crash.json b/test/runTest/actions/line-crash.json new file mode 100644 index 0000000..ae59ed7 --- /dev/null +++ b/test/runTest/actions/line-crash.json @@ -0,0 +1 @@ +[{"name":"Action 1","ops":[{"type":"mousedown","time":319,"x":43,"y":77},{"type":"mouseup","time":419,"x":43,"y":77},{"time":420,"delay":400,"type":"screenshot-auto"}],"scrollY":0,"scrollX":0,"timestamp":1586489537278}] \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
