MarkAreaView.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376
  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"; // TODO Optimize on polar
  41. import * as colorUtil from 'zrender/lib/tool/color.js';
  42. import SeriesData from '../../data/SeriesData.js';
  43. import * as numberUtil from '../../util/number.js';
  44. import * as graphic from '../../util/graphic.js';
  45. import { toggleHoverEmphasis, setStatesStylesFromModel } from '../../util/states.js';
  46. import * as markerHelper from './markerHelper.js';
  47. import MarkerView from './MarkerView.js';
  48. import { retrieve, mergeAll, map, curry, filter, extend, isString } from 'zrender/lib/core/util.js';
  49. import { isCoordinateSystemType } from '../../coord/CoordinateSystem.js';
  50. import MarkerModel from './MarkerModel.js';
  51. import { makeInner } from '../../util/model.js';
  52. import { getVisualFromData } from '../../visual/helper.js';
  53. import { setLabelStyle, getLabelStatesModels } from '../../label/labelStyle.js';
  54. import { getECData } from '../../util/innerStore.js';
  55. import { parseDataValue } from '../../data/helper/dataValueHelper.js';
  56. var inner = makeInner();
  57. var markAreaTransform = function (seriesModel, coordSys, maModel, item) {
  58. var lt = markerHelper.dataTransform(seriesModel, item[0]);
  59. var rb = markerHelper.dataTransform(seriesModel, item[1]); // FIXME make sure lt is less than rb
  60. var ltCoord = lt.coord;
  61. var rbCoord = rb.coord;
  62. ltCoord[0] = retrieve(ltCoord[0], -Infinity);
  63. ltCoord[1] = retrieve(ltCoord[1], -Infinity);
  64. rbCoord[0] = retrieve(rbCoord[0], Infinity);
  65. rbCoord[1] = retrieve(rbCoord[1], Infinity); // Merge option into one
  66. var result = mergeAll([{}, lt, rb]);
  67. result.coord = [lt.coord, rb.coord];
  68. result.x0 = lt.x;
  69. result.y0 = lt.y;
  70. result.x1 = rb.x;
  71. result.y1 = rb.y;
  72. return result;
  73. };
  74. function isInfinity(val) {
  75. return !isNaN(val) && !isFinite(val);
  76. } // If a markArea has one dim
  77. function ifMarkAreaHasOnlyDim(dimIndex, fromCoord, toCoord, coordSys) {
  78. var otherDimIndex = 1 - dimIndex;
  79. return isInfinity(fromCoord[otherDimIndex]) && isInfinity(toCoord[otherDimIndex]);
  80. }
  81. function markAreaFilter(coordSys, item) {
  82. var fromCoord = item.coord[0];
  83. var toCoord = item.coord[1];
  84. var item0 = {
  85. coord: fromCoord,
  86. x: item.x0,
  87. y: item.y0
  88. };
  89. var item1 = {
  90. coord: toCoord,
  91. x: item.x1,
  92. y: item.y1
  93. };
  94. if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
  95. // In case
  96. // {
  97. // markArea: {
  98. // data: [{ yAxis: 2 }]
  99. // }
  100. // }
  101. if (fromCoord && toCoord && (ifMarkAreaHasOnlyDim(1, fromCoord, toCoord, coordSys) || ifMarkAreaHasOnlyDim(0, fromCoord, toCoord, coordSys))) {
  102. return true;
  103. } //Directly returning true may also do the work,
  104. //because markArea will not be shown automatically
  105. //when it's not included in coordinate system.
  106. //But filtering ahead can avoid keeping rendering markArea
  107. //when there are too many of them.
  108. return markerHelper.zoneFilter(coordSys, item0, item1);
  109. }
  110. return markerHelper.dataFilter(coordSys, item0) || markerHelper.dataFilter(coordSys, item1);
  111. } // dims can be ['x0', 'y0'], ['x1', 'y1'], ['x0', 'y1'], ['x1', 'y0']
  112. function getSingleMarkerEndPoint(data, idx, dims, seriesModel, api) {
  113. var coordSys = seriesModel.coordinateSystem;
  114. var itemModel = data.getItemModel(idx);
  115. var point;
  116. var xPx = numberUtil.parsePercent(itemModel.get(dims[0]), api.getWidth());
  117. var yPx = numberUtil.parsePercent(itemModel.get(dims[1]), api.getHeight());
  118. if (!isNaN(xPx) && !isNaN(yPx)) {
  119. point = [xPx, yPx];
  120. } else {
  121. // Chart like bar may have there own marker positioning logic
  122. if (seriesModel.getMarkerPosition) {
  123. // Use the getMarkerPosition
  124. point = seriesModel.getMarkerPosition(data.getValues(dims, idx));
  125. } else {
  126. var x = data.get(dims[0], idx);
  127. var y = data.get(dims[1], idx);
  128. var pt = [x, y];
  129. coordSys.clampData && coordSys.clampData(pt, pt);
  130. point = coordSys.dataToPoint(pt, true);
  131. }
  132. if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
  133. // TODO: TYPE ts@4.1 may still infer it as Axis instead of Axis2D. Not sure if it's a bug
  134. var xAxis = coordSys.getAxis('x');
  135. var yAxis = coordSys.getAxis('y');
  136. var x = data.get(dims[0], idx);
  137. var y = data.get(dims[1], idx);
  138. if (isInfinity(x)) {
  139. point[0] = xAxis.toGlobalCoord(xAxis.getExtent()[dims[0] === 'x0' ? 0 : 1]);
  140. } else if (isInfinity(y)) {
  141. point[1] = yAxis.toGlobalCoord(yAxis.getExtent()[dims[1] === 'y0' ? 0 : 1]);
  142. }
  143. } // Use x, y if has any
  144. if (!isNaN(xPx)) {
  145. point[0] = xPx;
  146. }
  147. if (!isNaN(yPx)) {
  148. point[1] = yPx;
  149. }
  150. }
  151. return point;
  152. }
  153. var dimPermutations = [['x0', 'y0'], ['x1', 'y0'], ['x1', 'y1'], ['x0', 'y1']];
  154. var MarkAreaView =
  155. /** @class */
  156. function (_super) {
  157. __extends(MarkAreaView, _super);
  158. function MarkAreaView() {
  159. var _this = _super !== null && _super.apply(this, arguments) || this;
  160. _this.type = MarkAreaView.type;
  161. return _this;
  162. }
  163. MarkAreaView.prototype.updateTransform = function (markAreaModel, ecModel, api) {
  164. ecModel.eachSeries(function (seriesModel) {
  165. var maModel = MarkerModel.getMarkerModelFromSeries(seriesModel, 'markArea');
  166. if (maModel) {
  167. var areaData_1 = maModel.getData();
  168. areaData_1.each(function (idx) {
  169. var points = map(dimPermutations, function (dim) {
  170. return getSingleMarkerEndPoint(areaData_1, idx, dim, seriesModel, api);
  171. }); // Layout
  172. areaData_1.setItemLayout(idx, points);
  173. var el = areaData_1.getItemGraphicEl(idx);
  174. el.setShape('points', points);
  175. });
  176. }
  177. }, this);
  178. };
  179. MarkAreaView.prototype.renderSeries = function (seriesModel, maModel, ecModel, api) {
  180. var coordSys = seriesModel.coordinateSystem;
  181. var seriesId = seriesModel.id;
  182. var seriesData = seriesModel.getData();
  183. var areaGroupMap = this.markerGroupMap;
  184. var polygonGroup = areaGroupMap.get(seriesId) || areaGroupMap.set(seriesId, {
  185. group: new graphic.Group()
  186. });
  187. this.group.add(polygonGroup.group);
  188. this.markKeep(polygonGroup);
  189. var areaData = createList(coordSys, seriesModel, maModel); // Line data for tooltip and formatter
  190. maModel.setData(areaData); // Update visual and layout of line
  191. areaData.each(function (idx) {
  192. // Layout
  193. var points = map(dimPermutations, function (dim) {
  194. return getSingleMarkerEndPoint(areaData, idx, dim, seriesModel, api);
  195. });
  196. var xAxisScale = coordSys.getAxis('x').scale;
  197. var yAxisScale = coordSys.getAxis('y').scale;
  198. var xAxisExtent = xAxisScale.getExtent();
  199. var yAxisExtent = yAxisScale.getExtent();
  200. var xPointExtent = [xAxisScale.parse(areaData.get('x0', idx)), xAxisScale.parse(areaData.get('x1', idx))];
  201. var yPointExtent = [yAxisScale.parse(areaData.get('y0', idx)), yAxisScale.parse(areaData.get('y1', idx))];
  202. numberUtil.asc(xPointExtent);
  203. numberUtil.asc(yPointExtent);
  204. var overlapped = !(xAxisExtent[0] > xPointExtent[1] || xAxisExtent[1] < xPointExtent[0] || yAxisExtent[0] > yPointExtent[1] || yAxisExtent[1] < yPointExtent[0]); // If none of the area is inside coordSys, allClipped is set to be true
  205. // in layout so that label will not be displayed. See #12591
  206. var allClipped = !overlapped;
  207. areaData.setItemLayout(idx, {
  208. points: points,
  209. allClipped: allClipped
  210. });
  211. var style = areaData.getItemModel(idx).getModel('itemStyle').getItemStyle();
  212. var color = getVisualFromData(seriesData, 'color');
  213. if (!style.fill) {
  214. style.fill = color;
  215. if (isString(style.fill)) {
  216. style.fill = colorUtil.modifyAlpha(style.fill, 0.4);
  217. }
  218. }
  219. if (!style.stroke) {
  220. style.stroke = color;
  221. } // Visual
  222. areaData.setItemVisual(idx, 'style', style);
  223. });
  224. areaData.diff(inner(polygonGroup).data).add(function (idx) {
  225. var layout = areaData.getItemLayout(idx);
  226. if (!layout.allClipped) {
  227. var polygon = new graphic.Polygon({
  228. shape: {
  229. points: layout.points
  230. }
  231. });
  232. areaData.setItemGraphicEl(idx, polygon);
  233. polygonGroup.group.add(polygon);
  234. }
  235. }).update(function (newIdx, oldIdx) {
  236. var polygon = inner(polygonGroup).data.getItemGraphicEl(oldIdx);
  237. var layout = areaData.getItemLayout(newIdx);
  238. if (!layout.allClipped) {
  239. if (polygon) {
  240. graphic.updateProps(polygon, {
  241. shape: {
  242. points: layout.points
  243. }
  244. }, maModel, newIdx);
  245. } else {
  246. polygon = new graphic.Polygon({
  247. shape: {
  248. points: layout.points
  249. }
  250. });
  251. }
  252. areaData.setItemGraphicEl(newIdx, polygon);
  253. polygonGroup.group.add(polygon);
  254. } else if (polygon) {
  255. polygonGroup.group.remove(polygon);
  256. }
  257. }).remove(function (idx) {
  258. var polygon = inner(polygonGroup).data.getItemGraphicEl(idx);
  259. polygonGroup.group.remove(polygon);
  260. }).execute();
  261. areaData.eachItemGraphicEl(function (polygon, idx) {
  262. var itemModel = areaData.getItemModel(idx);
  263. var style = areaData.getItemVisual(idx, 'style');
  264. polygon.useStyle(areaData.getItemVisual(idx, 'style'));
  265. setLabelStyle(polygon, getLabelStatesModels(itemModel), {
  266. labelFetcher: maModel,
  267. labelDataIndex: idx,
  268. defaultText: areaData.getName(idx) || '',
  269. inheritColor: isString(style.fill) ? colorUtil.modifyAlpha(style.fill, 1) : '#000'
  270. });
  271. setStatesStylesFromModel(polygon, itemModel);
  272. toggleHoverEmphasis(polygon, null, null, itemModel.get(['emphasis', 'disabled']));
  273. getECData(polygon).dataModel = maModel;
  274. });
  275. inner(polygonGroup).data = areaData;
  276. polygonGroup.group.silent = maModel.get('silent') || seriesModel.get('silent');
  277. };
  278. MarkAreaView.type = 'markArea';
  279. return MarkAreaView;
  280. }(MarkerView);
  281. function createList(coordSys, seriesModel, maModel) {
  282. var areaData;
  283. var dataDims;
  284. var dims = ['x0', 'y0', 'x1', 'y1'];
  285. if (coordSys) {
  286. var coordDimsInfos_1 = map(coordSys && coordSys.dimensions, function (coordDim) {
  287. var data = seriesModel.getData();
  288. var info = data.getDimensionInfo(data.mapDimension(coordDim)) || {}; // In map series data don't have lng and lat dimension. Fallback to same with coordSys
  289. return extend(extend({}, info), {
  290. name: coordDim,
  291. // DON'T use ordinalMeta to parse and collect ordinal.
  292. ordinalMeta: null
  293. });
  294. });
  295. dataDims = map(dims, function (dim, idx) {
  296. return {
  297. name: dim,
  298. type: coordDimsInfos_1[idx % 2].type
  299. };
  300. });
  301. areaData = new SeriesData(dataDims, maModel);
  302. } else {
  303. dataDims = [{
  304. name: 'value',
  305. type: 'float'
  306. }];
  307. areaData = new SeriesData(dataDims, maModel);
  308. }
  309. var optData = map(maModel.get('data'), curry(markAreaTransform, seriesModel, coordSys, maModel));
  310. if (coordSys) {
  311. optData = filter(optData, curry(markAreaFilter, coordSys));
  312. }
  313. var dimValueGetter = coordSys ? function (item, dimName, dataIndex, dimIndex) {
  314. // TODO should convert to ParsedValue?
  315. var rawVal = item.coord[Math.floor(dimIndex / 2)][dimIndex % 2];
  316. return parseDataValue(rawVal, dataDims[dimIndex]);
  317. } : function (item, dimName, dataIndex, dimIndex) {
  318. return parseDataValue(item.value, dataDims[dimIndex]);
  319. };
  320. areaData.initData(optData, null, dimValueGetter);
  321. areaData.hasItemOption = true;
  322. return areaData;
  323. }
  324. export default MarkAreaView;