tilemap.src.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /* *
  2. * Tilemaps module
  3. *
  4. * (c) 2010-2017 Highsoft AS
  5. * Author: Øystein Moseng
  6. *
  7. * License: www.highcharts.com/license
  8. */
  9. 'use strict';
  10. import H from '../parts/Globals.js';
  11. import '../parts-map/HeatmapSeries.js';
  12. var seriesType = H.seriesType,
  13. pick = H.pick,
  14. // Utility func to get the middle number of 3
  15. between = function (x, a, b) {
  16. return Math.min(Math.max(a, x), b);
  17. },
  18. // Utility func to get padding definition from tile size division
  19. tilePaddingFromTileSize = function (series, xDiv, yDiv) {
  20. var options = series.options;
  21. return {
  22. xPad: (options.colsize || 1) / -xDiv,
  23. yPad: (options.rowsize || 1) / -yDiv
  24. };
  25. };
  26. // Map of shape types.
  27. H.tileShapeTypes = {
  28. // Hexagon shape type.
  29. hexagon: {
  30. alignDataLabel: H.seriesTypes.scatter.prototype.alignDataLabel,
  31. getSeriesPadding: function (series) {
  32. return tilePaddingFromTileSize(series, 3, 2);
  33. },
  34. haloPath: function (size) {
  35. if (!size) {
  36. return [];
  37. }
  38. var hexagon = this.tileEdges;
  39. return [
  40. 'M', hexagon.x2 - size, hexagon.y1 + size,
  41. 'L', hexagon.x3 + size, hexagon.y1 + size,
  42. hexagon.x4 + size * 1.5, hexagon.y2,
  43. hexagon.x3 + size, hexagon.y3 - size,
  44. hexagon.x2 - size, hexagon.y3 - size,
  45. hexagon.x1 - size * 1.5, hexagon.y2,
  46. 'Z'
  47. ];
  48. },
  49. translate: function () {
  50. var series = this,
  51. options = series.options,
  52. xAxis = series.xAxis,
  53. yAxis = series.yAxis,
  54. seriesPointPadding = options.pointPadding || 0,
  55. xPad = (options.colsize || 1) / 3,
  56. yPad = (options.rowsize || 1) / 2,
  57. yShift;
  58. series.generatePoints();
  59. series.points.forEach(function (point) {
  60. var x1 = between(
  61. Math.floor(
  62. xAxis.len -
  63. xAxis.translate(point.x - xPad * 2, 0, 1, 0, 1)
  64. ), -xAxis.len, 2 * xAxis.len
  65. ),
  66. x2 = between(
  67. Math.floor(
  68. xAxis.len -
  69. xAxis.translate(point.x - xPad, 0, 1, 0, 1)
  70. ), -xAxis.len, 2 * xAxis.len
  71. ),
  72. x3 = between(
  73. Math.floor(
  74. xAxis.len -
  75. xAxis.translate(point.x + xPad, 0, 1, 0, 1)
  76. ), -xAxis.len, 2 * xAxis.len
  77. ),
  78. x4 = between(
  79. Math.floor(
  80. xAxis.len -
  81. xAxis.translate(point.x + xPad * 2, 0, 1, 0, 1)
  82. ), -xAxis.len, 2 * xAxis.len
  83. ),
  84. y1 = between(
  85. Math.floor(yAxis.translate(point.y - yPad, 0, 1, 0, 1)),
  86. -yAxis.len,
  87. 2 * yAxis.len
  88. ),
  89. y2 = between(
  90. Math.floor(yAxis.translate(point.y, 0, 1, 0, 1)),
  91. -yAxis.len,
  92. 2 * yAxis.len
  93. ),
  94. y3 = between(
  95. Math.floor(yAxis.translate(point.y + yPad, 0, 1, 0, 1)),
  96. -yAxis.len,
  97. 2 * yAxis.len
  98. ),
  99. pointPadding = pick(point.pointPadding, seriesPointPadding),
  100. // We calculate the point padding of the midpoints to
  101. // preserve the angles of the shape.
  102. midPointPadding = pointPadding *
  103. Math.abs(x2 - x1) / Math.abs(y3 - y2),
  104. xMidPadding = xAxis.reversed ?
  105. -midPointPadding : midPointPadding,
  106. xPointPadding = xAxis.reversed ?
  107. -pointPadding : pointPadding,
  108. yPointPadding = yAxis.reversed ?
  109. -pointPadding : pointPadding;
  110. // Shift y-values for every second grid column
  111. if (point.x % 2) {
  112. yShift = yShift || Math.round(Math.abs(y3 - y1) / 2) *
  113. // We have to reverse the shift for reversed y-axes
  114. (yAxis.reversed ? -1 : 1);
  115. y1 += yShift;
  116. y2 += yShift;
  117. y3 += yShift;
  118. }
  119. // Set plotX and plotY for use in K-D-Tree and more
  120. point.plotX = point.clientX = (x2 + x3) / 2;
  121. point.plotY = y2;
  122. // Apply point padding to translated coordinates
  123. x1 += xMidPadding + xPointPadding;
  124. x2 += xPointPadding;
  125. x3 -= xPointPadding;
  126. x4 -= xMidPadding + xPointPadding;
  127. y1 -= yPointPadding;
  128. y3 += yPointPadding;
  129. // Store points for halo creation
  130. point.tileEdges = {
  131. x1: x1, x2: x2, x3: x3, x4: x4, y1: y1, y2: y2, y3: y3
  132. };
  133. // Finally set the shape for this point
  134. point.shapeType = 'path';
  135. point.shapeArgs = {
  136. d: [
  137. 'M', x2, y1,
  138. 'L', x3, y1,
  139. x4, y2,
  140. x3, y3,
  141. x2, y3,
  142. x1, y2,
  143. 'Z'
  144. ]
  145. };
  146. });
  147. series.translateColors();
  148. }
  149. },
  150. // Diamond shape type.
  151. diamond: {
  152. alignDataLabel: H.seriesTypes.scatter.prototype.alignDataLabel,
  153. getSeriesPadding: function (series) {
  154. return tilePaddingFromTileSize(series, 2, 2);
  155. },
  156. haloPath: function (size) {
  157. if (!size) {
  158. return [];
  159. }
  160. var diamond = this.tileEdges;
  161. return [
  162. 'M', diamond.x2, diamond.y1 + size,
  163. 'L', diamond.x3 + size, diamond.y2,
  164. diamond.x2, diamond.y3 - size,
  165. diamond.x1 - size, diamond.y2,
  166. 'Z'
  167. ];
  168. },
  169. translate: function () {
  170. var series = this,
  171. options = series.options,
  172. xAxis = series.xAxis,
  173. yAxis = series.yAxis,
  174. seriesPointPadding = options.pointPadding || 0,
  175. xPad = (options.colsize || 1),
  176. yPad = (options.rowsize || 1) / 2,
  177. yShift;
  178. series.generatePoints();
  179. series.points.forEach(function (point) {
  180. var x1 = between(
  181. Math.round(
  182. xAxis.len -
  183. xAxis.translate(point.x - xPad, 0, 1, 0, 0)
  184. ), -xAxis.len, 2 * xAxis.len
  185. ),
  186. x2 = between(
  187. Math.round(
  188. xAxis.len -
  189. xAxis.translate(point.x, 0, 1, 0, 0)
  190. ), -xAxis.len, 2 * xAxis.len
  191. ),
  192. x3 = between(
  193. Math.round(
  194. xAxis.len -
  195. xAxis.translate(point.x + xPad, 0, 1, 0, 0)
  196. ), -xAxis.len, 2 * xAxis.len
  197. ),
  198. y1 = between(
  199. Math.round(yAxis.translate(point.y - yPad, 0, 1, 0, 0)),
  200. -yAxis.len,
  201. 2 * yAxis.len
  202. ),
  203. y2 = between(
  204. Math.round(yAxis.translate(point.y, 0, 1, 0, 0)),
  205. -yAxis.len,
  206. 2 * yAxis.len
  207. ),
  208. y3 = between(
  209. Math.round(yAxis.translate(point.y + yPad, 0, 1, 0, 0)),
  210. -yAxis.len,
  211. 2 * yAxis.len
  212. ),
  213. pointPadding = pick(point.pointPadding, seriesPointPadding),
  214. // We calculate the point padding of the midpoints to
  215. // preserve the angles of the shape.
  216. midPointPadding = pointPadding *
  217. Math.abs(x2 - x1) / Math.abs(y3 - y2),
  218. xPointPadding = xAxis.reversed ?
  219. -midPointPadding : midPointPadding,
  220. yPointPadding = yAxis.reversed ?
  221. -pointPadding : pointPadding;
  222. // Shift y-values for every second grid column
  223. // We have to reverse the shift for reversed y-axes
  224. if (point.x % 2) {
  225. yShift = Math.abs(y3 - y1) / 2 * (yAxis.reversed ? -1 : 1);
  226. y1 += yShift;
  227. y2 += yShift;
  228. y3 += yShift;
  229. }
  230. // Set plotX and plotY for use in K-D-Tree and more
  231. point.plotX = point.clientX = x2;
  232. point.plotY = y2;
  233. // Apply point padding to translated coordinates
  234. x1 += xPointPadding;
  235. x3 -= xPointPadding;
  236. y1 -= yPointPadding;
  237. y3 += yPointPadding;
  238. // Store points for halo creation
  239. point.tileEdges = {
  240. x1: x1, x2: x2, x3: x3, y1: y1, y2: y2, y3: y3
  241. };
  242. // Set this point's shape parameters
  243. point.shapeType = 'path';
  244. point.shapeArgs = {
  245. d: [
  246. 'M', x2, y1,
  247. 'L', x3, y2,
  248. x2, y3,
  249. x1, y2,
  250. 'Z'
  251. ]
  252. };
  253. });
  254. series.translateColors();
  255. }
  256. },
  257. // Circle shape type.
  258. circle: {
  259. alignDataLabel: H.seriesTypes.scatter.prototype.alignDataLabel,
  260. getSeriesPadding: function (series) {
  261. return tilePaddingFromTileSize(series, 2, 2);
  262. },
  263. haloPath: function (size) {
  264. return H.seriesTypes.scatter.prototype.pointClass.prototype.haloPath
  265. .call(
  266. this,
  267. size + (size && this.radius)
  268. );
  269. },
  270. translate: function () {
  271. var series = this,
  272. options = series.options,
  273. xAxis = series.xAxis,
  274. yAxis = series.yAxis,
  275. seriesPointPadding = options.pointPadding || 0,
  276. yRadius = (options.rowsize || 1) / 2,
  277. colsize = (options.colsize || 1),
  278. colsizePx,
  279. yRadiusPx,
  280. xRadiusPx,
  281. radius,
  282. forceNextRadiusCompute = false;
  283. series.generatePoints();
  284. series.points.forEach(function (point) {
  285. var x = between(
  286. Math.round(
  287. xAxis.len -
  288. xAxis.translate(point.x, 0, 1, 0, 0)
  289. ), -xAxis.len, 2 * xAxis.len
  290. ),
  291. y = between(
  292. Math.round(yAxis.translate(point.y, 0, 1, 0, 0)),
  293. -yAxis.len,
  294. 2 * yAxis.len
  295. ),
  296. pointPadding = seriesPointPadding,
  297. hasPerPointPadding = false;
  298. // If there is point padding defined on a single point, add it
  299. if (point.pointPadding !== undefined) {
  300. pointPadding = point.pointPadding;
  301. hasPerPointPadding = true;
  302. forceNextRadiusCompute = true;
  303. }
  304. // Find radius if not found already.
  305. // Use the smallest one (x vs y) to avoid overlap.
  306. // Note that the radius will be recomputed for each series.
  307. // Ideal (max) x radius is dependent on y radius:
  308. /*
  309. * (circle 2)
  310. * (circle 3)
  311. | yRadiusPx
  312. (circle 1) *-------|
  313. colsizePx
  314. The distance between circle 1 and 3 (and circle 2 and 3) is
  315. 2r, which is the hypotenuse of the triangle created by
  316. colsizePx and yRadiusPx. If the distance between circle 2
  317. and circle 1 is less than 2r, we use half of that distance
  318. instead (yRadiusPx).
  319. */
  320. if (!radius || forceNextRadiusCompute) {
  321. colsizePx = Math.abs(
  322. between(
  323. Math.floor(
  324. xAxis.len -
  325. xAxis.translate(point.x + colsize, 0, 1, 0, 0)
  326. ), -xAxis.len, 2 * xAxis.len
  327. ) - x
  328. );
  329. yRadiusPx = Math.abs(
  330. between(
  331. Math.floor(
  332. yAxis.translate(point.y + yRadius, 0, 1, 0, 0)
  333. ), -yAxis.len, 2 * yAxis.len
  334. ) - y
  335. );
  336. xRadiusPx = Math.floor(
  337. Math.sqrt(
  338. (colsizePx * colsizePx + yRadiusPx * yRadiusPx)
  339. ) / 2
  340. );
  341. radius = Math.min(
  342. colsizePx, xRadiusPx, yRadiusPx
  343. ) - pointPadding;
  344. // If we have per point padding we need to always compute
  345. // the radius for this point and the next. If we used to
  346. // have per point padding but don't anymore, don't force
  347. // compute next radius.
  348. if (forceNextRadiusCompute && !hasPerPointPadding) {
  349. forceNextRadiusCompute = false;
  350. }
  351. }
  352. // Shift y-values for every second grid column.
  353. // Note that we always use the optimal y axis radius for this.
  354. // Also note: We have to reverse the shift for reversed y-axes.
  355. if (point.x % 2) {
  356. y += yRadiusPx * (yAxis.reversed ? -1 : 1);
  357. }
  358. // Set plotX and plotY for use in K-D-Tree and more
  359. point.plotX = point.clientX = x;
  360. point.plotY = y;
  361. // Save radius for halo
  362. point.radius = radius;
  363. // Set this point's shape parameters
  364. point.shapeType = 'circle';
  365. point.shapeArgs = {
  366. x: x,
  367. y: y,
  368. r: radius
  369. };
  370. });
  371. series.translateColors();
  372. }
  373. },
  374. // Square shape type.
  375. square: {
  376. alignDataLabel: H.seriesTypes.heatmap.prototype.alignDataLabel,
  377. translate: H.seriesTypes.heatmap.prototype.translate,
  378. getSeriesPadding: function () {
  379. },
  380. haloPath: H.seriesTypes.heatmap.prototype.pointClass.prototype.haloPath
  381. }
  382. };
  383. // Extension to add pixel padding for series. Uses getSeriesPixelPadding on each
  384. // series and adds the largest padding required. If no series has this function
  385. // defined, we add nothing.
  386. H.addEvent(H.Axis, 'afterSetAxisTranslation', function () {
  387. if (this.recomputingForTilemap) {
  388. return;
  389. }
  390. var axis = this,
  391. // Find which series' padding to use
  392. seriesPadding = axis.series
  393. .map(function (series) {
  394. return series.getSeriesPixelPadding &&
  395. series.getSeriesPixelPadding(axis);
  396. })
  397. .reduce(function (a, b) {
  398. return (a && a.padding) > (b && b.padding) ? a : b;
  399. }, undefined) ||
  400. {
  401. padding: 0,
  402. axisLengthFactor: 1
  403. },
  404. lengthPadding = Math.round(
  405. seriesPadding.padding * seriesPadding.axisLengthFactor
  406. );
  407. // Don't waste time on this if we're not adding extra padding
  408. if (seriesPadding.padding) {
  409. // Recompute translation with new axis length now (minus padding)
  410. axis.len -= lengthPadding;
  411. axis.recomputingForTilemap = true;
  412. axis.setAxisTranslation();
  413. delete axis.recomputingForTilemap;
  414. axis.minPixelPadding += seriesPadding.padding;
  415. axis.len += lengthPadding;
  416. }
  417. });
  418. /**
  419. * @private
  420. * @class
  421. * @name Highcharts.seriesTypes.tilemap
  422. *
  423. * @augments Highcharts.Series
  424. */
  425. seriesType('tilemap', 'heatmap'
  426. /**
  427. * A tilemap series is a type of heatmap where the tile shapes are configurable.
  428. *
  429. * @sample highcharts/demo/honeycomb-usa/
  430. * Honeycomb tilemap, USA
  431. * @sample maps/plotoptions/honeycomb-brazil/
  432. * Honeycomb tilemap, Brazil
  433. * @sample maps/plotoptions/honeycomb-china/
  434. * Honeycomb tilemap, China
  435. * @sample maps/plotoptions/honeycomb-europe/
  436. * Honeycomb tilemap, Europe
  437. * @sample maps/demo/circlemap-africa/
  438. * Circlemap tilemap, Africa
  439. * @sample maps/demo/diamondmap
  440. * Diamondmap tilemap
  441. *
  442. * @extends plotOptions.heatmap
  443. * @since 6.0.0
  444. * @excluding jitter, joinBy, shadow, allAreas, mapData, data
  445. * @product highcharts highmaps
  446. * @optionparent plotOptions.tilemap
  447. */
  448. , { // Default options
  449. states: {
  450. hover: {
  451. halo: {
  452. enabled: true,
  453. size: 2,
  454. opacity: 0.5,
  455. attributes: {
  456. zIndex: 3
  457. }
  458. }
  459. }
  460. },
  461. /**
  462. * The padding between points in the tilemap.
  463. *
  464. * @sample maps/plotoptions/tilemap-pointpadding
  465. * Point padding on tiles
  466. */
  467. pointPadding: 2,
  468. /**
  469. * The column size - how many X axis units each column in the tilemap
  470. * should span. Works as in [Heatmaps](#plotOptions.heatmap.colsize).
  471. *
  472. * @sample {highcharts} maps/demo/heatmap/
  473. * One day
  474. * @sample {highmaps} maps/demo/heatmap/
  475. * One day
  476. *
  477. * @type {number}
  478. * @default 1
  479. * @product highcharts highmaps
  480. * @apioption plotOptions.tilemap.colsize
  481. */
  482. /**
  483. * The row size - how many Y axis units each tilemap row should span.
  484. * Analogous to [colsize](#plotOptions.tilemap.colsize).
  485. *
  486. * @sample {highcharts} maps/demo/heatmap/
  487. * 1 by default
  488. * @sample {highmaps} maps/demo/heatmap/
  489. * 1 by default
  490. *
  491. * @type {number}
  492. * @default 1
  493. * @product highcharts highmaps
  494. * @apioption plotOptions.tilemap.rowsize
  495. */
  496. /**
  497. * The shape of the tiles in the tilemap. Possible values are `hexagon`,
  498. * `circle`, `diamond`, and `square`.
  499. *
  500. * @sample maps/demo/circlemap-africa
  501. * Circular tile shapes
  502. * @sample maps/demo/diamondmap
  503. * Diamond tile shapes
  504. *
  505. * @validvalue ["circle", "diamond", "hexagon", "square"]
  506. */
  507. tileShape: 'hexagon'
  508. }, { // Prototype functions
  509. // Set tile shape object on series
  510. setOptions: function () {
  511. // Call original function
  512. var ret = H.seriesTypes.heatmap.prototype.setOptions.apply(
  513. this,
  514. Array.prototype.slice.call(arguments)
  515. );
  516. this.tileShape = H.tileShapeTypes[ret.tileShape];
  517. return ret;
  518. },
  519. // Use the shape's defined data label alignment function
  520. alignDataLabel: function () {
  521. return this.tileShape.alignDataLabel.apply(
  522. this,
  523. Array.prototype.slice.call(arguments)
  524. );
  525. },
  526. // Get metrics for padding of axis for this series
  527. getSeriesPixelPadding: function (axis) {
  528. var isX = axis.isXAxis,
  529. padding = this.tileShape.getSeriesPadding(this),
  530. coord1,
  531. coord2;
  532. // If the shape type does not require padding, return no-op padding
  533. if (!padding) {
  534. return {
  535. padding: 0,
  536. axisLengthFactor: 1
  537. };
  538. }
  539. // Use translate to compute how far outside the points we
  540. // draw, and use this difference as padding.
  541. coord1 = Math.round(
  542. axis.translate(
  543. isX ?
  544. padding.xPad * 2 :
  545. padding.yPad,
  546. 0, 1, 0, 1
  547. )
  548. );
  549. coord2 = Math.round(
  550. axis.translate(
  551. isX ? padding.xPad : 0,
  552. 0, 1, 0, 1
  553. )
  554. );
  555. return {
  556. padding: Math.abs(coord1 - coord2) || 0,
  557. // Offset the yAxis length to compensate for shift. Setting the
  558. // length factor to 2 would add the same margin to max as min.
  559. // Now we only add a slight bit of the min margin to max, as we
  560. // don't actually draw outside the max bounds. For the xAxis we
  561. // draw outside on both sides so we add the same margin to min
  562. // and max.
  563. axisLengthFactor: isX ? 2 : 1.1
  564. };
  565. },
  566. // Use translate from tileShape
  567. translate: function () {
  568. return this.tileShape.translate.apply(
  569. this,
  570. Array.prototype.slice.call(arguments)
  571. );
  572. }
  573. }, H.extend({
  574. /**
  575. * @private
  576. * @function Highcharts.Point#haloPath
  577. *
  578. * @return {Highcharts.SVGPathArray}
  579. */
  580. haloPath: function () {
  581. return this.series.tileShape.haloPath.apply(
  582. this,
  583. Array.prototype.slice.call(arguments)
  584. );
  585. }
  586. }, H.colorPointMixin));
  587. /**
  588. * A `tilemap` series. If the [type](#series.tilemap.type) option is
  589. * not specified, it is inherited from [chart.type](#chart.type).
  590. *
  591. * @extends series,plotOptions.tilemap
  592. * @excluding allAreas, dataParser, dataURL, joinBy, mapData, marker,
  593. * pointRange, shadow, stack
  594. * @product highcharts highmaps
  595. * @apioption series.tilemap
  596. */
  597. /**
  598. * An array of data points for the series. For the `tilemap` series
  599. * type, points can be given in the following ways:
  600. *
  601. * 1. An array of arrays with 3 or 2 values. In this case, the values correspond
  602. * to `x,y,value`. If the first value is a string, it is applied as the name
  603. * of the point, and the `x` value is inferred. The `x` value can also be
  604. * omitted, in which case the inner arrays should be of length 2\. Then the
  605. * `x` value is automatically calculated, either starting at 0 and
  606. * incremented by 1, or from `pointStart` and `pointInterval` given in the
  607. * series options.
  608. * ```js
  609. * data: [
  610. * [0, 9, 7],
  611. * [1, 10, 4],
  612. * [2, 6, 3]
  613. * ]
  614. * ```
  615. *
  616. * 2. An array of objects with named values. The objects are point configuration
  617. * objects as seen below. If the total number of data points exceeds the
  618. * series' [turboThreshold](#series.tilemap.turboThreshold), this option is
  619. * not available.
  620. * ```js
  621. * data: [{
  622. * x: 1,
  623. * y: 3,
  624. * value: 10,
  625. * name: "Point2",
  626. * color: "#00FF00"
  627. * }, {
  628. * x: 1,
  629. * y: 7,
  630. * value: 10,
  631. * name: "Point1",
  632. * color: "#FF00FF"
  633. * }]
  634. * ```
  635. *
  636. * Note that for some [tileShapes](#plotOptions.tilemap.tileShape) the grid
  637. * coordinates are offset.
  638. *
  639. * @sample maps/series/tilemap-gridoffset
  640. * Offset grid coordinates
  641. * @sample {highcharts} highcharts/series/data-array-of-arrays/
  642. * Arrays of numeric x and y
  643. * @sample {highcharts} highcharts/series/data-array-of-arrays-datetime/
  644. * Arrays of datetime x and y
  645. * @sample {highcharts} highcharts/series/data-array-of-name-value/
  646. * Arrays of point.name and y
  647. * @sample {highcharts} highcharts/series/data-array-of-objects/
  648. * Config objects
  649. *
  650. * @type {Array<Array<(number|string),number>|Array<(number|string),number,number>|*>}
  651. * @extends series.heatmap.data
  652. * @excluding marker
  653. * @product highcharts highmaps
  654. * @apioption series.tilemap.data
  655. */
  656. /**
  657. * The color of the point. In tilemaps the point color is rarely set
  658. * explicitly, as we use the color to denote the `value`. Options for
  659. * this are set in the [colorAxis](#colorAxis) configuration.
  660. *
  661. * @type {Highcharts.ColorString|Highcharts.GradientColorObject|Highcharts.PatternObject}
  662. * @product highcharts highmaps
  663. * @apioption series.tilemap.data.color
  664. */
  665. /**
  666. * The x coordinate of the point.
  667. *
  668. * Note that for some [tileShapes](#plotOptions.tilemap.tileShape) the grid
  669. * coordinates are offset.
  670. *
  671. * @sample maps/series/tilemap-gridoffset
  672. * Offset grid coordinates
  673. *
  674. * @type {number}
  675. * @product highcharts highmaps
  676. * @apioption series.tilemap.data.x
  677. */
  678. /**
  679. * The y coordinate of the point.
  680. *
  681. * Note that for some [tileShapes](#plotOptions.tilemap.tileShape) the grid
  682. * coordinates are offset.
  683. *
  684. * @sample maps/series/tilemap-gridoffset
  685. * Offset grid coordinates
  686. *
  687. * @type {number}
  688. * @product highcharts highmaps
  689. * @apioption series.tilemap.data.y
  690. */