LineView.js 40 KB

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