@mapcreator/sdk 0.0.9 → 0.0.10

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 (120) hide show
  1. package/dist/{esm/HighlightManager.d.ts → HighlightManager.d.ts} +2 -2
  2. package/dist/{esm/MCMap.d.ts → MCMap.d.ts} +1 -1
  3. package/dist/{esm/PopupManager.d.ts → PopupManager.d.ts} +4 -4
  4. package/dist/{esm/Registry.d.ts → Registry.d.ts} +3 -3
  5. package/dist/{esm/adornments → adornments}/categoricalLegend.d.ts +1 -1
  6. package/dist/{esm/adornments → adornments}/connectedLegend.d.ts +2 -2
  7. package/dist/{esm/adornments → adornments}/customAdornment.d.ts +1 -1
  8. package/dist/{esm/adornments → adornments}/heading.d.ts +1 -1
  9. package/dist/adornments/insetMap.d.ts +3 -0
  10. package/dist/{esm/adornments → adornments}/manualLegend.d.ts +1 -1
  11. package/dist/adornments/northArrow.d.ts +3 -0
  12. package/dist/adornments/scalebar.d.ts +3 -0
  13. package/dist/{esm/constants → constants}/index.d.ts +2 -2
  14. package/dist/{esm/controls → controls}/fullscreenControls.d.ts +1 -1
  15. package/dist/{esm/controls → controls}/geocoderControl.d.ts +1 -1
  16. package/dist/{esm/controls → controls}/geolocationControls.d.ts +1 -1
  17. package/dist/controls/refreshMapControls.d.ts +3 -0
  18. package/dist/controls/webControls.d.ts +4 -0
  19. package/dist/{esm/controls → controls}/zoomControls.d.ts +1 -1
  20. package/dist/index.d.ts +3 -0
  21. package/dist/locales/da_DK/strings.json.d.ts +10 -0
  22. package/dist/locales/de_DE/strings.json.d.ts +10 -0
  23. package/dist/locales/en_GB/strings.json.d.ts +10 -0
  24. package/dist/locales/es_ES/strings.json.d.ts +10 -0
  25. package/dist/locales/fr_FR/strings.json.d.ts +10 -0
  26. package/dist/locales/it_IT/strings.json.d.ts +10 -0
  27. package/dist/locales/nl_NL/strings.json.d.ts +10 -0
  28. package/dist/mapcreator-sdk.js +39590 -0
  29. package/dist/models/area.d.ts +5 -0
  30. package/dist/models/circle.d.ts +5 -0
  31. package/dist/models/dot.d.ts +3 -0
  32. package/dist/models/line.d.ts +4 -0
  33. package/dist/models/marker.d.ts +5 -0
  34. package/dist/models/polygon.d.ts +5 -0
  35. package/dist/{esm/renderAdornments.d.ts → renderAdornments.d.ts} +3 -3
  36. package/dist/{esm/types → types}/index.d.ts +1 -1
  37. package/dist/{esm/types → types}/mapstyle.d.ts +2 -6
  38. package/dist/{esm/utils → utils}/choropleth.d.ts +3 -3
  39. package/dist/{esm/utils → utils}/geolocation.d.ts +1 -1
  40. package/dist/{esm/utils → utils}/graphhopper.d.ts +1 -1
  41. package/dist/{esm/utils → utils}/helpers.d.ts +2 -2
  42. package/dist/{esm/utils → utils}/language.d.ts +1 -1
  43. package/dist/{esm/utils → utils}/models.d.ts +4 -4
  44. package/dist/{esm/utils → utils}/overlays.d.ts +1 -1
  45. package/dist/{esm/utils → utils}/svgHelpers.d.ts +3 -4
  46. package/dist/{esm/utils → utils}/template.d.ts +2 -2
  47. package/dist/{esm/utils → utils}/youtube.d.ts +1 -1
  48. package/package.json +7 -6
  49. package/dist/esm/HighlightManager.js +0 -203
  50. package/dist/esm/MCMap.js +0 -254
  51. package/dist/esm/PopupManager.js +0 -297
  52. package/dist/esm/Registry.js +0 -74
  53. package/dist/esm/adornments/categoricalLegend.js +0 -141
  54. package/dist/esm/adornments/connectedLegend.js +0 -393
  55. package/dist/esm/adornments/customAdornment.js +0 -29
  56. package/dist/esm/adornments/heading.js +0 -71
  57. package/dist/esm/adornments/insetMap.d.ts +0 -3
  58. package/dist/esm/adornments/insetMap.js +0 -351
  59. package/dist/esm/adornments/manualLegend.js +0 -15
  60. package/dist/esm/adornments/northArrow.d.ts +0 -3
  61. package/dist/esm/adornments/northArrow.js +0 -24
  62. package/dist/esm/adornments/scalebar.d.ts +0 -3
  63. package/dist/esm/adornments/scalebar.js +0 -176
  64. package/dist/esm/constants/index.js +0 -53
  65. package/dist/esm/controls/controls.js +0 -7
  66. package/dist/esm/controls/fullscreenControls.js +0 -29
  67. package/dist/esm/controls/geocoderControl.js +0 -202
  68. package/dist/esm/controls/geolocationControls.js +0 -65
  69. package/dist/esm/controls/refreshMapControls.d.ts +0 -3
  70. package/dist/esm/controls/refreshMapControls.js +0 -26
  71. package/dist/esm/controls/webControls.d.ts +0 -4
  72. package/dist/esm/controls/webControls.js +0 -40
  73. package/dist/esm/controls/zoomControls.js +0 -23
  74. package/dist/esm/i18n.js +0 -21
  75. package/dist/esm/index.d.ts +0 -5
  76. package/dist/esm/index.js +0 -5
  77. package/dist/esm/locales/da_DK/strings.json +0 -7
  78. package/dist/esm/locales/de_DE/strings.json +0 -7
  79. package/dist/esm/locales/en_GB/strings.json +0 -7
  80. package/dist/esm/locales/es_ES/strings.json +0 -7
  81. package/dist/esm/locales/fr_FR/strings.json +0 -7
  82. package/dist/esm/locales/it_IT/strings.json +0 -7
  83. package/dist/esm/locales/nl_NL/strings.json +0 -7
  84. package/dist/esm/models/area.d.ts +0 -5
  85. package/dist/esm/models/area.js +0 -165
  86. package/dist/esm/models/circle.d.ts +0 -5
  87. package/dist/esm/models/circle.js +0 -110
  88. package/dist/esm/models/dot.d.ts +0 -3
  89. package/dist/esm/models/dot.js +0 -42
  90. package/dist/esm/models/line.d.ts +0 -4
  91. package/dist/esm/models/line.js +0 -117
  92. package/dist/esm/models/marker.d.ts +0 -5
  93. package/dist/esm/models/marker.js +0 -179
  94. package/dist/esm/models/polygon.d.ts +0 -5
  95. package/dist/esm/models/polygon.js +0 -80
  96. package/dist/esm/renderAdornments.js +0 -129
  97. package/dist/esm/types/geometry.js +0 -1
  98. package/dist/esm/types/index.js +0 -1
  99. package/dist/esm/types/jobObject.js +0 -1
  100. package/dist/esm/types/mapstyle.js +0 -1
  101. package/dist/esm/utils/browser.js +0 -6
  102. package/dist/esm/utils/choropleth.js +0 -110
  103. package/dist/esm/utils/fullscreen.js +0 -40
  104. package/dist/esm/utils/geolocation.js +0 -93
  105. package/dist/esm/utils/graphhopper.js +0 -41
  106. package/dist/esm/utils/helpers.js +0 -116
  107. package/dist/esm/utils/language.js +0 -170
  108. package/dist/esm/utils/models.js +0 -103
  109. package/dist/esm/utils/overlays.js +0 -87
  110. package/dist/esm/utils/scalebar.js +0 -52
  111. package/dist/esm/utils/svgHelpers.js +0 -1512
  112. package/dist/esm/utils/template.js +0 -120
  113. package/dist/esm/utils/youtube.js +0 -64
  114. /package/dist/{esm/controls → controls}/controls.d.ts +0 -0
  115. /package/dist/{esm/i18n.d.ts → i18n.d.ts} +0 -0
  116. /package/dist/{esm/types → types}/geometry.d.ts +0 -0
  117. /package/dist/{esm/types → types}/jobObject.d.ts +0 -0
  118. /package/dist/{esm/utils → utils}/browser.d.ts +0 -0
  119. /package/dist/{esm/utils → utils}/fullscreen.d.ts +0 -0
  120. /package/dist/{esm/utils → utils}/scalebar.d.ts +0 -0
@@ -1,393 +0,0 @@
1
- import { groupByColor, getColumnName, legendTickCount, getColorGenerator, isChoroplethColumn, } from '@/utils/choropleth';
2
- import { formatLocale } from 'd3-format';
3
- import { extent, ticks as calcTicks } from 'd3-array';
4
- import { lerp, unlerp, clamp } from '@/utils/helpers';
5
- import { escapeXML, loadFonts, measureTextBlock } from '@/utils/svgHelpers';
6
- import { getCategoricalLegendSvg } from '@/adornments/categoricalLegend';
7
- const defaultFont = 'ArialMT';
8
- const padding = 15;
9
- export function useConnectedLegend(legend, jobObject, map, vapiUrl, accessToken) {
10
- const container = document.createElement('div');
11
- container.className = 'adornment';
12
- if (legend.showBackground) {
13
- container.style.boxShadow = '0 0 7px 0 rgba(33, 37, 41, 0.25)';
14
- container.style.borderRadius = '10px';
15
- }
16
- const fonts = [legend.titleFont ?? defaultFont, legend.labelFont ?? defaultFont];
17
- const fontsToLoad = Array.from(new Set(fonts));
18
- loadFonts(fontsToLoad, vapiUrl, accessToken).then(() => (container.innerHTML = getSvg(legend, jobObject, map)));
19
- return container;
20
- }
21
- function getSvg(legend, jobObject, map) {
22
- const { target } = legend;
23
- const group = jobObject.registry?.models?.[target.modelType]?.find(g => g.id === target.groupId);
24
- const bindings = group?.models ?? [];
25
- const choropleth = group?.choropleth;
26
- const dataColumn = getColumnName(group?.fillColor);
27
- return !choropleth ||
28
- !dataColumn ||
29
- group.models.every(area => !(area.visible ?? true)) ||
30
- !isChoroplethColumn(bindings, dataColumn)
31
- ? renderBlankLegend()
32
- : choropleth.colorMode === 'categorical'
33
- ? renderCategoricalLegend(legend, choropleth, dataColumn)
34
- : choropleth.colorMode === 'linear'
35
- ? renderContinuousLegend(legend, group, map)
36
- : choropleth.colorMode === 'quantile' || choropleth.colorMode === 'quantize'
37
- ? renderDiscreteLegend(legend, group, map)
38
- : renderBlankLegend();
39
- }
40
- function renderBlankLegend() {
41
- return `
42
- <svg
43
- xmlns="http://www.w3.org/2000/svg"
44
- width="0"
45
- height="0"
46
- viewBox="0 0 0 0"
47
- style="display: block;"
48
- >
49
- </svg>
50
- `;
51
- }
52
- function renderContinuousLegend(legend, group, map) {
53
- const barThickness = 15;
54
- const stopCount = 32;
55
- const barEndRadius = barThickness / 2;
56
- const titleMargin = 10;
57
- const tickLength = 20;
58
- const tickLabelMargin = 5;
59
- const { id, layout = 'vertical', labelFont = defaultFont, labelFontSize = 13, labelFontColor = '#000000', numberFormat = '.2~s', title = '', titleFont = defaultFont, titleFontSize = 14, titleFontColor = '#000000', showBackground = false, background = '#ffffff', } = legend;
60
- const gradientId = `gradient-${id}`;
61
- const isHorizontal = layout === 'horizontal';
62
- const colorGenerator = getColorGenerator(group);
63
- if (colorGenerator === undefined) {
64
- return renderBlankLegend();
65
- }
66
- const children = [];
67
- const [min, max] = extent(colorGenerator.domain());
68
- const ticks = calcTicks(min, max, legendTickCount);
69
- const formatLabel = getFormatter(numberFormat);
70
- const tickLabels = ticks.map(tick => formatLabel(tick));
71
- const tickLabelBoxes = tickLabels.map(label => measureTextBlock([label], labelFont, labelFontSize));
72
- const stops = [];
73
- for (let i = 0; i < stopCount; i++) {
74
- const t = i / (stopCount - 1);
75
- stops.push(`<stop offset="${t * 100}%" stop-color="${colorGenerator(min + t * (max - min))}" />`);
76
- }
77
- const transform = !isHorizontal ? 'rotate(90)' : '';
78
- children.push(`
79
- <defs>
80
- <linearGradient id="${gradientId}" gradientTransform="${transform}">
81
- ${stops.join('')}
82
- </linearGradient>
83
- </defs>
84
- `);
85
- const titleBox = measureTextBlock([title], titleFont, titleFontSize);
86
- const hasTitle = title.trim().length > 0;
87
- const labelBox = {
88
- width: Math.max(0, ...tickLabelBoxes.map(b => b.width)),
89
- height: Math.max(0, ...tickLabelBoxes.map(b => b.height)),
90
- ascent: Math.max(0, ...tickLabelBoxes.map(b => b.ascent)),
91
- };
92
- const titleBoxHeight = hasTitle ? titleBox.height + titleMargin : 0;
93
- const titleBoxWidth = hasTitle ? titleBox.width : 0;
94
- const count = ticks.length - 1;
95
- const barLength = clamp(45 * count, isHorizontal
96
- ? Math.ceil((labelBox.width + 10) * count)
97
- : Math.ceil((labelBox.height + 10) * count), isHorizontal
98
- ? Math.floor(map.getContainer().clientWidth - 10 - padding * 2)
99
- : Math.floor(map.getContainer().clientHeight - 10 - padding * 2 - titleBoxHeight));
100
- const width = isHorizontal
101
- ? Math.ceil(padding * 2 + Math.max(titleBoxWidth, barLength))
102
- : Math.ceil(padding * 2 + Math.max(titleBoxWidth, tickLength + tickLabelMargin + labelBox.width));
103
- const height = isHorizontal
104
- ? Math.ceil(padding * 2 + titleBoxHeight + tickLength + tickLabelMargin + labelBox.ascent)
105
- : Math.ceil(padding * 2 + titleBoxHeight + barLength);
106
- if (showBackground) {
107
- children.push(`
108
- <rect
109
- x="0"
110
- y="0"
111
- rx="10"
112
- ry="10"
113
- width="${width}"
114
- height="${height}"
115
- fill="${background}"
116
- />
117
- `);
118
- }
119
- const x = padding;
120
- let y = padding;
121
- if (hasTitle) {
122
- children.push(`
123
- <text
124
- x="${x}"
125
- y="${y + titleBox.ascent}"
126
- font-family="${titleFont}"
127
- font-size="${titleFontSize}"
128
- fill="${titleFontColor}"
129
- >
130
- ${escapeXML(title)}
131
- </text>
132
- `);
133
- y += titleBox.height + titleMargin;
134
- }
135
- children.push(`
136
- <rect
137
- x="${x}"
138
- y="${y}"
139
- rx="${barEndRadius}"
140
- ry="${barEndRadius}"
141
- width="${isHorizontal ? barLength : barThickness}"
142
- height="${isHorizontal ? barThickness : barLength}"
143
- fill="url(#${gradientId})"
144
- />
145
- `);
146
- for (let i = 1; i < ticks.length - 1; i++) {
147
- const tick = ticks[i];
148
- const label = tickLabels[i];
149
- const box = tickLabelBoxes[i];
150
- const offset = lerp(0, barLength, unlerp(min, max, tick));
151
- if (offset > barEndRadius && offset < barLength - barEndRadius) {
152
- children.push(`
153
- <line
154
- x1="${isHorizontal ? Math.floor(x + offset) + 0.5 : x}"
155
- y1="${isHorizontal ? y : Math.floor(y + offset) + 0.5}"
156
- x2="${isHorizontal ? Math.floor(x + offset) + 0.5 : x + tickLength}"
157
- y2="${isHorizontal ? y + tickLength : Math.floor(y + offset) + 0.5}"
158
- stroke="#ffffff"
159
- />
160
- `);
161
- }
162
- children.push(`
163
- <text
164
- x="${isHorizontal ? x + offset : x + tickLength + tickLabelMargin}"
165
- y="${isHorizontal
166
- ? y + tickLength + tickLabelMargin + box.ascent
167
- : y + offset - box.descent + box.height / 2}"
168
- font-family="${labelFont}"
169
- font-size="${labelFontSize}"
170
- fill="${labelFontColor}"
171
- text-anchor="${isHorizontal ? 'middle' : 'start'}"
172
- >
173
- ${escapeXML(label)}
174
- </text>
175
- `);
176
- }
177
- return `
178
- <svg
179
- xmlns="http://www.w3.org/2000/svg"
180
- width="${width}"
181
- height="${height}"
182
- viewBox="0 0 ${width} ${height}"
183
- style="display: block;"
184
- >
185
- ${children.join('')}
186
- </svg>
187
- `;
188
- }
189
- function renderDiscreteLegend(legend, group, map) {
190
- const gap = 10;
191
- const colorGenerator = getColorGenerator(group);
192
- const colors = colorGenerator?.range();
193
- const children = [];
194
- let height = 0;
195
- let width = 0;
196
- if (colorGenerator && colors && colors.length > 1) {
197
- const { layout = 'vertical', labelFont = defaultFont, labelFontSize = 13, labelFontColor = '#000000', labelStyle = 'range', numberFormat = '.2~s', title = '', titleFont = defaultFont, titleFontSize = 14, titleFontColor = '#000000', showBackground = false, background = '#ffffff', } = legend;
198
- const isVertical = layout === 'vertical';
199
- const isRange = labelStyle === 'range';
200
- const formatLabel = getFormatter(numberFormat);
201
- const labels = isRange
202
- ? colors
203
- .map(color => colorGenerator.invertExtent(color))
204
- .map((range, index, array) => index === 0
205
- ? `< ${formatLabel(range[1])}`
206
- : index === array.length - 1
207
- ? `> ${formatLabel(range[0])}`
208
- : `${formatLabel(range[0])} – ${formatLabel(range[1])}`)
209
- : colors
210
- .map(color => colorGenerator.invertExtent(color))
211
- .reduce((g, range, index) => (index && g.push(formatLabel(range[0])), g), []);
212
- const lBoxes = labels.map(label => measureTextBlock([label], labelFont, labelFontSize));
213
- const titleBox = measureTextBlock([title], titleFont, titleFontSize);
214
- const hasTitle = title.trim().length > 0;
215
- const labelBox = {
216
- width: Math.max(0, ...lBoxes.map(b => b.width)),
217
- height: Math.max(0, ...lBoxes.map(b => b.height)),
218
- ascent: Math.max(0, ...lBoxes.map(b => b.ascent)),
219
- };
220
- const titleBoxHeight = hasTitle ? titleBox.height + gap : 0;
221
- const titleBoxWidth = hasTitle ? titleBox.width : 0;
222
- const count = colors.length;
223
- let m = 45; // default segment length
224
- const c = 15; // segment width
225
- const r = c / 2; // radius
226
- if (isVertical) {
227
- m = clamp(m, Math.ceil(labelBox.height) + 10, Math.floor((map.getContainer().clientHeight - 10 - padding * 2 - titleBoxHeight) / count));
228
- height = Math.ceil(padding * 2 + titleBoxHeight + count * m);
229
- width = Math.ceil(padding * 2 + Math.max(titleBoxWidth, c + gap + labelBox.width));
230
- }
231
- else {
232
- m = clamp(m, Math.ceil(labelBox.width) + 10, Math.floor((map.getContainer().clientWidth - 10 - padding * 2) / count));
233
- width = Math.ceil(padding * 2 + Math.max(titleBoxWidth, count * m));
234
- height = Math.ceil(padding * 2 + titleBoxHeight + c + gap + labelBox.ascent);
235
- }
236
- if (showBackground) {
237
- children.push(`
238
- <rect
239
- x="0"
240
- y="0"
241
- rx="10"
242
- ry="10"
243
- width="${width}"
244
- height="${height}"
245
- fill="${background}"
246
- />
247
- `);
248
- }
249
- let x = padding;
250
- let y = padding;
251
- if (hasTitle) {
252
- children.push(`
253
- <text
254
- x="${x}"
255
- y="${y + titleBox.ascent}"
256
- font-family="${titleFont}"
257
- font-size="${titleFontSize}"
258
- fill="${titleFontColor}"
259
- >
260
- ${escapeXML(title)}
261
- </text>
262
- `);
263
- y += titleBoxHeight;
264
- }
265
- const w = isVertical ? c : m;
266
- const h = isVertical ? m : c;
267
- const dx = isVertical ? 0 : m;
268
- const dy = isVertical ? m : 0;
269
- const tickLength = isRange ? c : c + 5;
270
- const d1 = isVertical
271
- ? `M ${x} ${y + r} v ${m - r} h ${c} v ${-(m - r)} a ${r} ${r} 0 0 0 ${-c} 0 z`
272
- : `M ${x + r} ${y} h ${m - r} v ${c} h ${-(m - r)} a ${r} ${r} 0 0 1 0 ${-c} z`;
273
- children.push(`<path d="${d1}" fill="${colors[0]}" />`);
274
- x += dx;
275
- y += dy;
276
- for (let i = 1; i < count - 1; i++, x += dx, y += dy) {
277
- children.push(`
278
- <rect
279
- x="${x}"
280
- y="${y}"
281
- width="${w}"
282
- height="${h}"
283
- fill="${colors[i]}"
284
- />
285
- `);
286
- children.push(`
287
- <line
288
- x1="${isVertical ? x : x + 0.5}"
289
- y1="${isVertical ? y + 0.5 : y}"
290
- x2="${isVertical ? x + tickLength : x + 0.5}"
291
- y2="${isVertical ? y + 0.5 : y + tickLength}"
292
- stroke="#ffffff"
293
- />
294
- `);
295
- }
296
- const d2 = isVertical
297
- ? `M ${x} ${y} v ${m - r} a ${r} ${r} 0 0 0 ${c} 0 v ${-(m - r)} z`
298
- : `M ${x} ${y} h ${m - r} a ${r} ${r} 0 0 1 0 ${c} h ${-(m - r)} z`;
299
- children.push(`<path d="${d2}" fill="${colors[count - 1]}" />`);
300
- children.push(`
301
- <line
302
- x1="${isVertical ? x : x + 0.5}"
303
- y1="${isVertical ? y + 0.5 : y}"
304
- x2="${isVertical ? x + tickLength : x + 0.5}"
305
- y2="${isVertical ? y + 0.5 : y + tickLength}"
306
- stroke="#ffffff"
307
- />
308
- `);
309
- x = padding;
310
- y = padding + titleBoxHeight;
311
- for (let i = 0; i < labels.length; i++, x += dx, y += dy) {
312
- children.push(`
313
- <text
314
- x="${isVertical ? x + c + gap : x + (isRange ? m / 2 : m)}"
315
- y="${isVertical
316
- ? y + (isRange ? m / 2 : m) - labelBox.height / 2 + labelBox.ascent
317
- : y + c + gap + labelBox.ascent}"
318
- text-anchor="${isVertical ? 'start' : 'middle'}"
319
- font-family="${labelFont}"
320
- font-size="${labelFontSize}"
321
- fill="${labelFontColor}"
322
- >
323
- ${escapeXML(labels[i])}
324
- </text>
325
- `);
326
- }
327
- }
328
- return `
329
- <svg
330
- xmlns="http://www.w3.org/2000/svg"
331
- width="${width}"
332
- height="${height}"
333
- viewBox="0 0 ${width} ${height}"
334
- style="display: block;"
335
- >
336
- ${children.join('')}
337
- </svg>
338
- `;
339
- }
340
- function renderCategoricalLegend(legend, choropleth, dataColumn) {
341
- const categoricalGroup = choropleth.categoricalColors[dataColumn];
342
- if (categoricalGroup === undefined) {
343
- return renderBlankLegend();
344
- }
345
- const colorGroup = groupByColor(categoricalGroup.values);
346
- const entries = Object.entries(categoricalGroup.colors)
347
- .map(([color, meta]) => ({
348
- color,
349
- label: meta.title ?? colorGroup[color] ?? choropleth.defaultGroupName,
350
- order: meta.order,
351
- hidden: meta.hidden,
352
- svg: '',
353
- }))
354
- .filter(entry => !entry.hidden)
355
- .sort((a, b) => a.order - b.order);
356
- return getCategoricalLegendSvg({
357
- type: 'manualLegend',
358
- id: legend.id,
359
- name: legend.name,
360
- position: legend.position,
361
- stacking: legend.stacking ?? 'vertical',
362
- layout: legend.layout ?? 'vertical',
363
- title: legend.title ?? '',
364
- titleFont: legend.titleFont ?? defaultFont,
365
- titleFontColor: legend.titleFontColor ?? '#000000',
366
- titleFontSize: legend.titleFontSize ?? 14,
367
- entryFont: legend.labelFont ?? defaultFont,
368
- entryFontColor: legend.labelFontColor ?? '#000000',
369
- entryFontSize: legend.labelFontSize ?? 13,
370
- entryShape: 'rectangle',
371
- entries,
372
- background: legend.background ?? '#ffffff',
373
- showBackground: legend.showBackground ?? false,
374
- }, defaultFont);
375
- }
376
- function getFormatter(format) {
377
- const { decimal, group } = getSeparators();
378
- const locale = formatLocale({
379
- decimal,
380
- thousands: group,
381
- grouping: [3],
382
- currency: ['', ''],
383
- });
384
- return locale.format(format);
385
- }
386
- function getSeparators() {
387
- const parts = new Intl.NumberFormat(navigator.languages).formatToParts(1000.1);
388
- const decimal = parts.find(part => part.type === 'decimal')?.value;
389
- const group = parts.find(part => part.type === 'group')?.value;
390
- return decimal !== undefined && group !== undefined
391
- ? { decimal, group }
392
- : { decimal: '.', group: ',' };
393
- }
@@ -1,29 +0,0 @@
1
- import { numberRe } from '@/utils/helpers';
2
- export function useCustomAdornment(adornment) {
3
- const container = document.createElement('div');
4
- container.className = 'adornment';
5
- const { svg, scale = 1 } = adornment;
6
- const doc = new DOMParser().parseFromString(svg, 'image/svg+xml');
7
- const svgEl = doc.querySelector('svg');
8
- if (svgEl) {
9
- const viewBoxRe = new RegExp(numberRe
10
- .toString()
11
- .replace(/^\/\^|\$\/$/g, '')
12
- .replace(/.*/, '^($&)[, ]($&)[, ]($&)[, ]($&)$$'));
13
- const width = svgEl.getAttribute('width');
14
- const height = svgEl.getAttribute('height');
15
- if (width && height && numberRe.test(width) && numberRe.test(height)) {
16
- svgEl.setAttribute('width', String(Number(width) * scale));
17
- svgEl.setAttribute('height', String(Number(height) * scale));
18
- }
19
- else {
20
- const match = viewBoxRe.exec(svgEl.getAttribute('viewBox'));
21
- const w = match ? Number(match[3]) : 300;
22
- const h = match ? Number(match[4]) : 150;
23
- svgEl.setAttribute('width', String(w * scale));
24
- svgEl.setAttribute('height', String(h * scale));
25
- }
26
- container.appendChild(svgEl);
27
- }
28
- return container;
29
- }
@@ -1,71 +0,0 @@
1
- import { escapeXML, loadFonts, measureTextBlock } from '@/utils/svgHelpers';
2
- export function useHeading(heading, vapiUrl, accessToken) {
3
- const container = document.createElement('div');
4
- container.className = 'adornment';
5
- const defaultFont = 'ArialMT';
6
- const fonts = [heading.titleFont ?? defaultFont, heading.subtitleFont ?? defaultFont];
7
- const fontsToLoad = Array.from(new Set(fonts));
8
- loadFonts(fontsToLoad, vapiUrl, accessToken).then(() => (container.innerHTML = getSvg(heading, defaultFont)));
9
- return container;
10
- }
11
- function getSvg(heading, defaultFont) {
12
- const padding = 8;
13
- const radius = 6;
14
- const { title, titleColor = '#000000', titleFont = defaultFont, titleFontSize = 20, titleJustify = 'center', subtitle, subtitleColor = '#000000', subtitleFont = defaultFont, subtitleFontSize = 12, subtitleJustify = 'center', background = '#ffffff', showBackground = false, } = heading;
15
- let measuredWidth = 0;
16
- let titleHeight = 0;
17
- let subtitleHeight = 0;
18
- let titleY = 0;
19
- let subtitleY = 0;
20
- const titleBox = title.trim().length > 0 ? measureTextBlock([title], titleFont, titleFontSize) : null;
21
- const subtitleBox = subtitle.trim().length > 0
22
- ? measureTextBlock([subtitle], subtitleFont, subtitleFontSize)
23
- : null;
24
- measuredWidth = Math.max(titleBox?.width ?? 0, subtitleBox?.width ?? 0);
25
- if (titleBox) {
26
- const { ascent: ta, descent: td } = titleBox;
27
- titleHeight = ta + td;
28
- titleY = padding + ta;
29
- }
30
- if (subtitleBox) {
31
- const { ascent: sa, descent: sd } = subtitleBox;
32
- subtitleHeight = sa + sd;
33
- if (titleBox) {
34
- subtitleY = titleY + titleBox.descent + sa + 6;
35
- }
36
- else {
37
- subtitleY = padding + sa;
38
- }
39
- }
40
- const containerWidth = measuredWidth + padding * 2;
41
- const containerHeight = titleHeight + subtitleHeight + padding * 2;
42
- const titleX = titleJustify === 'center'
43
- ? containerWidth / 2
44
- : titleJustify === 'right'
45
- ? containerWidth - padding
46
- : padding;
47
- const subtitleX = subtitleJustify === 'center'
48
- ? containerWidth / 2
49
- : subtitleJustify === 'right'
50
- ? containerWidth - padding
51
- : padding;
52
- let svg = '';
53
- svg += `<svg xmlns="http://www.w3.org/2000/svg" width="${containerWidth}" height="${containerHeight}" viewBox="0 0 ${containerWidth} ${containerHeight}">`;
54
- svg += `<rect x="0" y="0" width="${containerWidth}" height="${containerHeight}" fill="${background}" rx="${radius}" style="visibility:${showBackground ? 'visible' : 'hidden'}" />`;
55
- if (titleBox || subtitleBox) {
56
- const titleAnchor = titleJustify === 'center' ? 'middle' : titleJustify === 'right' ? 'end' : 'start';
57
- const subtitleAnchor = subtitleJustify === 'center' ? 'middle' : subtitleJustify === 'right' ? 'end' : 'start';
58
- svg += `<text x="${titleX}" y="${titleY}" fill="${titleColor}" font-family="${titleFont}" font-size="${titleFontSize}" text-anchor="${titleAnchor}">`;
59
- if (titleBox) {
60
- svg += `${escapeXML(title)}`;
61
- }
62
- if (subtitleBox) {
63
- svg += `<tspan x="${subtitleX}" y="${subtitleY}" fill="${subtitleColor}" font-family="${subtitleFont}" font-size="${subtitleFontSize}" text-anchor="${subtitleAnchor}">`;
64
- svg += `${escapeXML(subtitle)}`;
65
- svg += `</tspan>`;
66
- }
67
- svg += `</text>`;
68
- }
69
- svg += `</svg>`;
70
- return svg;
71
- }
@@ -1,3 +0,0 @@
1
- import type { Map } from '@mapcreator/maplibre-gl';
2
- import type { JobObjectInsetMap } from '@/types/jobObject';
3
- export declare function useInsetMap(insetMap: JobObjectInsetMap, map: Map, cdnUrl: string): HTMLElement;