@techie_doubts/tui.chart.2026 4.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/README.md +165 -0
  2. package/dist/esm/animator.d.ts +32 -0
  3. package/dist/esm/animator.js +102 -0
  4. package/dist/esm/brushes/axis.d.ts +3 -0
  5. package/dist/esm/brushes/axis.js +21 -0
  6. package/dist/esm/brushes/basic.d.ts +9 -0
  7. package/dist/esm/brushes/basic.js +95 -0
  8. package/dist/esm/brushes/boxPlot.d.ts +2 -0
  9. package/dist/esm/brushes/boxPlot.js +22 -0
  10. package/dist/esm/brushes/circleLegend.d.ts +2 -0
  11. package/dist/esm/brushes/circleLegend.js +26 -0
  12. package/dist/esm/brushes/dataLabel.d.ts +6 -0
  13. package/dist/esm/brushes/dataLabel.js +176 -0
  14. package/dist/esm/brushes/exportMenu.d.ts +2 -0
  15. package/dist/esm/brushes/exportMenu.js +55 -0
  16. package/dist/esm/brushes/gauge.d.ts +2 -0
  17. package/dist/esm/brushes/gauge.js +39 -0
  18. package/dist/esm/brushes/label.d.ts +34 -0
  19. package/dist/esm/brushes/label.js +165 -0
  20. package/dist/esm/brushes/legend.d.ts +7 -0
  21. package/dist/esm/brushes/legend.js +162 -0
  22. package/dist/esm/brushes/lineSeries.d.ts +5 -0
  23. package/dist/esm/brushes/lineSeries.js +41 -0
  24. package/dist/esm/brushes/polygon.d.ts +2 -0
  25. package/dist/esm/brushes/polygon.js +24 -0
  26. package/dist/esm/brushes/resetButton.d.ts +3 -0
  27. package/dist/esm/brushes/resetButton.js +112 -0
  28. package/dist/esm/brushes/scatterSeries.d.ts +2 -0
  29. package/dist/esm/brushes/scatterSeries.js +125 -0
  30. package/dist/esm/brushes/sector.d.ts +2 -0
  31. package/dist/esm/brushes/sector.js +54 -0
  32. package/dist/esm/brushes/spectrumLegend.d.ts +14 -0
  33. package/dist/esm/brushes/spectrumLegend.js +199 -0
  34. package/dist/esm/charts/areaChart.d.ts +254 -0
  35. package/dist/esm/charts/areaChart.js +358 -0
  36. package/dist/esm/charts/barChart.d.ts +203 -0
  37. package/dist/esm/charts/barChart.js +300 -0
  38. package/dist/esm/charts/boxPlotChart.d.ts +209 -0
  39. package/dist/esm/charts/boxPlotChart.js +288 -0
  40. package/dist/esm/charts/bubbleChart.d.ts +188 -0
  41. package/dist/esm/charts/bubbleChart.js +263 -0
  42. package/dist/esm/charts/bulletChart.d.ts +199 -0
  43. package/dist/esm/charts/bulletChart.js +278 -0
  44. package/dist/esm/charts/chart.d.ts +133 -0
  45. package/dist/esm/charts/chart.js +484 -0
  46. package/dist/esm/charts/columnChart.d.ts +205 -0
  47. package/dist/esm/charts/columnChart.js +299 -0
  48. package/dist/esm/charts/columnLineChart.d.ts +271 -0
  49. package/dist/esm/charts/columnLineChart.js +386 -0
  50. package/dist/esm/charts/gaugeChart.d.ts +191 -0
  51. package/dist/esm/charts/gaugeChart.js +279 -0
  52. package/dist/esm/charts/heatmapChart.d.ts +199 -0
  53. package/dist/esm/charts/heatmapChart.js +292 -0
  54. package/dist/esm/charts/lineAreaChart.d.ts +271 -0
  55. package/dist/esm/charts/lineAreaChart.js +374 -0
  56. package/dist/esm/charts/lineChart.d.ts +253 -0
  57. package/dist/esm/charts/lineChart.js +360 -0
  58. package/dist/esm/charts/lineScatterChart.d.ts +200 -0
  59. package/dist/esm/charts/lineScatterChart.js +285 -0
  60. package/dist/esm/charts/nestedPieChart.d.ts +192 -0
  61. package/dist/esm/charts/nestedPieChart.js +268 -0
  62. package/dist/esm/charts/pieChart.d.ts +156 -0
  63. package/dist/esm/charts/pieChart.js +224 -0
  64. package/dist/esm/charts/radarChart.d.ts +169 -0
  65. package/dist/esm/charts/radarChart.js +240 -0
  66. package/dist/esm/charts/radialBarChart.d.ts +172 -0
  67. package/dist/esm/charts/radialBarChart.js +251 -0
  68. package/dist/esm/charts/scatterChart.d.ts +184 -0
  69. package/dist/esm/charts/scatterChart.js +279 -0
  70. package/dist/esm/charts/treemapChart.d.ts +166 -0
  71. package/dist/esm/charts/treemapChart.js +239 -0
  72. package/dist/esm/component/areaSeries.d.ts +96 -0
  73. package/dist/esm/component/areaSeries.js +474 -0
  74. package/dist/esm/component/axis.d.ts +40 -0
  75. package/dist/esm/component/axis.js +176 -0
  76. package/dist/esm/component/axisTitle.d.ts +25 -0
  77. package/dist/esm/component/axisTitle.js +67 -0
  78. package/dist/esm/component/axisUsingCenterY.d.ts +32 -0
  79. package/dist/esm/component/axisUsingCenterY.js +175 -0
  80. package/dist/esm/component/backButton.d.ts +13 -0
  81. package/dist/esm/component/backButton.js +26 -0
  82. package/dist/esm/component/background.d.ts +10 -0
  83. package/dist/esm/component/background.js +15 -0
  84. package/dist/esm/component/boxPlotSeries.d.ts +126 -0
  85. package/dist/esm/component/boxPlotSeries.js +410 -0
  86. package/dist/esm/component/boxSeries.d.ts +211 -0
  87. package/dist/esm/component/boxSeries.js +603 -0
  88. package/dist/esm/component/boxStackSeries.d.ts +62 -0
  89. package/dist/esm/component/boxStackSeries.js +447 -0
  90. package/dist/esm/component/bubbleSeries.d.ts +35 -0
  91. package/dist/esm/component/bubbleSeries.js +174 -0
  92. package/dist/esm/component/bulletSeries.d.ts +89 -0
  93. package/dist/esm/component/bulletSeries.js +392 -0
  94. package/dist/esm/component/circleLegend.d.ts +10 -0
  95. package/dist/esm/component/circleLegend.js +37 -0
  96. package/dist/esm/component/component.d.ts +64 -0
  97. package/dist/esm/component/component.js +170 -0
  98. package/dist/esm/component/componentManager.d.ts +23 -0
  99. package/dist/esm/component/componentManager.js +45 -0
  100. package/dist/esm/component/dataLabels.d.ts +23 -0
  101. package/dist/esm/component/dataLabels.js +134 -0
  102. package/dist/esm/component/exportMenu.d.ts +38 -0
  103. package/dist/esm/component/exportMenu.js +147 -0
  104. package/dist/esm/component/gaugeSeries.d.ts +160 -0
  105. package/dist/esm/component/gaugeSeries.js +447 -0
  106. package/dist/esm/component/heatmapSeries.d.ts +64 -0
  107. package/dist/esm/component/heatmapSeries.js +152 -0
  108. package/dist/esm/component/hoveredSeries.d.ts +27 -0
  109. package/dist/esm/component/hoveredSeries.js +95 -0
  110. package/dist/esm/component/legend.d.ts +26 -0
  111. package/dist/esm/component/legend.js +149 -0
  112. package/dist/esm/component/lineSeries.d.ts +69 -0
  113. package/dist/esm/component/lineSeries.js +319 -0
  114. package/dist/esm/component/noDataText.d.ts +9 -0
  115. package/dist/esm/component/noDataText.js +31 -0
  116. package/dist/esm/component/pieSeries.d.ts +137 -0
  117. package/dist/esm/component/pieSeries.js +390 -0
  118. package/dist/esm/component/plot.d.ts +37 -0
  119. package/dist/esm/component/plot.js +163 -0
  120. package/dist/esm/component/radarSeries.d.ts +85 -0
  121. package/dist/esm/component/radarSeries.js +222 -0
  122. package/dist/esm/component/radialAxis.d.ts +26 -0
  123. package/dist/esm/component/radialAxis.js +210 -0
  124. package/dist/esm/component/radialBarSeries.d.ts +111 -0
  125. package/dist/esm/component/radialBarSeries.js +349 -0
  126. package/dist/esm/component/radialPlot.d.ts +55 -0
  127. package/dist/esm/component/radialPlot.js +188 -0
  128. package/dist/esm/component/rangeSelection.d.ts +61 -0
  129. package/dist/esm/component/rangeSelection.js +150 -0
  130. package/dist/esm/component/resetButton.d.ts +13 -0
  131. package/dist/esm/component/resetButton.js +26 -0
  132. package/dist/esm/component/scatterSeries.d.ts +34 -0
  133. package/dist/esm/component/scatterSeries.js +159 -0
  134. package/dist/esm/component/selectedSeries.d.ts +26 -0
  135. package/dist/esm/component/selectedSeries.js +109 -0
  136. package/dist/esm/component/spectrumLegend.d.ts +15 -0
  137. package/dist/esm/component/spectrumLegend.js +76 -0
  138. package/dist/esm/component/title.d.ts +12 -0
  139. package/dist/esm/component/title.js +53 -0
  140. package/dist/esm/component/tooltip.d.ts +41 -0
  141. package/dist/esm/component/tooltip.js +131 -0
  142. package/dist/esm/component/treemapSeries.d.ts +57 -0
  143. package/dist/esm/component/treemapSeries.js +191 -0
  144. package/dist/esm/component/zeroAxis.d.ts +9 -0
  145. package/dist/esm/component/zeroAxis.js +49 -0
  146. package/dist/esm/eventEmitter.d.ts +8 -0
  147. package/dist/esm/eventEmitter.js +15 -0
  148. package/dist/esm/helpers/arrayUtil.d.ts +10 -0
  149. package/dist/esm/helpers/arrayUtil.js +54 -0
  150. package/dist/esm/helpers/axes.d.ts +67 -0
  151. package/dist/esm/helpers/axes.js +345 -0
  152. package/dist/esm/helpers/boxSeries.d.ts +5 -0
  153. package/dist/esm/helpers/boxSeries.js +71 -0
  154. package/dist/esm/helpers/calculator.d.ts +19 -0
  155. package/dist/esm/helpers/calculator.js +153 -0
  156. package/dist/esm/helpers/color.d.ts +153 -0
  157. package/dist/esm/helpers/color.js +218 -0
  158. package/dist/esm/helpers/colorSpectrum.d.ts +5 -0
  159. package/dist/esm/helpers/colorSpectrum.js +17 -0
  160. package/dist/esm/helpers/coordinate.d.ts +9 -0
  161. package/dist/esm/helpers/coordinate.js +51 -0
  162. package/dist/esm/helpers/dataLabels.d.ts +36 -0
  163. package/dist/esm/helpers/dataLabels.js +405 -0
  164. package/dist/esm/helpers/dom.d.ts +2 -0
  165. package/dist/esm/helpers/dom.js +8 -0
  166. package/dist/esm/helpers/downloader.d.ts +7 -0
  167. package/dist/esm/helpers/downloader.js +287 -0
  168. package/dist/esm/helpers/formatDate.d.ts +16 -0
  169. package/dist/esm/helpers/formatDate.js +140 -0
  170. package/dist/esm/helpers/geometric.d.ts +3 -0
  171. package/dist/esm/helpers/geometric.js +35 -0
  172. package/dist/esm/helpers/googleAnalytics.d.ts +1 -0
  173. package/dist/esm/helpers/googleAnalytics.js +39 -0
  174. package/dist/esm/helpers/htmlSanitizer.d.ts +1 -0
  175. package/dist/esm/helpers/htmlSanitizer.js +86 -0
  176. package/dist/esm/helpers/legend.d.ts +9 -0
  177. package/dist/esm/helpers/legend.js +47 -0
  178. package/dist/esm/helpers/pieSeries.d.ts +15 -0
  179. package/dist/esm/helpers/pieSeries.js +72 -0
  180. package/dist/esm/helpers/plot.d.ts +2 -0
  181. package/dist/esm/helpers/plot.js +4 -0
  182. package/dist/esm/helpers/radarSeries.d.ts +1 -0
  183. package/dist/esm/helpers/radarSeries.js +7 -0
  184. package/dist/esm/helpers/range.d.ts +6 -0
  185. package/dist/esm/helpers/range.js +16 -0
  186. package/dist/esm/helpers/responders.d.ts +37 -0
  187. package/dist/esm/helpers/responders.js +197 -0
  188. package/dist/esm/helpers/sector.d.ts +55 -0
  189. package/dist/esm/helpers/sector.js +117 -0
  190. package/dist/esm/helpers/squarifier.d.ts +8 -0
  191. package/dist/esm/helpers/squarifier.js +110 -0
  192. package/dist/esm/helpers/style.d.ts +14 -0
  193. package/dist/esm/helpers/style.js +48 -0
  194. package/dist/esm/helpers/theme.d.ts +58 -0
  195. package/dist/esm/helpers/theme.js +557 -0
  196. package/dist/esm/helpers/tooltip.d.ts +2 -0
  197. package/dist/esm/helpers/tooltip.js +18 -0
  198. package/dist/esm/helpers/tooltipTemplate.d.ts +21 -0
  199. package/dist/esm/helpers/tooltipTemplate.js +147 -0
  200. package/dist/esm/helpers/utils.d.ts +42 -0
  201. package/dist/esm/helpers/utils.js +268 -0
  202. package/dist/esm/helpers/validation.d.ts +6 -0
  203. package/dist/esm/helpers/validation.js +16 -0
  204. package/dist/esm/index.d.ts +40 -0
  205. package/dist/esm/index.js +75 -0
  206. package/dist/esm/message.d.ts +11 -0
  207. package/dist/esm/message.js +11 -0
  208. package/dist/esm/painter.d.ts +27 -0
  209. package/dist/esm/painter.js +88 -0
  210. package/dist/esm/responderDetectors.d.ts +6 -0
  211. package/dist/esm/responderDetectors.js +124 -0
  212. package/dist/esm/scale/coordinateScaleCalculator.d.ts +24 -0
  213. package/dist/esm/scale/coordinateScaleCalculator.js +174 -0
  214. package/dist/esm/scale/datetimeScaleCalculator.d.ts +20 -0
  215. package/dist/esm/scale/datetimeScaleCalculator.js +59 -0
  216. package/dist/esm/store/axes.d.ts +30 -0
  217. package/dist/esm/store/axes.js +282 -0
  218. package/dist/esm/store/category.d.ts +4 -0
  219. package/dist/esm/store/category.js +73 -0
  220. package/dist/esm/store/colorValueScale.d.ts +3 -0
  221. package/dist/esm/store/colorValueScale.js +56 -0
  222. package/dist/esm/store/dataRange.d.ts +4 -0
  223. package/dist/esm/store/dataRange.js +170 -0
  224. package/dist/esm/store/gaugeAxes.d.ts +4 -0
  225. package/dist/esm/store/gaugeAxes.js +175 -0
  226. package/dist/esm/store/heatmapAxes.d.ts +3 -0
  227. package/dist/esm/store/heatmapAxes.js +98 -0
  228. package/dist/esm/store/heatmapSeriesData.d.ts +3 -0
  229. package/dist/esm/store/heatmapSeriesData.js +34 -0
  230. package/dist/esm/store/layout.d.ts +12 -0
  231. package/dist/esm/store/layout.js +487 -0
  232. package/dist/esm/store/legend.d.ts +3 -0
  233. package/dist/esm/store/legend.js +435 -0
  234. package/dist/esm/store/nestedPieSeriesData.d.ts +3 -0
  235. package/dist/esm/store/nestedPieSeriesData.js +49 -0
  236. package/dist/esm/store/options.d.ts +3 -0
  237. package/dist/esm/store/options.js +62 -0
  238. package/dist/esm/store/plot.d.ts +3 -0
  239. package/dist/esm/store/plot.js +102 -0
  240. package/dist/esm/store/radialAxes.d.ts +8 -0
  241. package/dist/esm/store/radialAxes.js +199 -0
  242. package/dist/esm/store/reactive.d.ts +11 -0
  243. package/dist/esm/store/reactive.js +196 -0
  244. package/dist/esm/store/root.d.ts +3 -0
  245. package/dist/esm/store/root.js +46 -0
  246. package/dist/esm/store/scale.d.ts +3 -0
  247. package/dist/esm/store/scale.js +102 -0
  248. package/dist/esm/store/seriesData.d.ts +3 -0
  249. package/dist/esm/store/seriesData.js +299 -0
  250. package/dist/esm/store/stackSeriesData.d.ts +8 -0
  251. package/dist/esm/store/stackSeriesData.js +192 -0
  252. package/dist/esm/store/store.d.ts +20 -0
  253. package/dist/esm/store/store.js +112 -0
  254. package/dist/esm/store/theme.d.ts +3 -0
  255. package/dist/esm/store/theme.js +139 -0
  256. package/dist/esm/store/treemapSeriesData.d.ts +4 -0
  257. package/dist/esm/store/treemapSeriesData.js +93 -0
  258. package/dist/td-chart.css +127 -0
  259. package/dist/td-chart.js +41463 -0
  260. package/dist/td-chart.min.css +6 -0
  261. package/dist/td-chart.min.js +9 -0
  262. package/package.json +112 -0
  263. package/types/brushes.d.ts +30 -0
  264. package/types/charts.d.ts +152 -0
  265. package/types/components/axis.d.ts +71 -0
  266. package/types/components/circleLegend.d.ts +9 -0
  267. package/types/components/dataLabels.d.ts +119 -0
  268. package/types/components/exportMenu.d.ts +14 -0
  269. package/types/components/legend.d.ts +27 -0
  270. package/types/components/plot.d.ts +8 -0
  271. package/types/components/radialAxis.d.ts +22 -0
  272. package/types/components/radialPlot.d.ts +11 -0
  273. package/types/components/rangeSelection.d.ts +3 -0
  274. package/types/components/resetButton.d.ts +13 -0
  275. package/types/components/series.d.ts +386 -0
  276. package/types/components/spectrumLegend.d.ts +25 -0
  277. package/types/components/tooltip.d.ts +58 -0
  278. package/types/components/zoom.d.ts +3 -0
  279. package/types/eventEmitter.d.ts +12 -0
  280. package/types/index.d.ts +615 -0
  281. package/types/options.d.ts +833 -0
  282. package/types/resizeObserver.d.ts +54 -0
  283. package/types/store/store.d.ts +564 -0
  284. package/types/theme.d.ts +670 -0
@@ -0,0 +1,15 @@
1
+ import { PieSeriesType } from "../../types/options";
2
+ import { TooltipData } from "../../types/components/tooltip";
3
+ import { RawSeries, OptionsWithDataLabels } from "../../types/store/store";
4
+ export declare function hasClockwiseSemiCircle(clockwise: boolean, startAngle: number, endAngle: number): boolean;
5
+ export declare function hasCounterClockwiseSemiCircle(clockwise: boolean, startAngle: number, endAngle: number): boolean;
6
+ export declare function getRadius(defaultRadius: number, radius: string | number): number;
7
+ export declare function getTotalAngle(clockwise: boolean, startAngle: number, endAngle: number): number;
8
+ export declare function isSemiCircle(clockwise: boolean, startAngle: number, endAngle: number): boolean;
9
+ export declare function getSemiCircleCenterY(rectHeight: number, clockwise: boolean): number;
10
+ export declare function makePieTooltipData(seriesRawData: PieSeriesType[], category?: string): TooltipData[];
11
+ export declare function hasNestedPieSeries(series: RawSeries): boolean;
12
+ export declare function getNestedPieChartAliasNames(series: RawSeries): string[];
13
+ export declare function pieTooltipLabelFormatter(percentValue: number): string;
14
+ export declare function hasOuterDataLabel(options: OptionsWithDataLabels, series: RawSeries): boolean;
15
+ export declare function hasOuterPieSeriesName(options: OptionsWithDataLabels, series: RawSeries): boolean;
@@ -0,0 +1,72 @@
1
+ import { getPercentageValue, isString, isNull } from "./utils";
2
+ import { DEGREE_NEGATIVE_90, DEGREE_90, DEGREE_180, DEGREE_NEGATIVE_180, DEGREE_360, DEGREE_0, } from "./sector";
3
+ const semiCircleCenterYRatio = {
4
+ COUNTER_CLOCKWISE: 0.1,
5
+ CLOCKWISE: 1,
6
+ };
7
+ export function hasClockwiseSemiCircle(clockwise, startAngle, endAngle) {
8
+ return (clockwise &&
9
+ ((startAngle >= DEGREE_NEGATIVE_90 && endAngle <= DEGREE_90) ||
10
+ (startAngle >= DEGREE_90 && endAngle <= DEGREE_180)));
11
+ }
12
+ export function hasCounterClockwiseSemiCircle(clockwise, startAngle, endAngle) {
13
+ return (!clockwise &&
14
+ ((startAngle >= DEGREE_NEGATIVE_180 && endAngle <= DEGREE_90) ||
15
+ (startAngle <= DEGREE_90 && endAngle >= DEGREE_NEGATIVE_90)));
16
+ }
17
+ export function getRadius(defaultRadius, radius) {
18
+ return isString(radius)
19
+ ? Number(((defaultRadius * getPercentageValue(radius)) / 100).toFixed(2))
20
+ : radius;
21
+ }
22
+ export function getTotalAngle(clockwise, startAngle, endAngle) {
23
+ const diffAngle = endAngle - startAngle;
24
+ const absDiff = Math.abs(diffAngle);
25
+ const needSubstractAngle = (diffAngle > DEGREE_0 && absDiff !== DEGREE_360 && !clockwise) ||
26
+ (diffAngle < DEGREE_0 && absDiff !== DEGREE_360 && clockwise);
27
+ return needSubstractAngle ? DEGREE_360 - absDiff : absDiff;
28
+ }
29
+ export function isSemiCircle(clockwise, startAngle, endAngle) {
30
+ return (getTotalAngle(clockwise, startAngle, endAngle) <= DEGREE_180 &&
31
+ (hasClockwiseSemiCircle(clockwise, startAngle, endAngle) ||
32
+ hasCounterClockwiseSemiCircle(clockwise, startAngle, endAngle)));
33
+ }
34
+ export function getSemiCircleCenterY(rectHeight, clockwise) {
35
+ return clockwise
36
+ ? rectHeight * semiCircleCenterYRatio.CLOCKWISE
37
+ : rectHeight * semiCircleCenterYRatio.COUNTER_CLOCKWISE;
38
+ }
39
+ export function makePieTooltipData(seriesRawData, category = '') {
40
+ return seriesRawData
41
+ .filter(({ data }) => !isNull(data))
42
+ .map(({ data, name, color, rootParentName }) => ({
43
+ label: name,
44
+ color: color,
45
+ value: data,
46
+ category,
47
+ rootParentName,
48
+ templateType: 'pie',
49
+ }));
50
+ }
51
+ export function hasNestedPieSeries(series) {
52
+ var _a;
53
+ return !!(series.pie && Array.isArray((_a = series.pie[0]) === null || _a === void 0 ? void 0 : _a.data));
54
+ }
55
+ export function getNestedPieChartAliasNames(series) {
56
+ return series.pie.map(({ name }) => name);
57
+ }
58
+ export function pieTooltipLabelFormatter(percentValue) {
59
+ const percentageString = percentValue.toFixed(2);
60
+ const percent = parseFloat(percentageString);
61
+ const needSlice = percentageString.length > 5;
62
+ return `${needSlice ? parseFloat(percentageString.substr(0, 4)) : String(percent)}%`;
63
+ }
64
+ export function hasOuterDataLabel(options, series) {
65
+ var _a, _b, _c;
66
+ return !!series.pie && ((_c = (_b = (_a = options) === null || _a === void 0 ? void 0 : _a.series) === null || _b === void 0 ? void 0 : _b.dataLabels) === null || _c === void 0 ? void 0 : _c.anchor) === 'outer';
67
+ }
68
+ export function hasOuterPieSeriesName(options, series) {
69
+ var _a, _b, _c, _d;
70
+ return (!!series.pie &&
71
+ ((_d = (_c = (_b = (_a = options) === null || _a === void 0 ? void 0 : _a.series) === null || _b === void 0 ? void 0 : _b.dataLabels) === null || _c === void 0 ? void 0 : _c.pieSeriesName) === null || _d === void 0 ? void 0 : _d.anchor) === 'outer');
72
+ }
@@ -0,0 +1,2 @@
1
+ import { PlotLine, PlotBand, GaugePlotBand } from "../../types/options";
2
+ export declare function isExistPlotId<T extends PlotLine | PlotBand | GaugePlotBand>(plots: T[], data: T): boolean;
@@ -0,0 +1,4 @@
1
+ import { isUndefined } from "./utils";
2
+ export function isExistPlotId(plots, data) {
3
+ return plots.some(({ id: bandId }) => !isUndefined(bandId) && !isUndefined(data.id) && bandId === data.id);
4
+ }
@@ -0,0 +1 @@
1
+ export declare function getRadialRadiusValues(labels: string[], size: number, deleteCount?: number): number[];
@@ -0,0 +1,7 @@
1
+ export function getRadialRadiusValues(labels, size, deleteCount = 0) {
2
+ const result = labels.map((_, index) => (index / (labels.length - 1)) * size);
3
+ if (deleteCount) {
4
+ result.splice(result.length - deleteCount);
5
+ }
6
+ return result;
7
+ }
@@ -0,0 +1,6 @@
1
+ import { RangeDataType, BoxSeriesDataType } from "../../types/options";
2
+ import { TooltipDataValue } from "../../types/components/tooltip";
3
+ export declare function isRangeValue<T>(value: unknown): value is RangeDataType<T>;
4
+ export declare function isRangeData(data?: BoxSeriesDataType[] | TooltipDataValue): boolean;
5
+ export declare function isZooming(categories: string[], zoomRange?: RangeDataType<number>): boolean;
6
+ export declare function getDataInRange<T>(data: T[], range?: RangeDataType<number>): T[];
@@ -0,0 +1,16 @@
1
+ import { getFirstValidValue } from "./utils";
2
+ export function isRangeValue(value) {
3
+ return Array.isArray(value) && value.length === 2;
4
+ }
5
+ export function isRangeData(data) {
6
+ return Array.isArray(data) && isRangeValue(getFirstValidValue(data));
7
+ }
8
+ export function isZooming(categories, zoomRange) {
9
+ return !!(zoomRange && (zoomRange[0] !== 0 || zoomRange[1] !== categories.length - 1));
10
+ }
11
+ export function getDataInRange(data, range) {
12
+ if (!range) {
13
+ return data;
14
+ }
15
+ return data.slice(range[0], range[1] + 1);
16
+ }
@@ -0,0 +1,37 @@
1
+ import { BoxPlotResponderModel, BulletResponderModel, CircleModel, CircleResponderModel, HeatmapRectResponderModel, SectorResponderModel, RectResponderModel, TreemapRectResponderModel, ResponderModel, GroupedSectorResponderModel, GaugeResponderModel } from "../../types/components/series";
2
+ import { LineTypeEventDetectType, Point, Rect } from "../../types/options";
3
+ import { LabelAxisData } from "../../types/store/store";
4
+ import { TooltipData } from "../../types/components/tooltip";
5
+ export declare type RespondersThemeType = 'select' | 'hover';
6
+ export interface SelectedSeriesEventModel {
7
+ models: ResponderModel[];
8
+ comparisonModel: ResponderModel[];
9
+ name: string;
10
+ eventDetectType?: LineTypeEventDetectType;
11
+ alias?: string;
12
+ }
13
+ export interface RectResponderInfoForCoordinateType {
14
+ x: number;
15
+ label: string;
16
+ }
17
+ export declare function isSameSeriesResponder({ models, comparisonModel, name, eventDetectType, }: SelectedSeriesEventModel): boolean | 0 | undefined;
18
+ export declare function getNearestResponder(responders: CircleResponderModel[], mousePosition: Point, rect: Rect): CircleResponderModel[];
19
+ export declare function makeRectResponderModel(rect: Rect, axis: LabelAxisData, categories: string[], vertical?: boolean): RectResponderModel[];
20
+ export declare function makeRectResponderModelForCoordinateType(responderInfo: RectResponderInfoForCoordinateType[], rect: Rect): RectResponderModel[];
21
+ export declare function makeTooltipCircleMap(seriesCircleModel: CircleModel[], tooltipDataArr: TooltipData[]): Record<string, CircleResponderModel[]>;
22
+ export declare function getDeepestNode(responders: TreemapRectResponderModel[]): TreemapRectResponderModel[];
23
+ export declare function isClickSameNameResponder<T extends HeatmapRectResponderModel | BulletResponderModel | GaugeResponderModel>(responders: T[], selectedSeries?: T[]): boolean | 0 | undefined;
24
+ export declare function isClickSameCircleResponder(responders: CircleResponderModel[], selectedSeries?: CircleResponderModel[]): boolean;
25
+ export declare function isClickSameDataResponder<T extends RectResponderModel | BoxPlotResponderModel | SectorResponderModel>(responders: T[], selectedSeries?: T[]): boolean;
26
+ export declare function isClickSameLabelResponder(responders: TreemapRectResponderModel[], selectedSeries?: TreemapRectResponderModel[]): boolean | 0 | undefined;
27
+ export declare function isClickSameGroupedRectResponder(responders: RectResponderModel[], selectedSeries?: RectResponderModel[]): boolean | 0 | undefined;
28
+ export declare function isClickSameBoxPlotDataResponder(responders: BoxPlotResponderModel[], selectedSeries?: BoxPlotResponderModel[]): boolean;
29
+ export declare function makeGroupedSectorResponderModel(radiusRanges: number[], renderOptions: {
30
+ centerX: number;
31
+ centerY: number;
32
+ angleRange: {
33
+ start: number;
34
+ end: number;
35
+ };
36
+ clockwise: boolean;
37
+ }, categories: string[]): GroupedSectorResponderModel[];
@@ -0,0 +1,197 @@
1
+ import { getDistance } from "./calculator";
2
+ import { range } from "./utils";
3
+ import { getRadiusRanges } from "./sector";
4
+ // eslint-disable-next-line complexity
5
+ export function isSameSeriesResponder({ models, comparisonModel, name, eventDetectType, }) {
6
+ switch (name) {
7
+ case 'heatmap':
8
+ return isClickSameNameResponder(models, comparisonModel);
9
+ case 'bullet':
10
+ return eventDetectType === 'grouped'
11
+ ? isClickSameGroupedRectResponder(models, comparisonModel)
12
+ : isClickSameNameResponder(models, comparisonModel);
13
+ case 'radar':
14
+ case 'bubble':
15
+ case 'scatter':
16
+ case 'area':
17
+ case 'line':
18
+ return isClickSameCircleResponder(models, comparisonModel);
19
+ case 'pie':
20
+ return isClickSameDataResponder(models, comparisonModel);
21
+ case 'column':
22
+ case 'bar':
23
+ return eventDetectType === 'grouped'
24
+ ? isClickSameGroupedRectResponder(models, comparisonModel)
25
+ : isClickSameDataResponder(models, comparisonModel);
26
+ case 'boxPlot':
27
+ return eventDetectType === 'grouped'
28
+ ? isClickSameDataResponder(models, comparisonModel)
29
+ : isClickSameBoxPlotDataResponder(models, comparisonModel);
30
+ case 'treemap':
31
+ return isClickSameLabelResponder(models, comparisonModel);
32
+ case 'gauge':
33
+ return isClickSameNameResponder(models, comparisonModel);
34
+ default:
35
+ return false;
36
+ }
37
+ }
38
+ export function getNearestResponder(responders, mousePosition, rect) {
39
+ let minDistance = Infinity;
40
+ let result = [];
41
+ responders.forEach((responder) => {
42
+ const { x, y, radius } = responder;
43
+ const responderPoint = { x: x + rect.x, y: y + rect.y };
44
+ const distance = getDistance(responderPoint, mousePosition);
45
+ if (minDistance > distance) {
46
+ minDistance = distance;
47
+ result = [responder];
48
+ }
49
+ else if (minDistance === distance) {
50
+ if (result.length && result[0].radius > radius) {
51
+ result = [responder];
52
+ }
53
+ else {
54
+ result.push(responder);
55
+ }
56
+ }
57
+ });
58
+ return result;
59
+ }
60
+ export function makeRectResponderModel(rect, axis, categories, vertical = true) {
61
+ const { pointOnColumn, tickDistance, rectResponderCount } = axis;
62
+ const { width, height } = rect;
63
+ const halfDetectAreaIndex = pointOnColumn ? [] : [0, rectResponderCount - 1];
64
+ const halfSize = tickDistance / 2;
65
+ return range(0, rectResponderCount).map((index) => {
66
+ const half = halfDetectAreaIndex.includes(index);
67
+ const size = half ? halfSize : tickDistance;
68
+ let startPos = 0;
69
+ if (index !== 0) {
70
+ startPos += pointOnColumn ? tickDistance * index : halfSize + tickDistance * (index - 1);
71
+ }
72
+ return {
73
+ type: 'rect',
74
+ y: vertical ? 0 : startPos,
75
+ height: vertical ? height : size,
76
+ x: vertical ? startPos : 0,
77
+ width: vertical ? size : width,
78
+ index,
79
+ label: categories[index],
80
+ };
81
+ });
82
+ }
83
+ export function makeRectResponderModelForCoordinateType(responderInfo, rect) {
84
+ const { width, height } = rect;
85
+ let startPos = 0;
86
+ return responderInfo
87
+ .sort((a, b) => a.x - b.x)
88
+ .reduce((acc, model, index) => {
89
+ const { x, label } = model;
90
+ const next = responderInfo[index + 1];
91
+ const endPos = next ? (next.x + x) / 2 : width;
92
+ const rectResponderModel = {
93
+ type: 'rect',
94
+ x: startPos,
95
+ y: 0,
96
+ width: endPos - startPos,
97
+ height,
98
+ label,
99
+ index,
100
+ };
101
+ startPos = endPos;
102
+ return [...acc, rectResponderModel];
103
+ }, []);
104
+ }
105
+ export function makeTooltipCircleMap(seriesCircleModel, tooltipDataArr) {
106
+ const dataMap = tooltipDataArr.reduce((acc, cur) => {
107
+ const { index, seriesIndex } = cur;
108
+ if (!acc[seriesIndex]) {
109
+ acc[seriesIndex] = [];
110
+ }
111
+ acc[seriesIndex][index] = cur;
112
+ return acc;
113
+ }, []);
114
+ return seriesCircleModel.reduce((acc, model) => {
115
+ const { seriesIndex, index } = model;
116
+ const data = dataMap[seriesIndex][index];
117
+ const { category } = data;
118
+ if (!category) {
119
+ return acc;
120
+ }
121
+ if (!acc[category]) {
122
+ acc[category] = [];
123
+ }
124
+ acc[category].push(Object.assign(Object.assign({}, model), { data }));
125
+ return acc;
126
+ }, {});
127
+ }
128
+ export function getDeepestNode(responders) {
129
+ return responders.reduce((acc, responder) => {
130
+ if (!acc.length || responder.depth > acc[0].depth) {
131
+ return [responder];
132
+ }
133
+ return acc;
134
+ }, []);
135
+ }
136
+ export function isClickSameNameResponder(responders, selectedSeries) {
137
+ var _a;
138
+ return (responders.length && ((_a = selectedSeries) === null || _a === void 0 ? void 0 : _a.length) && responders[0].name === selectedSeries[0].name);
139
+ }
140
+ export function isClickSameCircleResponder(responders, selectedSeries) {
141
+ var _a;
142
+ let same = false;
143
+ if (responders.length && ((_a = selectedSeries) === null || _a === void 0 ? void 0 : _a.length) && responders.length === selectedSeries.length) {
144
+ same = responders.reduce((acc, cur, idx) => {
145
+ return (acc &&
146
+ cur.seriesIndex === selectedSeries[idx].seriesIndex &&
147
+ cur.index === selectedSeries[idx].index);
148
+ }, true);
149
+ }
150
+ return same;
151
+ }
152
+ export function isClickSameDataResponder(responders, selectedSeries) {
153
+ var _a;
154
+ let same = false;
155
+ if (responders.length && ((_a = selectedSeries) === null || _a === void 0 ? void 0 : _a.length) && responders.length === selectedSeries.length) {
156
+ same = responders.reduce((acc, cur, idx) => {
157
+ var _a, _b, _c, _d;
158
+ return (acc &&
159
+ ((_a = cur.data) === null || _a === void 0 ? void 0 : _a.label) === ((_b = selectedSeries[idx].data) === null || _b === void 0 ? void 0 : _b.label) &&
160
+ ((_c = cur.data) === null || _c === void 0 ? void 0 : _c.category) === ((_d = selectedSeries[idx].data) === null || _d === void 0 ? void 0 : _d.category));
161
+ }, true);
162
+ }
163
+ return same;
164
+ }
165
+ export function isClickSameLabelResponder(responders, selectedSeries) {
166
+ var _a;
167
+ return (responders.length && ((_a = selectedSeries) === null || _a === void 0 ? void 0 : _a.length) && responders[0].label === selectedSeries[0].label);
168
+ }
169
+ export function isClickSameGroupedRectResponder(responders, selectedSeries) {
170
+ var _a;
171
+ return (responders.length && ((_a = selectedSeries) === null || _a === void 0 ? void 0 : _a.length) && responders[0].index === selectedSeries[0].index);
172
+ }
173
+ export function isClickSameBoxPlotDataResponder(responders, selectedSeries) {
174
+ var _a, _b, _c, _d, _e;
175
+ let same = false;
176
+ if (responders.length && ((_a = selectedSeries) === null || _a === void 0 ? void 0 : _a.length)) {
177
+ const { type, data } = responders[0];
178
+ same =
179
+ type === selectedSeries[0].type &&
180
+ ((_b = data) === null || _b === void 0 ? void 0 : _b.label) === ((_c = selectedSeries[0].data) === null || _c === void 0 ? void 0 : _c.label) &&
181
+ ((_d = data) === null || _d === void 0 ? void 0 : _d.category) === ((_e = selectedSeries[0].data) === null || _e === void 0 ? void 0 : _e.category);
182
+ }
183
+ return same;
184
+ }
185
+ export function makeGroupedSectorResponderModel(radiusRanges, renderOptions, categories) {
186
+ const { centerX, centerY, angleRange: { start, end }, clockwise, } = renderOptions;
187
+ return getRadiusRanges(radiusRanges, 0).map((radius, index) => ({
188
+ type: 'sector',
189
+ x: centerX,
190
+ y: centerY,
191
+ degree: { start, end },
192
+ radius,
193
+ name: categories[index],
194
+ clockwise,
195
+ index,
196
+ }));
197
+ }
@@ -0,0 +1,55 @@
1
+ import { Point, PieSeriesOptions, Rect, DataLabelAnchor, RadialBarSeriesOptions } from "../../types/options";
2
+ import { SectorModel, RadiusRange } from "../../types/components/series";
3
+ import { RadialDataLabel, RadialAnchor } from "../../types/components/dataLabels";
4
+ export declare const DEGREE_180 = 180;
5
+ export declare const DEGREE_NEGATIVE_180 = -180;
6
+ export declare const DEGREE_360 = 360;
7
+ export declare const DEGREE_0 = 0;
8
+ export declare const DEGREE_NEGATIVE_90 = -90;
9
+ export declare const DEGREE_90 = 90;
10
+ declare type RadialPositionParam = {
11
+ anchor: DataLabelAnchor;
12
+ x: number;
13
+ y: number;
14
+ radius: {
15
+ inner: number;
16
+ outer: number;
17
+ };
18
+ degree: {
19
+ start: number;
20
+ end: number;
21
+ };
22
+ drawingStartAngle?: number;
23
+ };
24
+ export declare function makeAnchorPositionParam(anchor: DataLabelAnchor, model: SectorModel | RadialDataLabel): {
25
+ radius: {
26
+ inner: number;
27
+ outer: number;
28
+ };
29
+ x: number;
30
+ y: number;
31
+ degree: {
32
+ start: number;
33
+ end: number;
34
+ };
35
+ drawingStartAngle?: number | undefined;
36
+ anchor: DataLabelAnchor;
37
+ };
38
+ export declare function calculateDegreeToRadian(degree: number, drawingStartAngle?: number): number;
39
+ export declare function calculateRadianToDegree(radian: number, drawingStartAngle?: number): number;
40
+ export declare function getRadialAnchorPosition(param: RadialPositionParam): Point;
41
+ export declare function getRadialPosition(x: number, y: number, r: number, radian: number): {
42
+ x: number;
43
+ y: number;
44
+ };
45
+ export declare function withinRadian(clockwise: boolean, startDegree: number, endDegree: number, currentDegree: number): boolean;
46
+ export declare function initSectorOptions(options?: PieSeriesOptions | RadialBarSeriesOptions): {
47
+ clockwise: boolean;
48
+ startAngle: number;
49
+ endAngle: number;
50
+ };
51
+ export declare function getDefaultRadius({ width, height }: Rect, isSemiCircular?: boolean, maxLabelWidth?: number, maxLabelHeight?: number): number;
52
+ export declare function getRadialLabelAlign(model: Pick<RadialDataLabel, 'totalAngle' | 'degree' | 'drawingStartAngle'>, anchor: RadialAnchor, needCalculateByHalf?: boolean): "left" | "center" | "right";
53
+ export declare function getRadiusRanges(radiusRanges: number[], padding: number): RadiusRange[];
54
+ export declare function calculateValidAngle(angle: number): number;
55
+ export {};
@@ -0,0 +1,117 @@
1
+ import { pick } from "./utils";
2
+ export const DEGREE_180 = 180;
3
+ export const DEGREE_NEGATIVE_180 = -180;
4
+ export const DEGREE_360 = 360;
5
+ export const DEGREE_0 = 0;
6
+ export const DEGREE_NEGATIVE_90 = -90;
7
+ export const DEGREE_90 = 90;
8
+ const MINIMUM_RADIUS = 10;
9
+ export function makeAnchorPositionParam(anchor, model) {
10
+ return Object.assign({ anchor }, pick(model, 'x', 'y', 'radius', 'degree', 'drawingStartAngle'));
11
+ }
12
+ export function calculateDegreeToRadian(degree, drawingStartAngle = DEGREE_NEGATIVE_90) {
13
+ let result = 0;
14
+ if (degree % DEGREE_360 === 0) {
15
+ result = (Math.PI / DEGREE_180) * drawingStartAngle;
16
+ }
17
+ else if (degree >= 0) {
18
+ result = (Math.PI / DEGREE_180) * (degree + drawingStartAngle);
19
+ }
20
+ return result;
21
+ }
22
+ export function calculateRadianToDegree(radian, drawingStartAngle = DEGREE_NEGATIVE_90) {
23
+ return ((radian * DEGREE_180) / Math.PI - drawingStartAngle + DEGREE_360) % DEGREE_360;
24
+ }
25
+ export function getRadialAnchorPosition(param) {
26
+ const { anchor, x, y, radius: { inner, outer }, degree: { start, end }, drawingStartAngle = DEGREE_NEGATIVE_90, } = param;
27
+ const halfDegree = start + (end - start) / 2;
28
+ const radian = calculateDegreeToRadian(halfDegree, drawingStartAngle);
29
+ const r = anchor === 'outer' ? outer : (outer + inner) / 2;
30
+ return getRadialPosition(x, y, r, radian);
31
+ }
32
+ export function getRadialPosition(x, y, r, radian) {
33
+ return { x: Math.round(x + r * Math.cos(radian)), y: Math.round(y + r * Math.sin(radian)) };
34
+ }
35
+ export function withinRadian(clockwise, startDegree, endDegree, currentDegree) {
36
+ return clockwise
37
+ ? startDegree <= currentDegree && endDegree >= currentDegree
38
+ : startDegree >= currentDegree && endDegree <= currentDegree;
39
+ }
40
+ export function initSectorOptions(options) {
41
+ var _a, _b, _c, _d, _e, _f, _g, _h;
42
+ const clockwise = (_b = (_a = options) === null || _a === void 0 ? void 0 : _a.clockwise, (_b !== null && _b !== void 0 ? _b : true));
43
+ return {
44
+ clockwise,
45
+ startAngle: (_e = (_d = (_c = options) === null || _c === void 0 ? void 0 : _c.angleRange) === null || _d === void 0 ? void 0 : _d.start, (_e !== null && _e !== void 0 ? _e : (clockwise ? DEGREE_0 : DEGREE_360))),
46
+ endAngle: (_h = (_g = (_f = options) === null || _f === void 0 ? void 0 : _f.angleRange) === null || _g === void 0 ? void 0 : _g.end, (_h !== null && _h !== void 0 ? _h : (clockwise ? DEGREE_360 : DEGREE_0))),
47
+ };
48
+ }
49
+ export function getDefaultRadius({ width, height }, isSemiCircular = false, maxLabelWidth = 0, maxLabelHeight = 0) {
50
+ let result;
51
+ if (isSemiCircular) {
52
+ result = Math.min(width / 2, height) - maxLabelHeight;
53
+ }
54
+ else if (width > height) {
55
+ result = height / 2 - maxLabelHeight;
56
+ }
57
+ else {
58
+ result = width / 2 - maxLabelWidth;
59
+ }
60
+ return Math.max(result, MINIMUM_RADIUS);
61
+ }
62
+ function getRadian(startAngle, endAngle, drawingStartAngle, needCalculateByHalf) {
63
+ const degree = needCalculateByHalf ? (endAngle + startAngle) / 2 : startAngle;
64
+ return calculateDegreeToRadian(degree, drawingStartAngle);
65
+ }
66
+ export function getRadialLabelAlign(model, anchor, needCalculateByHalf = true) {
67
+ const { totalAngle = DEGREE_360, degree: { start, end }, drawingStartAngle = DEGREE_NEGATIVE_90, } = model;
68
+ let textAlign = 'center';
69
+ if (anchor !== 'outer') {
70
+ return textAlign;
71
+ }
72
+ const radian0 = calculateDegreeToRadian(0, drawingStartAngle);
73
+ const halfRadian = calculateDegreeToRadian(totalAngle / 2, drawingStartAngle);
74
+ const radian = getRadian(start, end, drawingStartAngle, needCalculateByHalf);
75
+ if (drawingStartAngle >= DEGREE_NEGATIVE_90 && drawingStartAngle < DEGREE_90) {
76
+ if (radian0 < radian && halfRadian > radian) {
77
+ textAlign = 'left';
78
+ }
79
+ else if (halfRadian < radian) {
80
+ textAlign = 'right';
81
+ }
82
+ }
83
+ else if (radian0 < radian && halfRadian > radian) {
84
+ textAlign = 'right';
85
+ }
86
+ else if (halfRadian < radian) {
87
+ textAlign = 'left';
88
+ }
89
+ return textAlign;
90
+ }
91
+ export function getRadiusRanges(radiusRanges, padding) {
92
+ return radiusRanges.reduce((acc, cur, index) => {
93
+ if (index) {
94
+ acc.push({
95
+ inner: cur + padding,
96
+ outer: radiusRanges[index - 1] - padding,
97
+ });
98
+ }
99
+ if (index === radiusRanges.length - 1) {
100
+ acc.push({
101
+ inner: padding,
102
+ outer: cur - padding,
103
+ });
104
+ }
105
+ return acc;
106
+ }, []);
107
+ }
108
+ // Recalculate to an angle between 0 and 360 degrees.
109
+ export function calculateValidAngle(angle) {
110
+ if (angle < DEGREE_0) {
111
+ return DEGREE_360 + (angle % DEGREE_360);
112
+ }
113
+ if (angle > DEGREE_360) {
114
+ return angle % DEGREE_360;
115
+ }
116
+ return angle;
117
+ }
@@ -0,0 +1,8 @@
1
+ import { TreemapSeriesData } from "../../types/store/store";
2
+ import { Rect } from "../../types/options";
3
+ declare type IdType = string | number;
4
+ export declare type BoundMap = {
5
+ [key in IdType]: Rect;
6
+ };
7
+ export declare function squarify(layout: Rect, seriesItems: TreemapSeriesData[]): {};
8
+ export {};
@@ -0,0 +1,110 @@
1
+ import { sum } from "./calculator";
2
+ import { pluck } from "./arrayUtil";
3
+ function calculateScale(values, width, height) {
4
+ return (width * height) / sum(values);
5
+ }
6
+ function isVerticalStack({ height, width }) {
7
+ return height < width;
8
+ }
9
+ function selectBaseSize(baseBound) {
10
+ return isVerticalStack(baseBound) ? baseBound.height : baseBound.width;
11
+ }
12
+ function makeBaseData(seriesItems, baseBound) {
13
+ const { width, height } = baseBound;
14
+ const scale = calculateScale(pluck(seriesItems, 'data'), width, height);
15
+ return seriesItems
16
+ .map((seriesItem) => ({
17
+ id: seriesItem.id,
18
+ weight: seriesItem.data * scale,
19
+ }))
20
+ .sort((a, b) => b.weight - a.weight);
21
+ }
22
+ /**
23
+ * Calculate worst aspect ratio.
24
+ * Referred function worst() in https://www.win.tue.nl/~vanwijk/stm.pdf
25
+ */
26
+ function worst(total, min, max, baseSize) {
27
+ const sumSquare = total * total;
28
+ const sizeSquare = baseSize * baseSize;
29
+ return Math.max((sizeSquare * max) / sumSquare, sumSquare / (sizeSquare * min));
30
+ }
31
+ function changedStackDirection(total, weights, baseSize, newWeight) {
32
+ const minWeight = Math.min(...weights);
33
+ const maxWeight = Math.max(...weights);
34
+ const beforeWorst = worst(total, minWeight, maxWeight, baseSize);
35
+ const newWorst = worst(total + newWeight, Math.min(minWeight, newWeight), Math.max(maxWeight, newWeight), baseSize);
36
+ return newWorst >= beforeWorst;
37
+ }
38
+ function calculateFixedSize(baseSize, total, rows) {
39
+ if (!total) {
40
+ const weights = pluck(rows, 'weight');
41
+ total = sum(weights);
42
+ }
43
+ return total / baseSize;
44
+ }
45
+ function addBounds(startPosition, rows, fixedSize, callback) {
46
+ rows.reduce((storedPosition, rowDatum) => {
47
+ const dynamicSize = rowDatum.weight / fixedSize;
48
+ callback(dynamicSize, storedPosition, rowDatum.id);
49
+ return storedPosition + dynamicSize;
50
+ }, startPosition);
51
+ }
52
+ function addBound(boundMap, id, rect) {
53
+ boundMap[id] = rect;
54
+ }
55
+ function addBoundsForVerticalStack(boundMap, rows, baseBound, baseSize, total) {
56
+ const fixedWidth = calculateFixedSize(baseSize, total, rows);
57
+ addBounds(baseBound.y, rows, fixedWidth, (dynamicHeight, storedTop, id) => {
58
+ addBound(boundMap, id, {
59
+ x: baseBound.x,
60
+ y: storedTop,
61
+ width: fixedWidth,
62
+ height: dynamicHeight,
63
+ });
64
+ });
65
+ baseBound.x += fixedWidth;
66
+ baseBound.width -= fixedWidth;
67
+ }
68
+ function addBoundsForHorizontalStack(boundMap, rows, baseBound, baseSize, total) {
69
+ const fixedHeight = calculateFixedSize(baseSize, total, rows);
70
+ addBounds(baseBound.x, rows, fixedHeight, (dynamicWidth, storedLeft, id) => {
71
+ addBound(boundMap, id, {
72
+ x: storedLeft,
73
+ y: baseBound.y,
74
+ width: dynamicWidth,
75
+ height: fixedHeight,
76
+ });
77
+ });
78
+ baseBound.y += fixedHeight;
79
+ baseBound.height -= fixedHeight;
80
+ }
81
+ function getAddingBoundsFunction(baseBound) {
82
+ if (isVerticalStack(baseBound)) {
83
+ return addBoundsForVerticalStack;
84
+ }
85
+ return addBoundsForHorizontalStack;
86
+ }
87
+ export function squarify(layout, seriesItems) {
88
+ const baseBound = layout;
89
+ const baseData = makeBaseData(seriesItems, baseBound);
90
+ let row = [];
91
+ let baseSize, addBoundsFunc;
92
+ const boundMap = {};
93
+ baseData.forEach((datum) => {
94
+ const weights = pluck(row, 'weight');
95
+ const totalWeight = sum(weights);
96
+ if (row.length && changedStackDirection(totalWeight, weights, baseSize, datum.weight)) {
97
+ addBoundsFunc(boundMap, row, baseBound, baseSize, totalWeight);
98
+ row = [];
99
+ }
100
+ if (!row.length) {
101
+ baseSize = selectBaseSize(baseBound);
102
+ addBoundsFunc = getAddingBoundsFunction(baseBound);
103
+ }
104
+ row.push(datum);
105
+ });
106
+ if (row.length) {
107
+ addBoundsFunc(boundMap, row, baseBound, baseSize);
108
+ }
109
+ return boundMap;
110
+ }