LineView.js 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing,
  13. * software distributed under the License is distributed on an
  14. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  15. * KIND, either express or implied. See the License for the
  16. * specific language governing permissions and limitations
  17. * under the License.
  18. */
  19. var _config = require("../../config");
  20. var __DEV__ = _config.__DEV__;
  21. var zrUtil = require("zrender/lib/core/util");
  22. var SymbolDraw = require("../helper/SymbolDraw");
  23. var SymbolClz = require("../helper/Symbol");
  24. var lineAnimationDiff = require("./lineAnimationDiff");
  25. var graphic = require("../../util/graphic");
  26. var modelUtil = require("../../util/model");
  27. var _poly = require("./poly");
  28. var Polyline = _poly.Polyline;
  29. var Polygon = _poly.Polygon;
  30. var ChartView = require("../../view/Chart");
  31. var _helper = require("./helper");
  32. var prepareDataCoordInfo = _helper.prepareDataCoordInfo;
  33. var getStackedOnPoint = _helper.getStackedOnPoint;
  34. var _createClipPathFromCoordSys = require("../helper/createClipPathFromCoordSys");
  35. var createGridClipPath = _createClipPathFromCoordSys.createGridClipPath;
  36. var createPolarClipPath = _createClipPathFromCoordSys.createPolarClipPath;
  37. /*
  38. * Licensed to the Apache Software Foundation (ASF) under one
  39. * or more contributor license agreements. See the NOTICE file
  40. * distributed with this work for additional information
  41. * regarding copyright ownership. The ASF licenses this file
  42. * to you under the Apache License, Version 2.0 (the
  43. * "License"); you may not use this file except in compliance
  44. * with the License. You may obtain a copy of the License at
  45. *
  46. * http://www.apache.org/licenses/LICENSE-2.0
  47. *
  48. * Unless required by applicable law or agreed to in writing,
  49. * software distributed under the License is distributed on an
  50. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  51. * KIND, either express or implied. See the License for the
  52. * specific language governing permissions and limitations
  53. * under the License.
  54. */
  55. // FIXME step not support polar
  56. function isPointsSame(points1, points2) {
  57. if (points1.length !== points2.length) {
  58. return;
  59. }
  60. for (var i = 0; i < points1.length; i++) {
  61. var p1 = points1[i];
  62. var p2 = points2[i];
  63. if (p1[0] !== p2[0] || p1[1] !== p2[1]) {
  64. return;
  65. }
  66. }
  67. return true;
  68. }
  69. function getSmooth(smooth) {
  70. return typeof smooth === 'number' ? smooth : smooth ? 0.5 : 0;
  71. }
  72. /**
  73. * @param {module:echarts/coord/cartesian/Cartesian2D|module:echarts/coord/polar/Polar} coordSys
  74. * @param {module:echarts/data/List} data
  75. * @param {Object} dataCoordInfo
  76. * @param {Array.<Array.<number>>} points
  77. */
  78. function getStackedOnPoints(coordSys, data, dataCoordInfo) {
  79. if (!dataCoordInfo.valueDim) {
  80. return [];
  81. }
  82. var points = [];
  83. for (var idx = 0, len = data.count(); idx < len; idx++) {
  84. points.push(getStackedOnPoint(dataCoordInfo, coordSys, data, idx));
  85. }
  86. return points;
  87. }
  88. function turnPointsIntoStep(points, coordSys, stepTurnAt) {
  89. var baseAxis = coordSys.getBaseAxis();
  90. var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;
  91. var stepPoints = [];
  92. for (var i = 0; i < points.length - 1; i++) {
  93. var nextPt = points[i + 1];
  94. var pt = points[i];
  95. stepPoints.push(pt);
  96. var stepPt = [];
  97. switch (stepTurnAt) {
  98. case 'end':
  99. stepPt[baseIndex] = nextPt[baseIndex];
  100. stepPt[1 - baseIndex] = pt[1 - baseIndex]; // default is start
  101. stepPoints.push(stepPt);
  102. break;
  103. case 'middle':
  104. // default is start
  105. var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
  106. var stepPt2 = [];
  107. stepPt[baseIndex] = stepPt2[baseIndex] = middle;
  108. stepPt[1 - baseIndex] = pt[1 - baseIndex];
  109. stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
  110. stepPoints.push(stepPt);
  111. stepPoints.push(stepPt2);
  112. break;
  113. default:
  114. stepPt[baseIndex] = pt[baseIndex];
  115. stepPt[1 - baseIndex] = nextPt[1 - baseIndex]; // default is start
  116. stepPoints.push(stepPt);
  117. }
  118. } // Last points
  119. points[i] && stepPoints.push(points[i]);
  120. return stepPoints;
  121. }
  122. function getVisualGradient(data, coordSys) {
  123. var visualMetaList = data.getVisual('visualMeta');
  124. if (!visualMetaList || !visualMetaList.length || !data.count()) {
  125. // When data.count() is 0, gradient range can not be calculated.
  126. return;
  127. }
  128. if (coordSys.type !== 'cartesian2d') {
  129. return;
  130. }
  131. var coordDim;
  132. var visualMeta;
  133. for (var i = visualMetaList.length - 1; i >= 0; i--) {
  134. var dimIndex = visualMetaList[i].dimension;
  135. var dimName = data.dimensions[dimIndex];
  136. var dimInfo = data.getDimensionInfo(dimName);
  137. coordDim = dimInfo && dimInfo.coordDim; // Can only be x or y
  138. if (coordDim === 'x' || coordDim === 'y') {
  139. visualMeta = visualMetaList[i];
  140. break;
  141. }
  142. }
  143. if (!visualMeta) {
  144. return;
  145. } // If the area to be rendered is bigger than area defined by LinearGradient,
  146. // the canvas spec prescribes that the color of the first stop and the last
  147. // stop should be used. But if two stops are added at offset 0, in effect
  148. // browsers use the color of the second stop to render area outside
  149. // LinearGradient. So we can only infinitesimally extend area defined in
  150. // LinearGradient to render `outerColors`.
  151. var axis = coordSys.getAxis(coordDim); // dataToCoor mapping may not be linear, but must be monotonic.
  152. var colorStops = zrUtil.map(visualMeta.stops, function (stop) {
  153. return {
  154. coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
  155. color: stop.color
  156. };
  157. });
  158. var stopLen = colorStops.length;
  159. var outerColors = visualMeta.outerColors.slice();
  160. if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
  161. colorStops.reverse();
  162. outerColors.reverse();
  163. }
  164. var tinyExtent = 10; // Arbitrary value: 10px
  165. var minCoord = colorStops[0].coord - tinyExtent;
  166. var maxCoord = colorStops[stopLen - 1].coord + tinyExtent;
  167. var coordSpan = maxCoord - minCoord;
  168. if (coordSpan < 1e-3) {
  169. return 'transparent';
  170. }
  171. zrUtil.each(colorStops, function (stop) {
  172. stop.offset = (stop.coord - minCoord) / coordSpan;
  173. });
  174. colorStops.push({
  175. offset: stopLen ? colorStops[stopLen - 1].offset : 0.5,
  176. color: outerColors[1] || 'transparent'
  177. });
  178. colorStops.unshift({
  179. // notice colorStops.length have been changed.
  180. offset: stopLen ? colorStops[0].offset : 0.5,
  181. color: outerColors[0] || 'transparent'
  182. }); // zrUtil.each(colorStops, function (colorStop) {
  183. // // Make sure each offset has rounded px to avoid not sharp edge
  184. // colorStop.offset = (Math.round(colorStop.offset * (end - start) + start) - start) / (end - start);
  185. // });
  186. var gradient = new graphic.LinearGradient(0, 0, 0, 0, colorStops, true);
  187. gradient[coordDim] = minCoord;
  188. gradient[coordDim + '2'] = maxCoord;
  189. return gradient;
  190. }
  191. function getIsIgnoreFunc(seriesModel, data, coordSys) {
  192. var showAllSymbol = seriesModel.get('showAllSymbol');
  193. var isAuto = showAllSymbol === 'auto';
  194. if (showAllSymbol && !isAuto) {
  195. return;
  196. }
  197. var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
  198. if (!categoryAxis) {
  199. return;
  200. } // Note that category label interval strategy might bring some weird effect
  201. // in some scenario: users may wonder why some of the symbols are not
  202. // displayed. So we show all symbols as possible as we can.
  203. if (isAuto // Simplify the logic, do not determine label overlap here.
  204. && canShowAllSymbolForCategory(categoryAxis, data)) {
  205. return;
  206. } // Otherwise follow the label interval strategy on category axis.
  207. var categoryDataDim = data.mapDimension(categoryAxis.dim);
  208. var labelMap = {};
  209. zrUtil.each(categoryAxis.getViewLabels(), function (labelItem) {
  210. labelMap[labelItem.tickValue] = 1;
  211. });
  212. return function (dataIndex) {
  213. return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
  214. };
  215. }
  216. function canShowAllSymbolForCategory(categoryAxis, data) {
  217. // In mose cases, line is monotonous on category axis, and the label size
  218. // is close with each other. So we check the symbol size and some of the
  219. // label size alone with the category axis to estimate whether all symbol
  220. // can be shown without overlap.
  221. var axisExtent = categoryAxis.getExtent();
  222. var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count();
  223. isNaN(availSize) && (availSize = 0); // 0/0 is NaN.
  224. // Sampling some points, max 5.
  225. var dataLen = data.count();
  226. var step = Math.max(1, Math.round(dataLen / 5));
  227. for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
  228. if (SymbolClz.getSymbolSize(data, dataIndex // Only for cartesian, where `isHorizontal` exists.
  229. )[categoryAxis.isHorizontal() ? 1 : 0] // Empirical number
  230. * 1.5 > availSize) {
  231. return false;
  232. }
  233. }
  234. return true;
  235. }
  236. function createLineClipPath(coordSys, hasAnimation, seriesModel) {
  237. if (coordSys.type === 'cartesian2d') {
  238. var isHorizontal = coordSys.getBaseAxis().isHorizontal();
  239. var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel); // Expand clip shape to avoid clipping when line value exceeds axis
  240. if (!seriesModel.get('clip', true)) {
  241. var rectShape = clipPath.shape;
  242. var expandSize = Math.max(rectShape.width, rectShape.height);
  243. if (isHorizontal) {
  244. rectShape.y -= expandSize;
  245. rectShape.height += expandSize * 2;
  246. } else {
  247. rectShape.x -= expandSize;
  248. rectShape.width += expandSize * 2;
  249. }
  250. }
  251. return clipPath;
  252. } else {
  253. return createPolarClipPath(coordSys, hasAnimation, seriesModel);
  254. }
  255. }
  256. var _default = ChartView.extend({
  257. type: 'line',
  258. init: function () {
  259. var lineGroup = new graphic.Group();
  260. var symbolDraw = new SymbolDraw();
  261. this.group.add(symbolDraw.group);
  262. this._symbolDraw = symbolDraw;
  263. this._lineGroup = lineGroup;
  264. },
  265. render: function (seriesModel, ecModel, api) {
  266. var coordSys = seriesModel.coordinateSystem;
  267. var group = this.group;
  268. var data = seriesModel.getData();
  269. var lineStyleModel = seriesModel.getModel('lineStyle');
  270. var areaStyleModel = seriesModel.getModel('areaStyle');
  271. var points = data.mapArray(data.getItemLayout);
  272. var isCoordSysPolar = coordSys.type === 'polar';
  273. var prevCoordSys = this._coordSys;
  274. var symbolDraw = this._symbolDraw;
  275. var polyline = this._polyline;
  276. var polygon = this._polygon;
  277. var lineGroup = this._lineGroup;
  278. var hasAnimation = seriesModel.get('animation');
  279. var isAreaChart = !areaStyleModel.isEmpty();
  280. var valueOrigin = areaStyleModel.get('origin');
  281. var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);
  282. var stackedOnPoints = getStackedOnPoints(coordSys, data, dataCoordInfo);
  283. var showSymbol = seriesModel.get('showSymbol');
  284. var isIgnoreFunc = showSymbol && !isCoordSysPolar && getIsIgnoreFunc(seriesModel, data, coordSys); // Remove temporary symbols
  285. var oldData = this._data;
  286. oldData && oldData.eachItemGraphicEl(function (el, idx) {
  287. if (el.__temp) {
  288. group.remove(el);
  289. oldData.setItemGraphicEl(idx, null);
  290. }
  291. }); // Remove previous created symbols if showSymbol changed to false
  292. if (!showSymbol) {
  293. symbolDraw.remove();
  294. }
  295. group.add(lineGroup); // FIXME step not support polar
  296. var step = !isCoordSysPolar && seriesModel.get('step');
  297. var clipShapeForSymbol;
  298. if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
  299. clipShapeForSymbol = coordSys.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent.
  300. // See #7913 and `test/dataZoom-clip.html`.
  301. if (clipShapeForSymbol.width != null) {
  302. clipShapeForSymbol.x -= 0.1;
  303. clipShapeForSymbol.y -= 0.1;
  304. clipShapeForSymbol.width += 0.2;
  305. clipShapeForSymbol.height += 0.2;
  306. } else if (clipShapeForSymbol.r0) {
  307. clipShapeForSymbol.r0 -= 0.5;
  308. clipShapeForSymbol.r1 += 0.5;
  309. }
  310. }
  311. this._clipShapeForSymbol = clipShapeForSymbol; // Initialization animation or coordinate system changed
  312. if (!(polyline && prevCoordSys.type === coordSys.type && step === this._step)) {
  313. showSymbol && symbolDraw.updateData(data, {
  314. isIgnore: isIgnoreFunc,
  315. clipShape: clipShapeForSymbol
  316. });
  317. if (step) {
  318. // TODO If stacked series is not step
  319. points = turnPointsIntoStep(points, coordSys, step);
  320. stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
  321. }
  322. polyline = this._newPolyline(points, coordSys, hasAnimation);
  323. if (isAreaChart) {
  324. polygon = this._newPolygon(points, stackedOnPoints, coordSys, hasAnimation);
  325. }
  326. lineGroup.setClipPath(createLineClipPath(coordSys, true, seriesModel));
  327. } else {
  328. if (isAreaChart && !polygon) {
  329. // If areaStyle is added
  330. polygon = this._newPolygon(points, stackedOnPoints, coordSys, hasAnimation);
  331. } else if (polygon && !isAreaChart) {
  332. // If areaStyle is removed
  333. lineGroup.remove(polygon);
  334. polygon = this._polygon = null;
  335. } // Update clipPath
  336. lineGroup.setClipPath(createLineClipPath(coordSys, false, seriesModel)); // Always update, or it is wrong in the case turning on legend
  337. // because points are not changed
  338. showSymbol && symbolDraw.updateData(data, {
  339. isIgnore: isIgnoreFunc,
  340. clipShape: clipShapeForSymbol
  341. }); // Stop symbol animation and sync with line points
  342. // FIXME performance?
  343. data.eachItemGraphicEl(function (el) {
  344. el.stopAnimation(true);
  345. }); // In the case data zoom triggerred refreshing frequently
  346. // Data may not change if line has a category axis. So it should animate nothing
  347. if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || !isPointsSame(this._points, points)) {
  348. if (hasAnimation) {
  349. this._updateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin);
  350. } else {
  351. // Not do it in update with animation
  352. if (step) {
  353. // TODO If stacked series is not step
  354. points = turnPointsIntoStep(points, coordSys, step);
  355. stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step);
  356. }
  357. polyline.setShape({
  358. points: points
  359. });
  360. polygon && polygon.setShape({
  361. points: points,
  362. stackedOnPoints: stackedOnPoints
  363. });
  364. }
  365. }
  366. }
  367. var visualColor = getVisualGradient(data, coordSys) || data.getVisual('color');
  368. polyline.useStyle(zrUtil.defaults( // Use color in lineStyle first
  369. lineStyleModel.getLineStyle(), {
  370. fill: 'none',
  371. stroke: visualColor,
  372. lineJoin: 'bevel'
  373. }));
  374. var smooth = seriesModel.get('smooth');
  375. smooth = getSmooth(seriesModel.get('smooth'));
  376. polyline.setShape({
  377. smooth: smooth,
  378. smoothMonotone: seriesModel.get('smoothMonotone'),
  379. connectNulls: seriesModel.get('connectNulls')
  380. });
  381. if (polygon) {
  382. var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
  383. var stackedOnSmooth = 0;
  384. polygon.useStyle(zrUtil.defaults(areaStyleModel.getAreaStyle(), {
  385. fill: visualColor,
  386. opacity: 0.7,
  387. lineJoin: 'bevel'
  388. }));
  389. if (stackedOnSeries) {
  390. stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
  391. }
  392. polygon.setShape({
  393. smooth: smooth,
  394. stackedOnSmooth: stackedOnSmooth,
  395. smoothMonotone: seriesModel.get('smoothMonotone'),
  396. connectNulls: seriesModel.get('connectNulls')
  397. });
  398. }
  399. this._data = data; // Save the coordinate system for transition animation when data changed
  400. this._coordSys = coordSys;
  401. this._stackedOnPoints = stackedOnPoints;
  402. this._points = points;
  403. this._step = step;
  404. this._valueOrigin = valueOrigin;
  405. },
  406. dispose: function () {},
  407. highlight: function (seriesModel, ecModel, api, payload) {
  408. var data = seriesModel.getData();
  409. var dataIndex = modelUtil.queryDataIndex(data, payload);
  410. if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
  411. var symbol = data.getItemGraphicEl(dataIndex);
  412. if (!symbol) {
  413. // Create a temporary symbol if it is not exists
  414. var pt = data.getItemLayout(dataIndex);
  415. if (!pt) {
  416. // Null data
  417. return;
  418. } // fix #11360: should't draw symbol outside clipShapeForSymbol
  419. if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(pt[0], pt[1])) {
  420. return;
  421. }
  422. symbol = new SymbolClz(data, dataIndex);
  423. symbol.position = pt;
  424. symbol.setZ(seriesModel.get('zlevel'), seriesModel.get('z'));
  425. symbol.ignore = isNaN(pt[0]) || isNaN(pt[1]);
  426. symbol.__temp = true;
  427. data.setItemGraphicEl(dataIndex, symbol); // Stop scale animation
  428. symbol.stopSymbolAnimation(true);
  429. this.group.add(symbol);
  430. }
  431. symbol.highlight();
  432. } else {
  433. // Highlight whole series
  434. ChartView.prototype.highlight.call(this, seriesModel, ecModel, api, payload);
  435. }
  436. },
  437. downplay: function (seriesModel, ecModel, api, payload) {
  438. var data = seriesModel.getData();
  439. var dataIndex = modelUtil.queryDataIndex(data, payload);
  440. if (dataIndex != null && dataIndex >= 0) {
  441. var symbol = data.getItemGraphicEl(dataIndex);
  442. if (symbol) {
  443. if (symbol.__temp) {
  444. data.setItemGraphicEl(dataIndex, null);
  445. this.group.remove(symbol);
  446. } else {
  447. symbol.downplay();
  448. }
  449. }
  450. } else {
  451. // FIXME
  452. // can not downplay completely.
  453. // Downplay whole series
  454. ChartView.prototype.downplay.call(this, seriesModel, ecModel, api, payload);
  455. }
  456. },
  457. /**
  458. * @param {module:zrender/container/Group} group
  459. * @param {Array.<Array.<number>>} points
  460. * @private
  461. */
  462. _newPolyline: function (points) {
  463. var polyline = this._polyline; // Remove previous created polyline
  464. if (polyline) {
  465. this._lineGroup.remove(polyline);
  466. }
  467. polyline = new Polyline({
  468. shape: {
  469. points: points
  470. },
  471. silent: true,
  472. z2: 10
  473. });
  474. this._lineGroup.add(polyline);
  475. this._polyline = polyline;
  476. return polyline;
  477. },
  478. /**
  479. * @param {module:zrender/container/Group} group
  480. * @param {Array.<Array.<number>>} stackedOnPoints
  481. * @param {Array.<Array.<number>>} points
  482. * @private
  483. */
  484. _newPolygon: function (points, stackedOnPoints) {
  485. var polygon = this._polygon; // Remove previous created polygon
  486. if (polygon) {
  487. this._lineGroup.remove(polygon);
  488. }
  489. polygon = new Polygon({
  490. shape: {
  491. points: points,
  492. stackedOnPoints: stackedOnPoints
  493. },
  494. silent: true
  495. });
  496. this._lineGroup.add(polygon);
  497. this._polygon = polygon;
  498. return polygon;
  499. },
  500. /**
  501. * @private
  502. */
  503. // FIXME Two value axis
  504. _updateAnimation: function (data, stackedOnPoints, coordSys, api, step, valueOrigin) {
  505. var polyline = this._polyline;
  506. var polygon = this._polygon;
  507. var seriesModel = data.hostModel;
  508. var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin, valueOrigin);
  509. var current = diff.current;
  510. var stackedOnCurrent = diff.stackedOnCurrent;
  511. var next = diff.next;
  512. var stackedOnNext = diff.stackedOnNext;
  513. if (step) {
  514. // TODO If stacked series is not step
  515. current = turnPointsIntoStep(diff.current, coordSys, step);
  516. stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step);
  517. next = turnPointsIntoStep(diff.next, coordSys, step);
  518. stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step);
  519. } // `diff.current` is subset of `current` (which should be ensured by
  520. // turnPointsIntoStep), so points in `__points` can be updated when
  521. // points in `current` are update during animation.
  522. polyline.shape.__points = diff.current;
  523. polyline.shape.points = current;
  524. graphic.updateProps(polyline, {
  525. shape: {
  526. points: next
  527. }
  528. }, seriesModel);
  529. if (polygon) {
  530. polygon.setShape({
  531. points: current,
  532. stackedOnPoints: stackedOnCurrent
  533. });
  534. graphic.updateProps(polygon, {
  535. shape: {
  536. points: next,
  537. stackedOnPoints: stackedOnNext
  538. }
  539. }, seriesModel);
  540. }
  541. var updatedDataInfo = [];
  542. var diffStatus = diff.status;
  543. for (var i = 0; i < diffStatus.length; i++) {
  544. var cmd = diffStatus[i].cmd;
  545. if (cmd === '=') {
  546. var el = data.getItemGraphicEl(diffStatus[i].idx1);
  547. if (el) {
  548. updatedDataInfo.push({
  549. el: el,
  550. ptIdx: i // Index of points
  551. });
  552. }
  553. }
  554. }
  555. if (polyline.animators && polyline.animators.length) {
  556. polyline.animators[0].during(function () {
  557. for (var i = 0; i < updatedDataInfo.length; i++) {
  558. var el = updatedDataInfo[i].el;
  559. el.attr('position', polyline.shape.__points[updatedDataInfo[i].ptIdx]);
  560. }
  561. });
  562. }
  563. },
  564. remove: function (ecModel) {
  565. var group = this.group;
  566. var oldData = this._data;
  567. this._lineGroup.removeAll();
  568. this._symbolDraw.remove(true); // Remove temporary created elements when highlighting
  569. oldData && oldData.eachItemGraphicEl(function (el, idx) {
  570. if (el.__temp) {
  571. group.remove(el);
  572. oldData.setItemGraphicEl(idx, null);
  573. }
  574. });
  575. this._polyline = this._polygon = this._coordSys = this._points = this._stackedOnPoints = this._data = null;
  576. }
  577. });
  578. module.exports = _default;