LineView.js 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284
  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 mose 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 = seriesModel.get('animation');
  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 triggerred 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: should't draw symbol outside clipShapeForSymbol
  679. if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
  680. return;
  681. }
  682. var zlevel = seriesModel.get('zlevel');
  683. var z = seriesModel.get('z');
  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 seriesDalay = seriesModel.get('animationDelay') || 0;
  781. var seriesDalayValue = zrUtil.isFunction(seriesDalay) ? seriesDalay(null) : seriesDalay;
  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(seriesDalay) ? seriesDalay(idx) : seriesDuration * ratio + seriesDalayValue;
  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. labelInner(endLabel).setLabelText(value);
  946. }
  947. }
  948. };
  949. /**
  950. * @private
  951. */
  952. // FIXME Two value axis
  953. LineView.prototype._doUpdateAnimation = function (data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls) {
  954. var polyline = this._polyline;
  955. var polygon = this._polygon;
  956. var seriesModel = data.hostModel;
  957. var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin, valueOrigin);
  958. var current = diff.current;
  959. var stackedOnCurrent = diff.stackedOnCurrent;
  960. var next = diff.next;
  961. var stackedOnNext = diff.stackedOnNext;
  962. if (step) {
  963. // TODO If stacked series is not step
  964. current = turnPointsIntoStep(diff.current, coordSys, step, connectNulls);
  965. stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step, connectNulls);
  966. next = turnPointsIntoStep(diff.next, coordSys, step, connectNulls);
  967. stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step, connectNulls);
  968. } // Don't apply animation if diff is large.
  969. // For better result and avoid memory explosion problems like
  970. // https://github.com/apache/incubator-echarts/issues/12229
  971. if (getBoundingDiff(current, next) > 3000 || polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000) {
  972. polyline.stopAnimation();
  973. polyline.setShape({
  974. points: next
  975. });
  976. if (polygon) {
  977. polygon.stopAnimation();
  978. polygon.setShape({
  979. points: next,
  980. stackedOnPoints: stackedOnNext
  981. });
  982. }
  983. return;
  984. }
  985. polyline.shape.__points = diff.current;
  986. polyline.shape.points = current;
  987. var target = {
  988. shape: {
  989. points: next
  990. }
  991. }; // Also animate the original points.
  992. // If points reference is changed when turning into step line.
  993. if (diff.current !== current) {
  994. target.shape.__points = diff.next;
  995. } // Stop previous animation.
  996. polyline.stopAnimation();
  997. graphic.updateProps(polyline, target, seriesModel);
  998. if (polygon) {
  999. polygon.setShape({
  1000. // Reuse the points with polyline.
  1001. points: current,
  1002. stackedOnPoints: stackedOnCurrent
  1003. });
  1004. polygon.stopAnimation();
  1005. graphic.updateProps(polygon, {
  1006. shape: {
  1007. stackedOnPoints: stackedOnNext
  1008. }
  1009. }, seriesModel); // If use attr directly in updateProps.
  1010. if (polyline.shape.points !== polygon.shape.points) {
  1011. polygon.shape.points = polyline.shape.points;
  1012. }
  1013. }
  1014. var updatedDataInfo = [];
  1015. var diffStatus = diff.status;
  1016. for (var i = 0; i < diffStatus.length; i++) {
  1017. var cmd = diffStatus[i].cmd;
  1018. if (cmd === '=') {
  1019. var el = data.getItemGraphicEl(diffStatus[i].idx1);
  1020. if (el) {
  1021. updatedDataInfo.push({
  1022. el: el,
  1023. ptIdx: i // Index of points
  1024. });
  1025. }
  1026. }
  1027. }
  1028. if (polyline.animators && polyline.animators.length) {
  1029. polyline.animators[0].during(function () {
  1030. polygon && polygon.dirtyShape();
  1031. var points = polyline.shape.__points;
  1032. for (var i = 0; i < updatedDataInfo.length; i++) {
  1033. var el = updatedDataInfo[i].el;
  1034. var offset = updatedDataInfo[i].ptIdx * 2;
  1035. el.x = points[offset];
  1036. el.y = points[offset + 1];
  1037. el.markRedraw();
  1038. }
  1039. });
  1040. }
  1041. };
  1042. LineView.prototype.remove = function (ecModel) {
  1043. var group = this.group;
  1044. var oldData = this._data;
  1045. this._lineGroup.removeAll();
  1046. this._symbolDraw.remove(true); // Remove temporary created elements when highlighting
  1047. oldData && oldData.eachItemGraphicEl(function (el, idx) {
  1048. if (el.__temp) {
  1049. group.remove(el);
  1050. oldData.setItemGraphicEl(idx, null);
  1051. }
  1052. });
  1053. this._polyline = this._polygon = this._coordSys = this._points = this._stackedOnPoints = this._endLabel = this._data = null;
  1054. };
  1055. LineView.type = 'line';
  1056. return LineView;
  1057. }(ChartView);
  1058. export default LineView;