MatrixView.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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. import ComponentView from '../../view/Component.js';
  42. import Model from '../../model/Model.js';
  43. import BoundingRect from 'zrender/lib/core/BoundingRect.js';
  44. import * as vectorUtil from 'zrender/lib/core/vector.js';
  45. import { subPixelOptimize } from 'zrender/lib/graphic/helper/subPixelOptimize.js';
  46. import { Rect, Line, XY, setTooltipConfig, expandOrShrinkRect } from '../../util/graphic.js';
  47. import { clearTmpModel, ListIterator } from '../../util/model.js';
  48. import { clone, retrieve2 } from 'zrender/lib/core/util.js';
  49. import { invert } from 'zrender/lib/core/matrix.js';
  50. import { setLabelStyle } from '../../label/labelStyle.js';
  51. var round = Math.round;
  52. var Z2_BACKGROUND = 0;
  53. var Z2_OUTER_BORDER = 99;
  54. var Z2_BODY_CORNER_CELL_DEFAULT = {
  55. normal: 25,
  56. special: 100
  57. };
  58. var Z2_DIMENSION_CELL_DEFAULT = {
  59. normal: 50,
  60. special: 125
  61. };
  62. var MatrixView = /** @class */function (_super) {
  63. __extends(MatrixView, _super);
  64. function MatrixView() {
  65. var _this = _super !== null && _super.apply(this, arguments) || this;
  66. _this.type = MatrixView.type;
  67. return _this;
  68. }
  69. MatrixView.prototype.render = function (matrixModel, ecModel) {
  70. this.group.removeAll();
  71. var group = this.group;
  72. var coordSys = matrixModel.coordinateSystem;
  73. var rect = coordSys.getRect();
  74. var xDimModel = matrixModel.getDimensionModel('x');
  75. var yDimModel = matrixModel.getDimensionModel('y');
  76. var xDim = xDimModel.dim;
  77. var yDim = yDimModel.dim;
  78. // PENDING:
  79. // reuse the existing text and rect elements for performance?
  80. renderDimensionCells(group, matrixModel, ecModel);
  81. createBodyAndCorner(group, matrixModel, xDim, yDim, ecModel);
  82. var borderZ2Option = matrixModel.getShallow('borderZ2', true);
  83. var outerBorderZ2 = retrieve2(borderZ2Option, Z2_OUTER_BORDER);
  84. var dividerLineZ2 = outerBorderZ2 - 1;
  85. // Outer border and overall background. Use separate elements because of z-order:
  86. // The overall background should appear below any other elements.
  87. // But in most cases, the outer border and the divider line should be above the normal cell borders -
  88. // especially when cell borders have different colors. But users may highlight some specific cells by
  89. // overstirking their border, in which case it should be above the outer border.
  90. var bgStyle = matrixModel.getModel('backgroundStyle').getItemStyle(['borderWidth']);
  91. bgStyle.lineWidth = 0;
  92. var borderStyle = matrixModel.getModel('backgroundStyle').getItemStyle(['color', 'decal', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY']);
  93. borderStyle.fill = 'none';
  94. var bgRect = createMatrixRect(rect.clone(), bgStyle, Z2_BACKGROUND);
  95. var borderRect = createMatrixRect(rect.clone(), borderStyle, outerBorderZ2);
  96. bgRect.silent = true;
  97. borderRect.silent = true;
  98. group.add(bgRect);
  99. group.add(borderRect);
  100. // Header split line.
  101. var xDimCell0 = xDim.getUnitLayoutInfo(0, 0);
  102. var yDimCell0 = yDim.getUnitLayoutInfo(1, 0);
  103. if (xDimCell0 && yDimCell0) {
  104. if (xDim.shouldShow()) {
  105. group.add(createMatrixLine({
  106. x1: rect.x,
  107. y1: yDimCell0.xy,
  108. x2: rect.x + rect.width,
  109. y2: yDimCell0.xy
  110. }, xDimModel.getModel('dividerLineStyle').getLineStyle(), dividerLineZ2));
  111. }
  112. if (yDim.shouldShow()) {
  113. group.add(createMatrixLine({
  114. x1: xDimCell0.xy,
  115. y1: rect.y,
  116. x2: xDimCell0.xy,
  117. y2: rect.y + rect.height
  118. }, yDimModel.getModel('dividerLineStyle').getLineStyle(), dividerLineZ2));
  119. }
  120. }
  121. };
  122. MatrixView.type = 'matrix';
  123. return MatrixView;
  124. }(ComponentView);
  125. function renderDimensionCells(group, matrixModel, ecModel) {
  126. renderOnDimension(0);
  127. renderOnDimension(1);
  128. function renderOnDimension(dimIdx) {
  129. var thisDimModel = matrixModel.getDimensionModel(XY[dimIdx]);
  130. var thisDim = thisDimModel.dim;
  131. if (!thisDim.shouldShow()) {
  132. return;
  133. }
  134. var thisDimBgStyleModel = thisDimModel.getModel('itemStyle');
  135. var thisDimLabelModel = thisDimModel.getModel('label');
  136. var tooltipOption = matrixModel.getShallow('tooltip', true);
  137. var xyLocator = [];
  138. for (var it_1 = thisDim.resetCellIterator(); it_1.next();) {
  139. var dimCell = it_1.item;
  140. var shape = {};
  141. BoundingRect.copy(shape, dimCell.rect);
  142. vectorUtil.set(xyLocator, dimCell.id.x, dimCell.id.y);
  143. createMatrixCell(xyLocator, matrixModel, group, ecModel, dimCell.option, thisDimBgStyleModel, thisDimLabelModel, thisDimModel, shape, dimCell.option.value, Z2_DIMENSION_CELL_DEFAULT, tooltipOption);
  144. }
  145. }
  146. }
  147. function createBodyAndCorner(group, matrixModel, xDim, yDim, ecModel) {
  148. createBodyOrCornerCells('body', matrixModel.getBody(), xDim, yDim);
  149. if (xDim.shouldShow() && yDim.shouldShow()) {
  150. createBodyOrCornerCells('corner', matrixModel.getCorner(), yDim, xDim);
  151. }
  152. function createBodyOrCornerCells(bodyCornerOptionRoot, bodyOrCorner, dimForCoordX,
  153. // Can be `matrix.y` (transposed) for corners.
  154. dimForCoordY) {
  155. // Prevent inheriting from ancestor.
  156. var parentCellModel = new Model(matrixModel.getShallow(bodyCornerOptionRoot, true));
  157. var parentItemStyleModel = parentCellModel.getModel('itemStyle');
  158. var parentLabelModel = parentCellModel.getModel('label');
  159. var itx = new ListIterator();
  160. var ity = new ListIterator();
  161. var xyLocator = [];
  162. var tooltipOption = matrixModel.getShallow('tooltip', true);
  163. for (dimForCoordY.resetLayoutIterator(ity, 1); ity.next();) {
  164. for (dimForCoordX.resetLayoutIterator(itx, 0); itx.next();) {
  165. var xLayout = itx.item;
  166. var yLayout = ity.item;
  167. vectorUtil.set(xyLocator, xLayout.id.x, yLayout.id.y);
  168. var bodyCornerCell = bodyOrCorner.getCell(xyLocator);
  169. // If in span of an other body or corner cell, never render it.
  170. if (bodyCornerCell && bodyCornerCell.inSpanOf && bodyCornerCell.inSpanOf !== bodyCornerCell) {
  171. continue;
  172. }
  173. var shape = {};
  174. if (bodyCornerCell && bodyCornerCell.span) {
  175. BoundingRect.copy(shape, bodyCornerCell.spanRect);
  176. } else {
  177. xLayout.dim.getLayout(shape, 0, xyLocator[0]);
  178. yLayout.dim.getLayout(shape, 1, xyLocator[1]);
  179. }
  180. var bodyCornerCellOption = bodyCornerCell ? bodyCornerCell.option : null;
  181. createMatrixCell(xyLocator, matrixModel, group, ecModel, bodyCornerCellOption, parentItemStyleModel, parentLabelModel, parentCellModel, shape, bodyCornerCellOption ? bodyCornerCellOption.value : null, Z2_BODY_CORNER_CELL_DEFAULT, tooltipOption);
  182. }
  183. }
  184. } // End of createBodyOrCornerCells
  185. }
  186. function createMatrixCell(xyLocator, matrixModel, group, ecModel, cellOption, parentItemStyleModel, parentLabelModel, parentCellModel, shape, textValue, zrCellDefault, tooltipOption) {
  187. var _a;
  188. // Do not use getModel for handy performance optimization.
  189. _tmpCellItemStyleModel.option = cellOption ? cellOption.itemStyle : null;
  190. _tmpCellItemStyleModel.parentModel = parentItemStyleModel;
  191. _tmpCellModel.option = cellOption;
  192. _tmpCellModel.parentModel = parentCellModel;
  193. // Use different z2 because special border may be defined in itemStyle.
  194. var z2 = retrieve2(_tmpCellModel.getShallow('z2'), cellOption && cellOption.itemStyle ? zrCellDefault.special : zrCellDefault.normal);
  195. var tooltipOptionShow = tooltipOption && tooltipOption.show;
  196. var cellRect = createMatrixRect(shape, _tmpCellItemStyleModel.getItemStyle(), z2);
  197. group.add(cellRect);
  198. var cursorOption = _tmpCellModel.get('cursor');
  199. if (cursorOption != null) {
  200. cellRect.attr('cursor', cursorOption);
  201. }
  202. var cellText;
  203. if (textValue != null) {
  204. var text = textValue + '';
  205. _tmpCellLabelModel.option = cellOption ? cellOption.label : null;
  206. _tmpCellLabelModel.parentModel = parentLabelModel;
  207. // This is to accept `option.textStyle` as the default.
  208. _tmpCellLabelModel.ecModel = ecModel;
  209. setLabelStyle(cellRect,
  210. // Currently do not support other states (`emphasis`, `select`, `blur`)
  211. {
  212. normal: _tmpCellLabelModel
  213. }, {
  214. defaultText: text,
  215. autoOverflowArea: true,
  216. // By default based on boundingRect. But boundingRect contains borderWidth,
  217. // and borderWidth is half outside the cell. Thus specific `layoutRect` explicitly.
  218. layoutRect: clone(cellRect.shape)
  219. });
  220. cellText = cellRect.getTextContent();
  221. if (cellText) {
  222. cellText.z2 = z2 + 1;
  223. var style = cellText.style;
  224. if (style && style.overflow && style.overflow !== 'none' && style.lineOverflow) {
  225. // `overflow: 'break'/'breakAll'/'truncate'` does not guarantee prevention of overflow
  226. // when space is insufficient. Use a `clipPath` in such case.
  227. var clipShape = {};
  228. BoundingRect.copy(clipShape, shape);
  229. // `lineWidth` is half outside half inside the bounding rect.
  230. expandOrShrinkRect(clipShape, (((_a = cellRect.style) === null || _a === void 0 ? void 0 : _a.lineWidth) || 0) / 2, true, true);
  231. cellRect.updateInnerText();
  232. cellText.getLocalTransform(_tmpInnerTextTrans);
  233. invert(_tmpInnerTextTrans, _tmpInnerTextTrans);
  234. BoundingRect.applyTransform(clipShape, clipShape, _tmpInnerTextTrans);
  235. cellText.setClipPath(new Rect({
  236. shape: clipShape
  237. }));
  238. }
  239. }
  240. setTooltipConfig({
  241. el: cellRect,
  242. componentModel: matrixModel,
  243. itemName: text,
  244. itemTooltipOption: tooltipOption,
  245. formatterParamsExtra: {
  246. xyLocator: xyLocator.slice()
  247. }
  248. });
  249. }
  250. // Set silent
  251. if (cellText) {
  252. var labelSilent = _tmpCellLabelModel.get('silent');
  253. // auto, tooltip of text cells need silient: false, but non-text cells
  254. // do not need a special cursor in most cases.
  255. if (labelSilent == null) {
  256. labelSilent = !tooltipOptionShow;
  257. }
  258. cellText.silent = labelSilent;
  259. cellText.ignoreHostSilent = true;
  260. }
  261. var rectSilent = _tmpCellModel.get('silent');
  262. if (rectSilent == null) {
  263. rectSilent =
  264. // If no background color in cell, set `rect.silent: false` will cause that only
  265. // the border response to mouse hovering, which is probably weird.
  266. !cellRect.style || cellRect.style.fill === 'none' || !cellRect.style.fill;
  267. }
  268. cellRect.silent = rectSilent;
  269. clearTmpModel(_tmpCellModel);
  270. clearTmpModel(_tmpCellItemStyleModel);
  271. clearTmpModel(_tmpCellLabelModel);
  272. }
  273. var _tmpCellModel = new Model();
  274. var _tmpCellItemStyleModel = new Model();
  275. var _tmpCellLabelModel = new Model();
  276. var _tmpInnerTextTrans = [];
  277. // FIXME: move all of the subpixel process to Matrix.ts resize, otherwise the result of
  278. // `dataToLayout` is not consistent with this rendering, and the caller (like heatmap) can
  279. // not precisely align with the matrix border.
  280. function createMatrixRect(shape, style, z2) {
  281. // Currently `subPixelOptimizeRect` can not be used here because it will break rect alignment.
  282. // Optimize line and rect with the same direction.
  283. var lineWidth = style.lineWidth;
  284. if (lineWidth) {
  285. var x2Original = shape.x + shape.width;
  286. var y2Original = shape.y + shape.height;
  287. shape.x = subPixelOptimize(shape.x, lineWidth, true);
  288. shape.y = subPixelOptimize(shape.y, lineWidth, true);
  289. shape.width = subPixelOptimize(x2Original, lineWidth, true) - shape.x;
  290. shape.height = subPixelOptimize(y2Original, lineWidth, true) - shape.y;
  291. }
  292. return new Rect({
  293. shape: shape,
  294. style: style,
  295. z2: z2
  296. });
  297. }
  298. function createMatrixLine(shape, style, z2) {
  299. var lineWidth = style.lineWidth;
  300. if (lineWidth) {
  301. if (round(shape.x1 * 2) === round(shape.x2 * 2)) {
  302. shape.x1 = shape.x2 = subPixelOptimize(shape.x1, lineWidth, true);
  303. }
  304. if (round(shape.y1 * 2) === round(shape.y2 * 2)) {
  305. shape.y1 = shape.y2 = subPixelOptimize(shape.y1, lineWidth, true);
  306. }
  307. }
  308. return new Line({
  309. shape: shape,
  310. style: style,
  311. silent: true,
  312. z2: z2
  313. });
  314. }
  315. export default MatrixView;