LineView.js 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288
  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. /**
  20. * AUTO-GENERATED FILE. DO NOT MODIFY.
  21. */
  22. /*
  23. * Licensed to the Apache Software Foundation (ASF) under one
  24. * or more contributor license agreements. See the NOTICE file
  25. * distributed with this work for additional information
  26. * regarding copyright ownership. The ASF licenses this file
  27. * to you under the Apache License, Version 2.0 (the
  28. * "License"); you may not use this file except in compliance
  29. * with the License. You may obtain a copy of the License at
  30. *
  31. * http://www.apache.org/licenses/LICENSE-2.0
  32. *
  33. * Unless required by applicable law or agreed to in writing,
  34. * software distributed under the License is distributed on an
  35. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  36. * KIND, either express or implied. See the License for the
  37. * specific language governing permissions and limitations
  38. * under the License.
  39. */
  40. import { __extends } from "tslib"; // FIXME step not support polar
  41. import * as zrUtil from 'zrender/lib/core/util.js';
  42. import SymbolDraw from '../helper/SymbolDraw.js';
  43. import SymbolClz from '../helper/Symbol.js';
  44. import lineAnimationDiff from './lineAnimationDiff.js';
  45. import * as graphic from '../../util/graphic.js';
  46. import * as modelUtil from '../../util/model.js';
  47. import { ECPolyline, ECPolygon } from './poly.js';
  48. import ChartView from '../../view/Chart.js';
  49. import { prepareDataCoordInfo, getStackedOnPoint } from './helper.js';
  50. import { createGridClipPath, createPolarClipPath } from '../helper/createClipPathFromCoordSys.js';
  51. import { isCoordinateSystemType } from '../../coord/CoordinateSystem.js';
  52. import { setStatesStylesFromModel, setStatesFlag, toggleHoverEmphasis, SPECIAL_STATES } from '../../util/states.js';
  53. import { setLabelStyle, getLabelStatesModels, labelInner } from '../../label/labelStyle.js';
  54. import { getDefaultLabel, getDefaultInterpolatedLabel } from '../helper/labelHelper.js';
  55. import { getECData } from '../../util/innerStore.js';
  56. import { createFloat32Array } from '../../util/vendor.js';
  57. import { convertToColorString } from '../../util/format.js';
  58. import { lerp } from 'zrender/lib/tool/color.js';
  59. function isPointsSame(points1, points2) {
  60. if (points1.length !== points2.length) {
  61. return;
  62. }
  63. for (var i = 0; i < points1.length; i++) {
  64. if (points1[i] !== points2[i]) {
  65. return;
  66. }
  67. }
  68. return true;
  69. }
  70. function bboxFromPoints(points) {
  71. var minX = Infinity;
  72. var minY = Infinity;
  73. var maxX = -Infinity;
  74. var maxY = -Infinity;
  75. for (var i = 0; i < points.length;) {
  76. var x = points[i++];
  77. var y = points[i++];
  78. if (!isNaN(x)) {
  79. minX = Math.min(x, minX);
  80. maxX = Math.max(x, maxX);
  81. }
  82. if (!isNaN(y)) {
  83. minY = Math.min(y, minY);
  84. maxY = Math.max(y, maxY);
  85. }
  86. }
  87. return [[minX, minY], [maxX, maxY]];
  88. }
  89. function getBoundingDiff(points1, points2) {
  90. var _a = bboxFromPoints(points1),
  91. min1 = _a[0],
  92. max1 = _a[1];
  93. var _b = bboxFromPoints(points2),
  94. min2 = _b[0],
  95. max2 = _b[1]; // Get a max value from each corner of two boundings.
  96. 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]));
  97. }
  98. function getSmooth(smooth) {
  99. return zrUtil.isNumber(smooth) ? smooth : smooth ? 0.5 : 0;
  100. }
  101. function getStackedOnPoints(coordSys, data, dataCoordInfo) {
  102. if (!dataCoordInfo.valueDim) {
  103. return [];
  104. }
  105. var len = data.count();
  106. var points = createFloat32Array(len * 2);
  107. for (var idx = 0; idx < len; idx++) {
  108. var pt = getStackedOnPoint(dataCoordInfo, coordSys, data, idx);
  109. points[idx * 2] = pt[0];
  110. points[idx * 2 + 1] = pt[1];
  111. }
  112. return points;
  113. }
  114. function turnPointsIntoStep(points, coordSys, stepTurnAt, connectNulls) {
  115. var baseAxis = coordSys.getBaseAxis();
  116. var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;
  117. var stepPoints = [];
  118. var i = 0;
  119. var stepPt = [];
  120. var pt = [];
  121. var nextPt = [];
  122. var filteredPoints = [];
  123. if (connectNulls) {
  124. for (i = 0; i < points.length; i += 2) {
  125. if (!isNaN(points[i]) && !isNaN(points[i + 1])) {
  126. filteredPoints.push(points[i], points[i + 1]);
  127. }
  128. }
  129. points = filteredPoints;
  130. }
  131. for (i = 0; i < points.length - 2; i += 2) {
  132. nextPt[0] = points[i + 2];
  133. nextPt[1] = points[i + 3];
  134. pt[0] = points[i];
  135. pt[1] = points[i + 1];
  136. stepPoints.push(pt[0], pt[1]);
  137. switch (stepTurnAt) {
  138. case 'end':
  139. stepPt[baseIndex] = nextPt[baseIndex];
  140. stepPt[1 - baseIndex] = pt[1 - baseIndex];
  141. stepPoints.push(stepPt[0], stepPt[1]);
  142. break;
  143. case 'middle':
  144. var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
  145. var stepPt2 = [];
  146. stepPt[baseIndex] = stepPt2[baseIndex] = middle;
  147. stepPt[1 - baseIndex] = pt[1 - baseIndex];
  148. stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
  149. stepPoints.push(stepPt[0], stepPt[1]);
  150. stepPoints.push(stepPt2[0], stepPt2[1]);
  151. break;
  152. default:
  153. // default is start
  154. stepPt[baseIndex] = pt[baseIndex];
  155. stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
  156. stepPoints.push(stepPt[0], stepPt[1]);
  157. }
  158. } // Last points
  159. stepPoints.push(points[i++], points[i++]);
  160. return stepPoints;
  161. }
  162. /**
  163. * Clip color stops to edge. Avoid creating too large gradients.
  164. * Which may lead to blurry when GPU acceleration is enabled. See #15680
  165. *
  166. * The stops has been sorted from small to large.
  167. */
  168. function clipColorStops(colorStops, maxSize) {
  169. var newColorStops = [];
  170. var len = colorStops.length; // coord will always < 0 in prevOutOfRangeColorStop.
  171. var prevOutOfRangeColorStop;
  172. var prevInRangeColorStop;
  173. function lerpStop(stop0, stop1, clippedCoord) {
  174. var coord0 = stop0.coord;
  175. var p = (clippedCoord - coord0) / (stop1.coord - coord0);
  176. var color = lerp(p, [stop0.color, stop1.color]);
  177. return {
  178. coord: clippedCoord,
  179. color: color
  180. };
  181. }
  182. for (var i = 0; i < len; i++) {
  183. var stop_1 = colorStops[i];
  184. var coord = stop_1.coord;
  185. if (coord < 0) {
  186. prevOutOfRangeColorStop = stop_1;
  187. } else if (coord > maxSize) {
  188. if (prevInRangeColorStop) {
  189. newColorStops.push(lerpStop(prevInRangeColorStop, stop_1, maxSize));
  190. } else if (prevOutOfRangeColorStop) {
  191. // If there are two stops and coord range is between these two stops
  192. newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0), lerpStop(prevOutOfRangeColorStop, stop_1, maxSize));
  193. } // All following stop will be out of range. So just ignore them.
  194. break;
  195. } else {
  196. if (prevOutOfRangeColorStop) {
  197. newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0)); // Reset
  198. prevOutOfRangeColorStop = null;
  199. }
  200. newColorStops.push(stop_1);
  201. prevInRangeColorStop = stop_1;
  202. }
  203. }
  204. return newColorStops;
  205. }
  206. function getVisualGradient(data, coordSys, api) {
  207. var visualMetaList = data.getVisual('visualMeta');
  208. if (!visualMetaList || !visualMetaList.length || !data.count()) {
  209. // When data.count() is 0, gradient range can not be calculated.
  210. return;
  211. }
  212. if (coordSys.type !== 'cartesian2d') {
  213. if (process.env.NODE_ENV !== 'production') {
  214. console.warn('Visual map on line style is only supported on cartesian2d.');
  215. }
  216. return;
  217. }
  218. var coordDim;
  219. var visualMeta;
  220. for (var i = visualMetaList.length - 1; i >= 0; i--) {
  221. var dimInfo = data.getDimensionInfo(visualMetaList[i].dimension);
  222. coordDim = dimInfo && dimInfo.coordDim; // Can only be x or y
  223. if (coordDim === 'x' || coordDim === 'y') {
  224. visualMeta = visualMetaList[i];
  225. break;
  226. }
  227. }
  228. if (!visualMeta) {
  229. if (process.env.NODE_ENV !== 'production') {
  230. console.warn('Visual map on line style only support x or y dimension.');
  231. }
  232. return;
  233. } // If the area to be rendered is bigger than area defined by LinearGradient,
  234. // the canvas spec prescribes that the color of the first stop and the last
  235. // stop should be used. But if two stops are added at offset 0, in effect
  236. // browsers use the color of the second stop to render area outside
  237. // LinearGradient. So we can only infinitesimally extend area defined in
  238. // LinearGradient to render `outerColors`.
  239. var axis = coordSys.getAxis(coordDim); // dataToCoord mapping may not be linear, but must be monotonic.
  240. var colorStops = zrUtil.map(visualMeta.stops, function (stop) {
  241. // offset will be calculated later.
  242. return {
  243. coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
  244. color: stop.color
  245. };
  246. });
  247. var stopLen = colorStops.length;
  248. var outerColors = visualMeta.outerColors.slice();
  249. if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
  250. colorStops.reverse();
  251. outerColors.reverse();
  252. }
  253. var colorStopsInRange = clipColorStops(colorStops, coordDim === 'x' ? api.getWidth() : api.getHeight());
  254. var inRangeStopLen = colorStopsInRange.length;
  255. if (!inRangeStopLen && stopLen) {
  256. // All stops are out of range. All will be the same color.
  257. return colorStops[0].coord < 0 ? outerColors[1] ? outerColors[1] : colorStops[stopLen - 1].color : outerColors[0] ? outerColors[0] : colorStops[0].color;
  258. }
  259. var tinyExtent = 10; // Arbitrary value: 10px
  260. var minCoord = colorStopsInRange[0].coord - tinyExtent;
  261. var maxCoord = colorStopsInRange[inRangeStopLen - 1].coord + tinyExtent;
  262. var coordSpan = maxCoord - minCoord;
  263. if (coordSpan < 1e-3) {
  264. return 'transparent';
  265. }
  266. zrUtil.each(colorStopsInRange, function (stop) {
  267. stop.offset = (stop.coord - minCoord) / coordSpan;
  268. });
  269. colorStopsInRange.push({
  270. // NOTE: inRangeStopLen may still be 0 if stoplen is zero.
  271. offset: inRangeStopLen ? colorStopsInRange[inRangeStopLen - 1].offset : 0.5,
  272. color: outerColors[1] || 'transparent'
  273. });
  274. colorStopsInRange.unshift({
  275. offset: inRangeStopLen ? colorStopsInRange[0].offset : 0.5,
  276. color: outerColors[0] || 'transparent'
  277. });
  278. var gradient = new graphic.LinearGradient(0, 0, 0, 0, colorStopsInRange, true);
  279. gradient[coordDim] = minCoord;
  280. gradient[coordDim + '2'] = maxCoord;
  281. return gradient;
  282. }
  283. function getIsIgnoreFunc(seriesModel, data, coordSys) {
  284. var showAllSymbol = seriesModel.get('showAllSymbol');
  285. var isAuto = showAllSymbol === 'auto';
  286. if (showAllSymbol && !isAuto) {
  287. return;
  288. }
  289. var categoryAxis = coordSys.getAxesByScale('ordinal')[0];
  290. if (!categoryAxis) {
  291. return;
  292. } // Note that category label interval strategy might bring some weird effect
  293. // in some scenario: users may wonder why some of the symbols are not
  294. // displayed. So we show all symbols as possible as we can.
  295. if (isAuto // Simplify the logic, do not determine label overlap here.
  296. && canShowAllSymbolForCategory(categoryAxis, data)) {
  297. return;
  298. } // Otherwise follow the label interval strategy on category axis.
  299. var categoryDataDim = data.mapDimension(categoryAxis.dim);
  300. var labelMap = {};
  301. zrUtil.each(categoryAxis.getViewLabels(), function (labelItem) {
  302. var ordinalNumber = categoryAxis.scale.getRawOrdinalNumber(labelItem.tickValue);
  303. labelMap[ordinalNumber] = 1;
  304. });
  305. return function (dataIndex) {
  306. return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
  307. };
  308. }
  309. function canShowAllSymbolForCategory(categoryAxis, data) {
  310. // In most cases, line is monotonous on category axis, and the label size
  311. // is close with each other. So we check the symbol size and some of the
  312. // label size alone with the category axis to estimate whether all symbol
  313. // can be shown without overlap.
  314. var axisExtent = categoryAxis.getExtent();
  315. var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count();
  316. isNaN(availSize) && (availSize = 0); // 0/0 is NaN.
  317. // Sampling some points, max 5.
  318. var dataLen = data.count();
  319. var step = Math.max(1, Math.round(dataLen / 5));
  320. for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
  321. if (SymbolClz.getSymbolSize(data, dataIndex // Only for cartesian, where `isHorizontal` exists.
  322. )[categoryAxis.isHorizontal() ? 1 : 0] // Empirical number
  323. * 1.5 > availSize) {
  324. return false;
  325. }
  326. }
  327. return true;
  328. }
  329. function isPointNull(x, y) {
  330. return isNaN(x) || isNaN(y);
  331. }
  332. function getLastIndexNotNull(points) {
  333. var len = points.length / 2;
  334. for (; len > 0; len--) {
  335. if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
  336. break;
  337. }
  338. }
  339. return len - 1;
  340. }
  341. function getPointAtIndex(points, idx) {
  342. return [points[idx * 2], points[idx * 2 + 1]];
  343. }
  344. function getIndexRange(points, xOrY, dim) {
  345. var len = points.length / 2;
  346. var dimIdx = dim === 'x' ? 0 : 1;
  347. var a;
  348. var b;
  349. var prevIndex = 0;
  350. var nextIndex = -1;
  351. for (var i = 0; i < len; i++) {
  352. b = points[i * 2 + dimIdx];
  353. if (isNaN(b) || isNaN(points[i * 2 + 1 - dimIdx])) {
  354. continue;
  355. }
  356. if (i === 0) {
  357. a = b;
  358. continue;
  359. }
  360. if (a <= xOrY && b >= xOrY || a >= xOrY && b <= xOrY) {
  361. nextIndex = i;
  362. break;
  363. }
  364. prevIndex = i;
  365. a = b;
  366. }
  367. return {
  368. range: [prevIndex, nextIndex],
  369. t: (xOrY - a) / (b - a)
  370. };
  371. }
  372. function anyStateShowEndLabel(seriesModel) {
  373. if (seriesModel.get(['endLabel', 'show'])) {
  374. return true;
  375. }
  376. for (var i = 0; i < SPECIAL_STATES.length; i++) {
  377. if (seriesModel.get([SPECIAL_STATES[i], 'endLabel', 'show'])) {
  378. return true;
  379. }
  380. }
  381. return false;
  382. }
  383. function createLineClipPath(lineView, coordSys, hasAnimation, seriesModel) {
  384. if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
  385. var endLabelModel_1 = seriesModel.getModel('endLabel');
  386. var valueAnimation_1 = endLabelModel_1.get('valueAnimation');
  387. var data_1 = seriesModel.getData();
  388. var labelAnimationRecord_1 = {
  389. lastFrameIndex: 0
  390. };
  391. var during = anyStateShowEndLabel(seriesModel) ? function (percent, clipRect) {
  392. lineView._endLabelOnDuring(percent, clipRect, data_1, labelAnimationRecord_1, valueAnimation_1, endLabelModel_1, coordSys);
  393. } : null;
  394. var isHorizontal = coordSys.getBaseAxis().isHorizontal();
  395. var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, function () {
  396. var endLabel = lineView._endLabel;
  397. if (endLabel && hasAnimation) {
  398. if (labelAnimationRecord_1.originalX != null) {
  399. endLabel.attr({
  400. x: labelAnimationRecord_1.originalX,
  401. y: labelAnimationRecord_1.originalY
  402. });
  403. }
  404. }
  405. }, during); // Expand clip shape to avoid clipping when line value exceeds axis
  406. if (!seriesModel.get('clip', true)) {
  407. var rectShape = clipPath.shape;
  408. var expandSize = Math.max(rectShape.width, rectShape.height);
  409. if (isHorizontal) {
  410. rectShape.y -= expandSize;
  411. rectShape.height += expandSize * 2;
  412. } else {
  413. rectShape.x -= expandSize;
  414. rectShape.width += expandSize * 2;
  415. }
  416. } // Set to the final frame. To make sure label layout is right.
  417. if (during) {
  418. during(1, clipPath);
  419. }
  420. return clipPath;
  421. } else {
  422. if (process.env.NODE_ENV !== 'production') {
  423. if (seriesModel.get(['endLabel', 'show'])) {
  424. console.warn('endLabel is not supported for lines in polar systems.');
  425. }
  426. }
  427. return createPolarClipPath(coordSys, hasAnimation, seriesModel);
  428. }
  429. }
  430. function getEndLabelStateSpecified(endLabelModel, coordSys) {
  431. var baseAxis = coordSys.getBaseAxis();
  432. var isHorizontal = baseAxis.isHorizontal();
  433. var isBaseInversed = baseAxis.inverse;
  434. var align = isHorizontal ? isBaseInversed ? 'right' : 'left' : 'center';
  435. var verticalAlign = isHorizontal ? 'middle' : isBaseInversed ? 'top' : 'bottom';
  436. return {
  437. normal: {
  438. align: endLabelModel.get('align') || align,
  439. verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign
  440. }
  441. };
  442. }
  443. var LineView =
  444. /** @class */
  445. function (_super) {
  446. __extends(LineView, _super);
  447. function LineView() {
  448. return _super !== null && _super.apply(this, arguments) || this;
  449. }
  450. LineView.prototype.init = function () {
  451. var lineGroup = new graphic.Group();
  452. var symbolDraw = new SymbolDraw();
  453. this.group.add(symbolDraw.group);
  454. this._symbolDraw = symbolDraw;
  455. this._lineGroup = lineGroup;
  456. };
  457. LineView.prototype.render = function (seriesModel, ecModel, api) {
  458. var _this = this;
  459. var coordSys = seriesModel.coordinateSystem;
  460. var group = this.group;
  461. var data = seriesModel.getData();
  462. var lineStyleModel = seriesModel.getModel('lineStyle');
  463. var areaStyleModel = seriesModel.getModel('areaStyle');
  464. var points = data.getLayout('points') || [];
  465. var isCoordSysPolar = coordSys.type === 'polar';
  466. var prevCoordSys = this._coordSys;
  467. var symbolDraw = this._symbolDraw;
  468. var polyline = this._polyline;
  469. var polygon = this._polygon;
  470. var lineGroup = this._lineGroup;
  471. var hasAnimation = !ecModel.ssr && seriesModel.isAnimationEnabled();
  472. var isAreaChart = !areaStyleModel.isEmpty();
  473. var valueOrigin = areaStyleModel.get('origin');
  474. var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);
  475. var stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);
  476. var showSymbol = seriesModel.get('showSymbol');
  477. var connectNulls = seriesModel.get('connectNulls');
  478. var isIgnoreFunc = showSymbol && !isCoordSysPolar && getIsIgnoreFunc(seriesModel, data, coordSys); // Remove temporary symbols
  479. var oldData = this._data;
  480. oldData && oldData.eachItemGraphicEl(function (el, idx) {
  481. if (el.__temp) {
  482. group.remove(el);
  483. oldData.setItemGraphicEl(idx, null);
  484. }
  485. }); // Remove previous created symbols if showSymbol changed to false
  486. if (!showSymbol) {
  487. symbolDraw.remove();
  488. }
  489. group.add(lineGroup); // FIXME step not support polar
  490. var step = !isCoordSysPolar ? seriesModel.get('step') : false;
  491. var clipShapeForSymbol;
  492. if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
  493. clipShapeForSymbol = coordSys.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent.
  494. // See #7913 and `test/dataZoom-clip.html`.
  495. if (clipShapeForSymbol.width != null) {
  496. clipShapeForSymbol.x -= 0.1;
  497. clipShapeForSymbol.y -= 0.1;
  498. clipShapeForSymbol.width += 0.2;
  499. clipShapeForSymbol.height += 0.2;
  500. } else if (clipShapeForSymbol.r0) {
  501. clipShapeForSymbol.r0 -= 0.5;
  502. clipShapeForSymbol.r += 0.5;
  503. }
  504. }
  505. this._clipShapeForSymbol = clipShapeForSymbol;
  506. var visualColor = getVisualGradient(data, coordSys, api) || data.getVisual('style')[data.getVisual('drawType')]; // Initialization animation or coordinate system changed
  507. if (!(polyline && prevCoordSys.type === coordSys.type && step === this._step)) {
  508. showSymbol && symbolDraw.updateData(data, {
  509. isIgnore: isIgnoreFunc,
  510. clipShape: clipShapeForSymbol,
  511. disableAnimation: true,
  512. getSymbolPoint: function (idx) {
  513. return [points[idx * 2], points[idx * 2 + 1]];
  514. }
  515. });
  516. hasAnimation && this._initSymbolLabelAnimation(data, coordSys, clipShapeForSymbol);
  517. if (step) {
  518. // TODO If stacked series is not step
  519. points = turnPointsIntoStep(points, coordSys, step, connectNulls);
  520. if (stackedOnPoints) {
  521. stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
  522. }
  523. }
  524. polyline = this._newPolyline(points);
  525. if (isAreaChart) {
  526. polygon = this._newPolygon(points, stackedOnPoints);
  527. } // If areaStyle is removed
  528. else if (polygon) {
  529. lineGroup.remove(polygon);
  530. polygon = this._polygon = null;
  531. } // NOTE: Must update _endLabel before setClipPath.
  532. if (!isCoordSysPolar) {
  533. this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
  534. }
  535. lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
  536. } else {
  537. if (isAreaChart && !polygon) {
  538. // If areaStyle is added
  539. polygon = this._newPolygon(points, stackedOnPoints);
  540. } else if (polygon && !isAreaChart) {
  541. // If areaStyle is removed
  542. lineGroup.remove(polygon);
  543. polygon = this._polygon = null;
  544. } // NOTE: Must update _endLabel before setClipPath.
  545. if (!isCoordSysPolar) {
  546. this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
  547. } // Update clipPath
  548. var oldClipPath = lineGroup.getClipPath();
  549. if (oldClipPath) {
  550. var newClipPath = createLineClipPath(this, coordSys, false, seriesModel);
  551. graphic.initProps(oldClipPath, {
  552. shape: newClipPath.shape
  553. }, seriesModel);
  554. } else {
  555. lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
  556. } // Always update, or it is wrong in the case turning on legend
  557. // because points are not changed.
  558. showSymbol && symbolDraw.updateData(data, {
  559. isIgnore: isIgnoreFunc,
  560. clipShape: clipShapeForSymbol,
  561. disableAnimation: true,
  562. getSymbolPoint: function (idx) {
  563. return [points[idx * 2], points[idx * 2 + 1]];
  564. }
  565. }); // In the case data zoom triggered refreshing frequently
  566. // Data may not change if line has a category axis. So it should animate nothing.
  567. if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || !isPointsSame(this._points, points)) {
  568. if (hasAnimation) {
  569. this._doUpdateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls);
  570. } else {
  571. // Not do it in update with animation
  572. if (step) {
  573. // TODO If stacked series is not step
  574. points = turnPointsIntoStep(points, coordSys, step, connectNulls);
  575. if (stackedOnPoints) {
  576. stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
  577. }
  578. }
  579. polyline.setShape({
  580. points: points
  581. });
  582. polygon && polygon.setShape({
  583. points: points,
  584. stackedOnPoints: stackedOnPoints
  585. });
  586. }
  587. }
  588. }
  589. var emphasisModel = seriesModel.getModel('emphasis');
  590. var focus = emphasisModel.get('focus');
  591. var blurScope = emphasisModel.get('blurScope');
  592. var emphasisDisabled = emphasisModel.get('disabled');
  593. polyline.useStyle(zrUtil.defaults( // Use color in lineStyle first
  594. lineStyleModel.getLineStyle(), {
  595. fill: 'none',
  596. stroke: visualColor,
  597. lineJoin: 'bevel'
  598. }));
  599. setStatesStylesFromModel(polyline, seriesModel, 'lineStyle');
  600. if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') {
  601. var emphasisLineStyle = polyline.getState('emphasis').style;
  602. emphasisLineStyle.lineWidth = +polyline.style.lineWidth + 1;
  603. } // Needs seriesIndex for focus
  604. getECData(polyline).seriesIndex = seriesModel.seriesIndex;
  605. toggleHoverEmphasis(polyline, focus, blurScope, emphasisDisabled);
  606. var smooth = getSmooth(seriesModel.get('smooth'));
  607. var smoothMonotone = seriesModel.get('smoothMonotone');
  608. polyline.setShape({
  609. smooth: smooth,
  610. smoothMonotone: smoothMonotone,
  611. connectNulls: connectNulls
  612. });
  613. if (polygon) {
  614. var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
  615. var stackedOnSmooth = 0;
  616. polygon.useStyle(zrUtil.defaults(areaStyleModel.getAreaStyle(), {
  617. fill: visualColor,
  618. opacity: 0.7,
  619. lineJoin: 'bevel',
  620. decal: data.getVisual('style').decal
  621. }));
  622. if (stackedOnSeries) {
  623. stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
  624. }
  625. polygon.setShape({
  626. smooth: smooth,
  627. stackedOnSmooth: stackedOnSmooth,
  628. smoothMonotone: smoothMonotone,
  629. connectNulls: connectNulls
  630. });
  631. setStatesStylesFromModel(polygon, seriesModel, 'areaStyle'); // Needs seriesIndex for focus
  632. getECData(polygon).seriesIndex = seriesModel.seriesIndex;
  633. toggleHoverEmphasis(polygon, focus, blurScope, emphasisDisabled);
  634. }
  635. var changePolyState = function (toState) {
  636. _this._changePolyState(toState);
  637. };
  638. data.eachItemGraphicEl(function (el) {
  639. // Switch polyline / polygon state if element changed its state.
  640. el && (el.onHoverStateChange = changePolyState);
  641. });
  642. this._polyline.onHoverStateChange = changePolyState;
  643. this._data = data; // Save the coordinate system for transition animation when data changed
  644. this._coordSys = coordSys;
  645. this._stackedOnPoints = stackedOnPoints;
  646. this._points = points;
  647. this._step = step;
  648. this._valueOrigin = valueOrigin;
  649. if (seriesModel.get('triggerLineEvent')) {
  650. this.packEventData(seriesModel, polyline);
  651. polygon && this.packEventData(seriesModel, polygon);
  652. }
  653. };
  654. LineView.prototype.packEventData = function (seriesModel, el) {
  655. getECData(el).eventData = {
  656. componentType: 'series',
  657. componentSubType: 'line',
  658. componentIndex: seriesModel.componentIndex,
  659. seriesIndex: seriesModel.seriesIndex,
  660. seriesName: seriesModel.name,
  661. seriesType: 'line'
  662. };
  663. };
  664. LineView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
  665. var data = seriesModel.getData();
  666. var dataIndex = modelUtil.queryDataIndex(data, payload);
  667. this._changePolyState('emphasis');
  668. if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
  669. var points = data.getLayout('points');
  670. var symbol = data.getItemGraphicEl(dataIndex);
  671. if (!symbol) {
  672. // Create a temporary symbol if it is not exists
  673. var x = points[dataIndex * 2];
  674. var y = points[dataIndex * 2 + 1];
  675. if (isNaN(x) || isNaN(y)) {
  676. // Null data
  677. return;
  678. } // fix #11360: shouldn't draw symbol outside clipShapeForSymbol
  679. if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
  680. return;
  681. }
  682. var zlevel = seriesModel.get('zlevel') || 0;
  683. var z = seriesModel.get('z') || 0;
  684. symbol = new SymbolClz(data, dataIndex);
  685. symbol.x = x;
  686. symbol.y = y;
  687. symbol.setZ(zlevel, z); // ensure label text of the temporary symbol is in front of line and area polygon
  688. var symbolLabel = symbol.getSymbolPath().getTextContent();
  689. if (symbolLabel) {
  690. symbolLabel.zlevel = zlevel;
  691. symbolLabel.z = z;
  692. symbolLabel.z2 = this._polyline.z2 + 1;
  693. }
  694. symbol.__temp = true;
  695. data.setItemGraphicEl(dataIndex, symbol); // Stop scale animation
  696. symbol.stopSymbolAnimation(true);
  697. this.group.add(symbol);
  698. }
  699. symbol.highlight();
  700. } else {
  701. // Highlight whole series
  702. ChartView.prototype.highlight.call(this, seriesModel, ecModel, api, payload);
  703. }
  704. };
  705. LineView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
  706. var data = seriesModel.getData();
  707. var dataIndex = modelUtil.queryDataIndex(data, payload);
  708. this._changePolyState('normal');
  709. if (dataIndex != null && dataIndex >= 0) {
  710. var symbol = data.getItemGraphicEl(dataIndex);
  711. if (symbol) {
  712. if (symbol.__temp) {
  713. data.setItemGraphicEl(dataIndex, null);
  714. this.group.remove(symbol);
  715. } else {
  716. symbol.downplay();
  717. }
  718. }
  719. } else {
  720. // FIXME
  721. // can not downplay completely.
  722. // Downplay whole series
  723. ChartView.prototype.downplay.call(this, seriesModel, ecModel, api, payload);
  724. }
  725. };
  726. LineView.prototype._changePolyState = function (toState) {
  727. var polygon = this._polygon;
  728. setStatesFlag(this._polyline, toState);
  729. polygon && setStatesFlag(polygon, toState);
  730. };
  731. LineView.prototype._newPolyline = function (points) {
  732. var polyline = this._polyline; // Remove previous created polyline
  733. if (polyline) {
  734. this._lineGroup.remove(polyline);
  735. }
  736. polyline = new ECPolyline({
  737. shape: {
  738. points: points
  739. },
  740. segmentIgnoreThreshold: 2,
  741. z2: 10
  742. });
  743. this._lineGroup.add(polyline);
  744. this._polyline = polyline;
  745. return polyline;
  746. };
  747. LineView.prototype._newPolygon = function (points, stackedOnPoints) {
  748. var polygon = this._polygon; // Remove previous created polygon
  749. if (polygon) {
  750. this._lineGroup.remove(polygon);
  751. }
  752. polygon = new ECPolygon({
  753. shape: {
  754. points: points,
  755. stackedOnPoints: stackedOnPoints
  756. },
  757. segmentIgnoreThreshold: 2
  758. });
  759. this._lineGroup.add(polygon);
  760. this._polygon = polygon;
  761. return polygon;
  762. };
  763. LineView.prototype._initSymbolLabelAnimation = function (data, coordSys, clipShape) {
  764. var isHorizontalOrRadial;
  765. var isCoordSysPolar;
  766. var baseAxis = coordSys.getBaseAxis();
  767. var isAxisInverse = baseAxis.inverse;
  768. if (coordSys.type === 'cartesian2d') {
  769. isHorizontalOrRadial = baseAxis.isHorizontal();
  770. isCoordSysPolar = false;
  771. } else if (coordSys.type === 'polar') {
  772. isHorizontalOrRadial = baseAxis.dim === 'angle';
  773. isCoordSysPolar = true;
  774. }
  775. var seriesModel = data.hostModel;
  776. var seriesDuration = seriesModel.get('animationDuration');
  777. if (zrUtil.isFunction(seriesDuration)) {
  778. seriesDuration = seriesDuration(null);
  779. }
  780. var seriesDelay = seriesModel.get('animationDelay') || 0;
  781. var seriesDelayValue = zrUtil.isFunction(seriesDelay) ? seriesDelay(null) : seriesDelay;
  782. data.eachItemGraphicEl(function (symbol, idx) {
  783. var el = symbol;
  784. if (el) {
  785. var point = [symbol.x, symbol.y];
  786. var start = void 0;
  787. var end = void 0;
  788. var current = void 0;
  789. if (clipShape) {
  790. if (isCoordSysPolar) {
  791. var polarClip = clipShape;
  792. var coord = coordSys.pointToCoord(point);
  793. if (isHorizontalOrRadial) {
  794. start = polarClip.startAngle;
  795. end = polarClip.endAngle;
  796. current = -coord[1] / 180 * Math.PI;
  797. } else {
  798. start = polarClip.r0;
  799. end = polarClip.r;
  800. current = coord[0];
  801. }
  802. } else {
  803. var gridClip = clipShape;
  804. if (isHorizontalOrRadial) {
  805. start = gridClip.x;
  806. end = gridClip.x + gridClip.width;
  807. current = symbol.x;
  808. } else {
  809. start = gridClip.y + gridClip.height;
  810. end = gridClip.y;
  811. current = symbol.y;
  812. }
  813. }
  814. }
  815. var ratio = end === start ? 0 : (current - start) / (end - start);
  816. if (isAxisInverse) {
  817. ratio = 1 - ratio;
  818. }
  819. var delay = zrUtil.isFunction(seriesDelay) ? seriesDelay(idx) : seriesDuration * ratio + seriesDelayValue;
  820. var symbolPath = el.getSymbolPath();
  821. var text = symbolPath.getTextContent();
  822. el.attr({
  823. scaleX: 0,
  824. scaleY: 0
  825. });
  826. el.animateTo({
  827. scaleX: 1,
  828. scaleY: 1
  829. }, {
  830. duration: 200,
  831. setToFinal: true,
  832. delay: delay
  833. });
  834. if (text) {
  835. text.animateFrom({
  836. style: {
  837. opacity: 0
  838. }
  839. }, {
  840. duration: 300,
  841. delay: delay
  842. });
  843. }
  844. symbolPath.disableLabelAnimation = true;
  845. }
  846. });
  847. };
  848. LineView.prototype._initOrUpdateEndLabel = function (seriesModel, coordSys, inheritColor) {
  849. var endLabelModel = seriesModel.getModel('endLabel');
  850. if (anyStateShowEndLabel(seriesModel)) {
  851. var data_2 = seriesModel.getData();
  852. var polyline = this._polyline; // series may be filtered.
  853. var points = data_2.getLayout('points');
  854. if (!points) {
  855. polyline.removeTextContent();
  856. this._endLabel = null;
  857. return;
  858. }
  859. var endLabel = this._endLabel;
  860. if (!endLabel) {
  861. endLabel = this._endLabel = new graphic.Text({
  862. z2: 200 // should be higher than item symbol
  863. });
  864. endLabel.ignoreClip = true;
  865. polyline.setTextContent(this._endLabel);
  866. polyline.disableLabelAnimation = true;
  867. } // Find last non-NaN data to display data
  868. var dataIndex = getLastIndexNotNull(points);
  869. if (dataIndex >= 0) {
  870. setLabelStyle(polyline, getLabelStatesModels(seriesModel, 'endLabel'), {
  871. inheritColor: inheritColor,
  872. labelFetcher: seriesModel,
  873. labelDataIndex: dataIndex,
  874. defaultText: function (dataIndex, opt, interpolatedValue) {
  875. return interpolatedValue != null ? getDefaultInterpolatedLabel(data_2, interpolatedValue) : getDefaultLabel(data_2, dataIndex);
  876. },
  877. enableTextSetter: true
  878. }, getEndLabelStateSpecified(endLabelModel, coordSys));
  879. polyline.textConfig.position = null;
  880. }
  881. } else if (this._endLabel) {
  882. this._polyline.removeTextContent();
  883. this._endLabel = null;
  884. }
  885. };
  886. LineView.prototype._endLabelOnDuring = function (percent, clipRect, data, animationRecord, valueAnimation, endLabelModel, coordSys) {
  887. var endLabel = this._endLabel;
  888. var polyline = this._polyline;
  889. if (endLabel) {
  890. // NOTE: Don't remove percent < 1. percent === 1 means the first frame during render.
  891. // The label is not prepared at this time.
  892. if (percent < 1 && animationRecord.originalX == null) {
  893. animationRecord.originalX = endLabel.x;
  894. animationRecord.originalY = endLabel.y;
  895. }
  896. var points = data.getLayout('points');
  897. var seriesModel = data.hostModel;
  898. var connectNulls = seriesModel.get('connectNulls');
  899. var precision = endLabelModel.get('precision');
  900. var distance = endLabelModel.get('distance') || 0;
  901. var baseAxis = coordSys.getBaseAxis();
  902. var isHorizontal = baseAxis.isHorizontal();
  903. var isBaseInversed = baseAxis.inverse;
  904. var clipShape = clipRect.shape;
  905. var xOrY = isBaseInversed ? isHorizontal ? clipShape.x : clipShape.y + clipShape.height : isHorizontal ? clipShape.x + clipShape.width : clipShape.y;
  906. var distanceX = (isHorizontal ? distance : 0) * (isBaseInversed ? -1 : 1);
  907. var distanceY = (isHorizontal ? 0 : -distance) * (isBaseInversed ? -1 : 1);
  908. var dim = isHorizontal ? 'x' : 'y';
  909. var dataIndexRange = getIndexRange(points, xOrY, dim);
  910. var indices = dataIndexRange.range;
  911. var diff = indices[1] - indices[0];
  912. var value = void 0;
  913. if (diff >= 1) {
  914. // diff > 1 && connectNulls, which is on the null data.
  915. if (diff > 1 && !connectNulls) {
  916. var pt = getPointAtIndex(points, indices[0]);
  917. endLabel.attr({
  918. x: pt[0] + distanceX,
  919. y: pt[1] + distanceY
  920. });
  921. valueAnimation && (value = seriesModel.getRawValue(indices[0]));
  922. } else {
  923. var pt = polyline.getPointOn(xOrY, dim);
  924. pt && endLabel.attr({
  925. x: pt[0] + distanceX,
  926. y: pt[1] + distanceY
  927. });
  928. var startValue = seriesModel.getRawValue(indices[0]);
  929. var endValue = seriesModel.getRawValue(indices[1]);
  930. valueAnimation && (value = modelUtil.interpolateRawValues(data, precision, startValue, endValue, dataIndexRange.t));
  931. }
  932. animationRecord.lastFrameIndex = indices[0];
  933. } else {
  934. // If diff <= 0, which is the range is not found(Include NaN)
  935. // Choose the first point or last point.
  936. var idx = percent === 1 || animationRecord.lastFrameIndex > 0 ? indices[0] : 0;
  937. var pt = getPointAtIndex(points, idx);
  938. valueAnimation && (value = seriesModel.getRawValue(idx));
  939. endLabel.attr({
  940. x: pt[0] + distanceX,
  941. y: pt[1] + distanceY
  942. });
  943. }
  944. if (valueAnimation) {
  945. var inner = labelInner(endLabel);
  946. if (typeof inner.setLabelText === 'function') {
  947. inner.setLabelText(value);
  948. }
  949. }
  950. }
  951. };
  952. /**
  953. * @private
  954. */
  955. // FIXME Two value axis
  956. LineView.prototype._doUpdateAnimation = function (data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls) {
  957. var polyline = this._polyline;
  958. var polygon = this._polygon;
  959. var seriesModel = data.hostModel;
  960. var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin, valueOrigin);
  961. var current = diff.current;
  962. var stackedOnCurrent = diff.stackedOnCurrent;
  963. var next = diff.next;
  964. var stackedOnNext = diff.stackedOnNext;
  965. if (step) {
  966. // TODO If stacked series is not step
  967. current = turnPointsIntoStep(diff.current, coordSys, step, connectNulls);
  968. stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step, connectNulls);
  969. next = turnPointsIntoStep(diff.next, coordSys, step, connectNulls);
  970. stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step, connectNulls);
  971. } // Don't apply animation if diff is large.
  972. // For better result and avoid memory explosion problems like
  973. // https://github.com/apache/incubator-echarts/issues/12229
  974. if (getBoundingDiff(current, next) > 3000 || polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000) {
  975. polyline.stopAnimation();
  976. polyline.setShape({
  977. points: next
  978. });
  979. if (polygon) {
  980. polygon.stopAnimation();
  981. polygon.setShape({
  982. points: next,
  983. stackedOnPoints: stackedOnNext
  984. });
  985. }
  986. return;
  987. }
  988. polyline.shape.__points = diff.current;
  989. polyline.shape.points = current;
  990. var target = {
  991. shape: {
  992. points: next
  993. }
  994. }; // Also animate the original points.
  995. // If points reference is changed when turning into step line.
  996. if (diff.current !== current) {
  997. target.shape.__points = diff.next;
  998. } // Stop previous animation.
  999. polyline.stopAnimation();
  1000. graphic.updateProps(polyline, target, seriesModel);
  1001. if (polygon) {
  1002. polygon.setShape({
  1003. // Reuse the points with polyline.
  1004. points: current,
  1005. stackedOnPoints: stackedOnCurrent
  1006. });
  1007. polygon.stopAnimation();
  1008. graphic.updateProps(polygon, {
  1009. shape: {
  1010. stackedOnPoints: stackedOnNext
  1011. }
  1012. }, seriesModel); // If use attr directly in updateProps.
  1013. if (polyline.shape.points !== polygon.shape.points) {
  1014. polygon.shape.points = polyline.shape.points;
  1015. }
  1016. }
  1017. var updatedDataInfo = [];
  1018. var diffStatus = diff.status;
  1019. for (var i = 0; i < diffStatus.length; i++) {
  1020. var cmd = diffStatus[i].cmd;
  1021. if (cmd === '=') {
  1022. var el = data.getItemGraphicEl(diffStatus[i].idx1);
  1023. if (el) {
  1024. updatedDataInfo.push({
  1025. el: el,
  1026. ptIdx: i // Index of points
  1027. });
  1028. }
  1029. }
  1030. }
  1031. if (polyline.animators && polyline.animators.length) {
  1032. polyline.animators[0].during(function () {
  1033. polygon && polygon.dirtyShape();
  1034. var points = polyline.shape.__points;
  1035. for (var i = 0; i < updatedDataInfo.length; i++) {
  1036. var el = updatedDataInfo[i].el;
  1037. var offset = updatedDataInfo[i].ptIdx * 2;
  1038. el.x = points[offset];
  1039. el.y = points[offset + 1];
  1040. el.markRedraw();
  1041. }
  1042. });
  1043. }
  1044. };
  1045. LineView.prototype.remove = function (ecModel) {
  1046. var group = this.group;
  1047. var oldData = this._data;
  1048. this._lineGroup.removeAll();
  1049. this._symbolDraw.remove(true); // Remove temporary created elements when highlighting
  1050. oldData && oldData.eachItemGraphicEl(function (el, idx) {
  1051. if (el.__temp) {
  1052. group.remove(el);
  1053. oldData.setItemGraphicEl(idx, null);
  1054. }
  1055. });
  1056. this._polyline = this._polygon = this._coordSys = this._points = this._stackedOnPoints = this._endLabel = this._data = null;
  1057. };
  1058. LineView.type = 'line';
  1059. return LineView;
  1060. }(ChartView);
  1061. export default LineView;