lintje 0.1.1 → 0.2.0

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 (177) hide show
  1. package/dist-elements/actions.js +1 -1
  2. package/dist-elements/charts.js +1 -1
  3. package/dist-elements/chunks/{base-rBLTcEIv.js → base-Bg-IFOPG.js} +134 -105
  4. package/dist-elements/chunks/{date-format-B5DPGjAw.js → date-format-mHtZyBys.js} +28 -2
  5. package/dist-elements/chunks/disclosure-BXTX04gM.js +4 -0
  6. package/dist-elements/chunks/{disclosure-CHasOudX.js → disclosure-CMXhX-Vb.js} +7 -7
  7. package/dist-elements/chunks/download-y528pIHP.js +230 -0
  8. package/dist-elements/chunks/{focus-trap-w3vCamJ6.js → focus-trap-9BnE-xWv.js} +1 -1
  9. package/dist-elements/chunks/{input-jQVTln7H.js → input-BtuNFSWk.js} +13 -13
  10. package/dist-elements/chunks/{player-Bq9YGnpt.js → player-DXOZEyEy.js} +24 -24
  11. package/dist-elements/chunks/{sentence-CLNJOeXz.js → sentence-BI3lwEuT.js} +3 -3
  12. package/dist-elements/chunks/{stagger-9hYzxhMG.js → stagger-qGD3wmhg.js} +145 -123
  13. package/dist-elements/core.js +1 -1
  14. package/dist-elements/custom-elements.json +436 -26
  15. package/dist-elements/feedback.js +1 -1
  16. package/dist-elements/guides/dashboard.md +1 -1
  17. package/dist-elements/guides/events.md +3 -2
  18. package/dist-elements/guides/loading.md +3 -3
  19. package/dist-elements/guides/start.md +1 -1
  20. package/dist-elements/inputs.js +1 -0
  21. package/dist-elements/layout.js +1 -1
  22. package/dist-elements/lintje.js +22659 -22216
  23. package/dist-elements/map.js +1 -1
  24. package/dist-elements/overlays.js +1 -1
  25. package/dist-elements/tag/activity-log.js +11 -11
  26. package/dist-elements/tag/ai-label.js +7 -7
  27. package/dist-elements/tag/announcement.js +19 -19
  28. package/dist-elements/tag/app-search.js +21 -21
  29. package/dist-elements/tag/audio-player.js +34 -34
  30. package/dist-elements/tag/badge.js +1 -1
  31. package/dist-elements/tag/breadcrumbs.js +11 -11
  32. package/dist-elements/tag/button.js +1 -1
  33. package/dist-elements/tag/card-list.js +1 -1
  34. package/dist-elements/tag/card.js +25 -25
  35. package/dist-elements/tag/chart.d.ts +1 -0
  36. package/dist-elements/tag/chart.js +1868 -0
  37. package/dist-elements/tag/chat-answer.js +28 -28
  38. package/dist-elements/tag/chat-composer.js +20 -20
  39. package/dist-elements/tag/chat-message.js +9 -9
  40. package/dist-elements/tag/chat-strip.js +16 -16
  41. package/dist-elements/tag/chat-suggestions.js +1 -1
  42. package/dist-elements/tag/chat.js +27 -27
  43. package/dist-elements/tag/checkbox.js +6 -6
  44. package/dist-elements/tag/code.js +8 -8
  45. package/dist-elements/tag/combobox.js +13 -13
  46. package/dist-elements/tag/confirm-dialog.js +6 -6
  47. package/dist-elements/tag/conflict-alert.js +5 -5
  48. package/dist-elements/tag/copy-button.js +7 -7
  49. package/dist-elements/tag/data-table.js +179 -179
  50. package/dist-elements/tag/date-input.js +34 -42
  51. package/dist-elements/tag/date-range.js +33 -33
  52. package/dist-elements/tag/description-list.js +20 -20
  53. package/dist-elements/tag/document-viewer.js +19 -19
  54. package/dist-elements/tag/drawer.js +7 -7
  55. package/dist-elements/tag/empty-state.js +11 -11
  56. package/dist-elements/tag/error-summary.js +8 -8
  57. package/dist-elements/tag/expander.js +7 -7
  58. package/dist-elements/tag/explainer.js +9 -9
  59. package/dist-elements/tag/field.js +4 -4
  60. package/dist-elements/tag/file-upload.js +20 -20
  61. package/dist-elements/tag/filter-bar.js +35 -35
  62. package/dist-elements/tag/filter-sheet.js +6 -6
  63. package/dist-elements/tag/filter-zone.js +21 -21
  64. package/dist-elements/tag/footer.js +1 -1
  65. package/dist-elements/tag/form-actions.js +7 -7
  66. package/dist-elements/tag/form-section.js +3 -3
  67. package/dist-elements/tag/form.js +4 -4
  68. package/dist-elements/tag/gallery.js +6 -6
  69. package/dist-elements/tag/grid-item.js +1 -1
  70. package/dist-elements/tag/grid.js +1 -1
  71. package/dist-elements/tag/hero.js +6 -6
  72. package/dist-elements/tag/highlight.js +6 -6
  73. package/dist-elements/tag/icon-button.js +1 -1
  74. package/dist-elements/tag/icon.js +1 -1
  75. package/dist-elements/tag/job-list.js +6 -6
  76. package/dist-elements/tag/kpi-row.js +7 -5
  77. package/dist-elements/tag/kpi.js +259 -69
  78. package/dist-elements/tag/level-meter.js +5 -5
  79. package/dist-elements/tag/list.js +28 -28
  80. package/dist-elements/tag/logo.js +9 -9
  81. package/dist-elements/tag/map.d.ts +1 -0
  82. package/dist-elements/tag/map.js +21910 -0
  83. package/dist-elements/tag/menu-button.js +48 -47
  84. package/dist-elements/tag/modal.js +9 -9
  85. package/dist-elements/tag/multiselect.js +18 -18
  86. package/dist-elements/tag/note.js +4 -4
  87. package/dist-elements/tag/notifications.js +24 -24
  88. package/dist-elements/tag/number-input.js +8 -8
  89. package/dist-elements/tag/page-header.js +13 -13
  90. package/dist-elements/tag/pagination.js +27 -27
  91. package/dist-elements/tag/popover.js +1 -1
  92. package/dist-elements/tag/progress-bar.js +1 -1
  93. package/dist-elements/tag/prose.js +4 -4
  94. package/dist-elements/tag/qr-code.js +6 -6
  95. package/dist-elements/tag/radio-group.js +7 -7
  96. package/dist-elements/tag/range.js +13 -13
  97. package/dist-elements/tag/recording-status.js +8 -8
  98. package/dist-elements/tag/repeater.js +1 -1
  99. package/dist-elements/tag/segmented.js +7 -7
  100. package/dist-elements/tag/select.js +6 -6
  101. package/dist-elements/tag/session-expiry.js +13 -13
  102. package/dist-elements/tag/shell.js +168 -168
  103. package/dist-elements/tag/shortcuts.js +8 -8
  104. package/dist-elements/tag/skeleton.js +1 -1
  105. package/dist-elements/tag/slot-picker.d.ts +1 -0
  106. package/dist-elements/tag/slot-picker.js +74 -0
  107. package/dist-elements/tag/sortable-list.js +11 -11
  108. package/dist-elements/tag/spinner.js +1 -1
  109. package/dist-elements/tag/split-pane.js +4 -4
  110. package/dist-elements/tag/status-dot.js +1 -1
  111. package/dist-elements/tag/stepper.js +13 -13
  112. package/dist-elements/tag/streaming-text.js +15 -15
  113. package/dist-elements/tag/sub-nav.js +26 -26
  114. package/dist-elements/tag/tabs.js +13 -13
  115. package/dist-elements/tag/tag-input.js +14 -14
  116. package/dist-elements/tag/text-editor.js +7 -7
  117. package/dist-elements/tag/text-input.js +10 -10
  118. package/dist-elements/tag/textarea.js +6 -6
  119. package/dist-elements/tag/tile.js +1 -1
  120. package/dist-elements/tag/time-input.js +136 -42
  121. package/dist-elements/tag/toast.js +10 -10
  122. package/dist-elements/tag/toggle.js +6 -6
  123. package/dist-elements/tag/toggletip.js +11 -11
  124. package/dist-elements/tag/tooltip.js +1 -1
  125. package/dist-elements/tag/transcript.js +31 -31
  126. package/dist-elements/tag/translator.js +7 -7
  127. package/dist-elements/tag/tree-view.js +12 -12
  128. package/dist-elements/tag/user-menu.js +31 -30
  129. package/dist-elements/tag/video-player.js +13 -13
  130. package/dist-elements/tokens.css +2 -0
  131. package/dist-elements/types/bundle/charts.d.ts +1 -1
  132. package/dist-elements/types/bundle/index.d.ts +1 -1
  133. package/dist-elements/types/bundle/inputs.d.ts +1 -0
  134. package/dist-elements/types/bundle/map.d.ts +1 -1
  135. package/dist-elements/types/components/charts/{chart-tile/chart-tile.d.ts → chart/chart.d.ts} +7 -7
  136. package/dist-elements/types/components/charts/kpi/gauge.d.ts +18 -0
  137. package/dist-elements/types/components/charts/kpi/kpi.d.ts +28 -3
  138. package/dist-elements/types/components/chat/chat-answer/chat-answer.d.ts +1 -1
  139. package/dist-elements/types/components/index.d.ts +8 -5
  140. package/dist-elements/types/components/inputs/date-input/date-format.d.ts +4 -0
  141. package/dist-elements/types/components/inputs/slot-picker/slot-picker.d.ts +41 -0
  142. package/dist-elements/types/components/inputs/time-input/time-format.d.ts +4 -0
  143. package/dist-elements/types/components/inputs/time-input/time-input.d.ts +25 -6
  144. package/dist-elements/types/components/map/{map-tile/map-tile.d.ts → map/map.d.ts} +10 -6
  145. package/dist-elements/types/components/shared/charts/histogram-chart/histogram-chart.d.ts +33 -0
  146. package/dist-elements/types/components/shared/charts/index.d.ts +3 -1
  147. package/dist-elements/types/components/shared/charts/map-chart/area.d.ts +16 -0
  148. package/dist-elements/types/components/shared/charts/map-chart/drawings.d.ts +6 -2
  149. package/dist-elements/types/components/shared/charts/map-chart/geo.d.ts +6 -0
  150. package/dist-elements/types/components/shared/charts/map-chart/leaflet.d.ts +40 -2
  151. package/dist-elements/types/components/shared/charts/map-chart/map-chart.d.ts +17 -3
  152. package/dist-elements/types/components/shared/charts/map-chart/map-legend.d.ts +26 -0
  153. package/dist-elements/types/components/shared/charts/map-chart/marks.d.ts +47 -0
  154. package/dist-elements/types/components/shared/charts/map-chart/reveal.d.ts +1 -1
  155. package/dist-elements/types/components/shared/charts/scatter-chart/scatter-chart.d.ts +29 -0
  156. package/dist-elements/types/components/shared/charts/shared/axes.d.ts +21 -4
  157. package/dist-elements/types/components/shared/charts/shared/chart-icons.d.ts +4 -3
  158. package/dist-elements/types/components/shared/charts/shared/controller.d.ts +27 -15
  159. package/dist-elements/types/components/shared/charts/shared/types.d.ts +112 -6
  160. package/dist-elements/types/core/format.d.ts +5 -2
  161. package/dist-elements/types/icons/register.d.ts +1 -1
  162. package/dist-elements/types/primitives/shared/place.d.ts +1 -1
  163. package/dist-elements/types/primitives/tooltip/tooltip.d.ts +2 -0
  164. package/dist-elements/types/types.d.ts +37 -7
  165. package/dist-icons/functioneel-cirkelselectie.svg +1 -0
  166. package/dist-icons/functioneel-lasso.svg +1 -0
  167. package/dist-icons/functioneel-punaise-outline.svg +1 -0
  168. package/dist-icons/functioneel-punaise.svg +1 -0
  169. package/dist-icons/functioneel-rechthoekselectie.svg +1 -0
  170. package/dist-icons/functioneel-selectie.svg +1 -0
  171. package/package.json +1 -1
  172. package/dist-elements/chunks/disclosure-Z7Ny17sS.js +0 -4
  173. package/dist-elements/chunks/download-lFooAfD1.js +0 -226
  174. package/dist-elements/tag/chart-tile.d.ts +0 -1
  175. package/dist-elements/tag/chart-tile.js +0 -1474
  176. package/dist-elements/tag/map-tile.d.ts +0 -1
  177. package/dist-elements/tag/map-tile.js +0 -22292
@@ -1,24 +1,28 @@
1
1
  /**
2
- * `<lintje-map-tile>` — a map in its tile. The map shows a new layer at once and expects the host
2
+ * `<lintje-map>` — a map in its tile. The map shows a new layer at once and expects the host
3
3
  * to confirm it in the next `data`. `tile.expandable` shows the same map again in the modal; the
4
4
  * modal's own events stop here.
5
5
  *
6
6
  * Events: `lintje-mark-select` `{id, label, href?}` (`href` is the one the server minted on that
7
7
  * mark) and `lintje-layer-change` (the chosen layer's `value`). Undoing a selection is
8
8
  * `lintje-mark-select` with `id: null` and `data.clearHref`, so a page that keeps the selection
9
- * in the URL can drop it.
9
+ * in the URL can drop it. With `data.controls.lasso`, `.circle` or `.rect` a drawn area chooses
10
+ * every mark in it — two or more tools share one button that opens their menu:
11
+ * `lintje-area-select` `{area, ids}`, and `{area: null, ids: []}` when it is undone; the host
12
+ * keeps the area in its URL and sends it back as `selectedArea`.
10
13
  */
11
14
  import { nothing, type PropertyDeclarations, type PropertyValues, type TemplateResult } from 'lit';
12
15
  import { type FrameSettings } from '../../../core/element.js';
13
16
  import { LintjeContentTileElement } from '../../shared/content-tile.js';
14
17
  import '../../feedback/announcement/announcement.js';
15
18
  import '../../../primitives/tile/tile.js';
16
- import type { MapTileViewData } from '../../../types.js';
17
- export declare class LintjeMapTile extends LintjeContentTileElement {
19
+ import '../../../primitives/tooltip/tooltip.js';
20
+ import type { MapData } from '../../../types.js';
21
+ export declare class LintjeMap extends LintjeContentTileElement {
18
22
  #private;
19
23
  static styles: import("lit").CSSResult[];
20
24
  static properties: PropertyDeclarations;
21
- data?: MapTileViewData | null;
25
+ data?: MapData | null;
22
26
  /** The chosen layer, shown before the host confirms it. */
23
27
  layer?: string;
24
28
  protected get dataSettings(): FrameSettings | undefined;
@@ -36,6 +40,6 @@ export declare class LintjeMapTile extends LintjeContentTileElement {
36
40
  }
37
41
  declare global {
38
42
  interface HTMLElementTagNameMap {
39
- 'lintje-map-tile': LintjeMapTile;
43
+ 'lintje-map': LintjeMap;
40
44
  }
41
45
  }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * A histogram: counts in classes that touch, on an x-axis that runs on, so the labels stand on
3
+ * the class bounds. A median is a solid emphasis line, a threshold a dashed one.
4
+ */
5
+ import { type TemplateResult } from 'lit';
6
+ import { type PlotArea } from '../shared/scale.js';
7
+ import { type ChartOptions } from '../shared/controller.js';
8
+ import type { ChartSpec } from '../shared/types.js';
9
+ type HistogramSpec = Extract<ChartSpec, {
10
+ kind: 'histogram';
11
+ }>;
12
+ /** A class as the tooltip and the table name it: "8 tot 10 dagen", "30 dagen of meer". */
13
+ export declare function binLabel(bin: {
14
+ from: number;
15
+ to: number | null;
16
+ }, unit?: string): string;
17
+ export interface LineLabel {
18
+ x: number;
19
+ text: string;
20
+ /** Bold, as the median's label is, and measured so. */
21
+ bold?: boolean;
22
+ }
23
+ /**
24
+ * Where the labels of the median and the threshold stand: right of their line, or left of it
25
+ * where they would leave the drawing, and the right one a line lower when the two would touch.
26
+ */
27
+ export declare function placeLineLabels(labels: LineLabel[], area: PlotArea, fontFamily?: string): {
28
+ x: number;
29
+ y: number;
30
+ anchor: 'start' | 'end';
31
+ }[];
32
+ export declare function renderHistogramChart(spec: HistogramSpec, options: ChartOptions): TemplateResult;
33
+ export {};
@@ -11,8 +11,10 @@ export { renderGroupedBarChart } from './grouped-bar-chart/grouped-bar-chart.js'
11
11
  export { renderStackedBarChart } from './stacked-bar-chart/stacked-bar-chart.js';
12
12
  export { renderPieChart } from './pie-chart/pie-chart.js';
13
13
  export { renderDualAxisChart } from './dual-axis-chart/dual-axis-chart.js';
14
+ export { renderScatterChart } from './scatter-chart/scatter-chart.js';
14
15
  export { renderHeatmap, heatmapBounds, heatmapClasses } from './heatmap-chart/heatmap-chart.js';
15
16
  export type { HeatmapClass } from './heatmap-chart/heatmap-chart.js';
17
+ export { renderHistogramChart } from './histogram-chart/histogram-chart.js';
16
18
  export { renderMap } from './map-chart/map-chart.js';
17
19
  export type { MapOptions } from './map-chart/map-chart.js';
18
20
  export { renderChartFrame, renderLegend, renderAsOfMarker } from './shared/axes.js';
@@ -34,4 +36,4 @@ export { staggerStyle, gridStaggerStyle } from './shared/stagger.js';
34
36
  export type { StyleInfo } from './shared/stagger.js';
35
37
  export { chartStyles, chartFrameStyles, pieChartStyles, heatmapStyles } from './shared/chart-styles.js';
36
38
  export { mapStyles, mapChartStyles } from './map-chart/map-styles.js';
37
- export type { ChartSpec, ChartKind, ChartColor, ChartLink, LineSeriesData, BarSeriesData, MapTileData, MapValue, MapVariant, MapPlotData, MapPlotVariant, } from './shared/types.js';
39
+ export type { ChartSpec, ChartKind, ChartColor, ChartLink, LineSeriesData, BarSeriesData, ScatterPoint, ScatterSeriesData, MapSpec, MapValue, MapVariant, MapPlotData, MapPlotVariant, } from './shared/types.js';
@@ -0,0 +1,16 @@
1
+ import type { MapDrawing } from './drawings.js';
2
+ import type { MapArea } from '../shared/types.js';
3
+ /** The great-circle distance in km. */
4
+ export declare function distanceKm([lon1, lat1]: [number, number], [lon2, lat2]: [number, number]): number;
5
+ /**
6
+ * A rectangle between two corners, as a lasso of four: in Mercator a line of one longitude or
7
+ * latitude is straight, so the box on the screen is the box in degrees.
8
+ */
9
+ export declare function rectRing([lon1, lat1]: [number, number], [lon2, lat2]: [number, number]): [number, number][];
10
+ /** A ring of four corners that is a rectangle: what `rectRing` draws, for the panel's words. */
11
+ export declare function isRect(ring: [number, number][]): boolean;
12
+ /** A ring without any area: every corner on one line of longitude or of latitude. */
13
+ export declare const flatRing: (ring: [number, number][]) => boolean;
14
+ export declare function inArea(area: MapArea, point: [number, number]): boolean;
15
+ /** The ids of the marks of every drawing that lie wholly in the area, in drawing order. */
16
+ export declare function idsInArea(area: MapArea, drawings: MapDrawing[], geo?: string): string[];
@@ -3,16 +3,20 @@
3
3
  * svg map, the basemap and the tile's CSV read the same list, so a figure always speaks the unit
4
4
  * and the series names of its own layer.
5
5
  */
6
- import type { MapSeriesKey, MapTileData, MapValue, MapVariant } from '../shared/types.js';
6
+ import type { MapSeriesKey, MapSpec, MapValue, MapVariant } from '../shared/types.js';
7
7
  export type DrawingVariant = Exclude<MapVariant, 'plots'>;
8
8
  export interface MapDrawing {
9
9
  variant: DrawingVariant;
10
10
  values: MapValue[];
11
+ /** The layer's place in the stack, from the bottom; what keys a series switched off. */
12
+ index: number;
11
13
  /** The layer's name in the legend and the CSV: its `label`, or the word for its variant. */
12
14
  name: string;
13
15
  unit: string;
14
16
  /** The largest figure, at least 1: what the classes, widths and sizes scale to. */
15
17
  max: number;
18
+ /** The smallest figure a mark carries, for the legend's range; `max` without any. */
19
+ min: number;
16
20
  destination?: {
17
21
  lon: number;
18
22
  lat: number;
@@ -21,6 +25,6 @@ export interface MapDrawing {
21
25
  seriesLabels?: Partial<Record<MapSeriesKey, string>>;
22
26
  }
23
27
  /** The drawings in the order they draw, bottom first; `unit` is the map's own. */
24
- export declare function mapDrawings(data: MapTileData, unit: string): MapDrawing[];
28
+ export declare function mapDrawings(data: MapSpec, unit: string): MapDrawing[];
25
29
  /** A figure and its unit, without a dangling space when the unit is empty. */
26
30
  export declare function withUnit(figure: string, unit: string): string;
@@ -0,0 +1,6 @@
1
+ export type FeatureCollection = GeoJSON.FeatureCollection<GeoJSON.MultiPolygon, {
2
+ id: string;
3
+ name: string;
4
+ }>;
5
+ export declare const GEOS: Record<string, FeatureCollection>;
6
+ export declare function geoOf(name: string | undefined): FeatureCollection;
@@ -1,8 +1,33 @@
1
+ /**
2
+ * The map's surface: Leaflet carries the map — the projection, the panes, dragging, zooming and
3
+ * the tiles of a basemap — and the design system draws the data itself, into Leaflet's svg
4
+ * renderer (`marks.ts`). One instance hangs on the `ChartController`; `sync()` runs on every
5
+ * render. Geometry is unprojected (`*.lonlat.json`) and projected here once, at the zoom the
6
+ * map opens on; a pan or a zoom moves the drawing's group, not its paths.
7
+ */
8
+ import * as L from 'leaflet';
1
9
  import type { ChartController } from '../shared/controller.js';
2
- import type { MapTileData, MapValue } from '../shared/types.js';
10
+ import type { MapArea, MapSpec, MapTool, MapValue } from '../shared/types.js';
3
11
  export interface LeafletSyncOptions {
4
12
  unit: string;
5
13
  active: string | null;
14
+ /** The series the legend switched off, as `seriesKey()` names them. */
15
+ hidden: string[];
16
+ /** The layers of a stack switched off, by their place in it. */
17
+ hiddenLayers: number[];
18
+ /** The area that chose marks, and the marks it chose. */
19
+ area: MapArea | null;
20
+ chosen: string[];
21
+ /** The drawing tool that is on, and what a finished area goes to. */
22
+ tool: MapTool | null;
23
+ drawn: (area: MapArea) => void;
24
+ /** Escape with no area being drawn: the tool goes off. */
25
+ stopTool: () => void;
26
+ /** Panning with the mouse, and zooming by double click and pinch; the host may switch them off. */
27
+ drag: boolean;
28
+ zoom: boolean;
29
+ /** The scale bar shows: a move redraws the map so it follows. */
30
+ scale: boolean;
6
31
  select: (value: MapValue) => void;
7
32
  clear: () => void;
8
33
  /** Below 768 px, where a one-finger drag belongs to the page (rule 9). */
@@ -11,6 +36,8 @@ export interface LeafletSyncOptions {
11
36
  export declare class LeafletSurface {
12
37
  #private;
13
38
  constructor(controller: ChartController);
39
+ /** The Leaflet map, once the container has a size; a test looks at it. */
40
+ get map(): L.Map | null;
14
41
  /**
15
42
  * `ref` callback for the container. The map is built by the `ResizeObserver`, not here: Lit
16
43
  * commits a `ref` while the node is in its template fragment (0 × 0), and Leaflet would write
@@ -18,9 +45,20 @@ export declare class LeafletSurface {
18
45
  */
19
46
  readonly attach: (element: Element | undefined) => void;
20
47
  /** Applying synchronously is deliberate: a selection must land in the frame of its panel. */
21
- sync(data: MapTileData, options: LeafletSyncOptions): void;
48
+ sync(data: MapSpec, options: LeafletSyncOptions): void;
22
49
  zoomIn(): void;
23
50
  zoomOut(): void;
51
+ /** A wheel with its key: so many doublings around the pointer, fractional. */
52
+ zoomBy(event: MouseEvent, doublings: number): void;
53
+ /**
54
+ * The scale bar: a round distance in metres (1, 2 or 5 times a power of ten), at most `room`
55
+ * px wide, measured across the middle of the view, where Mercator's scale holds for what the
56
+ * reader looks at.
57
+ */
58
+ scaleBar(room?: number): {
59
+ width: number;
60
+ metres: number;
61
+ } | null;
24
62
  home(): void;
25
63
  destroy(): void;
26
64
  }
@@ -1,7 +1,19 @@
1
- /** The map: draws the pre-projected geometry from `assets/geo/`. */
1
+ /**
2
+ * The map: its chrome — the legend above it, the layer switcher, the zoom buttons, the select
3
+ * button with its menu of tools, the scale and the selection panel — around the surface that
4
+ * draws it (`leaflet.ts`).
5
+ */
2
6
  import { type TemplateResult } from 'lit';
3
7
  import type { ChartOptions } from '../shared/controller.js';
4
- import type { MapTileData, MapValue } from '../shared/types.js';
8
+ import type { MapArea, MapSpec, MapValue } from '../shared/types.js';
9
+ import '../../../../primitives/popover/popover.js';
10
+ /** The map's own height in a tile: on a phone taller, so all its buttons fit on the touch size. */
11
+ export declare const MAP_HEIGHT: {
12
+ readonly desktop: 400;
13
+ readonly mobile: 280;
14
+ };
15
+ /** The distance of the scale, in m or km: the figure beside the bracket. */
16
+ export declare function scaleLabel(metres: number): string;
5
17
  /**
6
18
  * What the map sends back. `description` and `selectedId` come from the map's own data, so
7
19
  * the chart options of those names are omitted.
@@ -13,5 +25,7 @@ export interface MapOptions extends Omit<ChartOptions, 'description' | 'onSelect
13
25
  /** The selection was undone (chosen mark again, empty map, Escape, close); travels the id. */
14
26
  onClear?: (previousId: string) => void;
15
27
  onLayerChange?: (value: string) => void;
28
+ /** An area was drawn, or undone (`null`); travels the ids of every mark in it. */
29
+ onArea?: (area: MapArea | null, ids: string[]) => void;
16
30
  }
17
- export declare function renderMap(data: MapTileData, options: MapOptions): TemplateResult;
31
+ export declare function renderMap(data: MapSpec, options: MapOptions): TemplateResult;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The legend above the map: a line per layer — its name, which switches the layer; its key,
3
+ * what its figures mean; its series, each a switch; and the hatch where it has gaps. The key is
4
+ * the same drawing as the map's: the classes, the sizes or the widths of its marks.
5
+ */
6
+ import { type TemplateResult } from 'lit';
7
+ import { type MapDrawing } from './drawings.js';
8
+ /** The lines a tile shows before the rest folds under "Nog n lagen". */
9
+ export declare const LEGEND_ROWS = 3;
10
+ export interface MapLegendOptions {
11
+ drawings: MapDrawing[];
12
+ /** The layers switched off, by their place in the stack. */
13
+ hiddenLayers: number[];
14
+ /** The series switched off, as `seriesKey()` names them. */
15
+ hiddenSeries: string[];
16
+ /** The modal: every layer, the classes with their bounds, the sizes nested at true size. */
17
+ expanded: boolean;
18
+ /** Below 768 px: one column, the series of a layer on their own line. */
19
+ mobile: boolean;
20
+ /** A tile's legend of more than `LEGEND_ROWS` layers is unfolded. */
21
+ open: boolean;
22
+ onLayer: (index: number) => void;
23
+ onSeries: (key: string) => void;
24
+ onOpen: (open: boolean) => void;
25
+ }
26
+ export declare function renderMapLegend(options: MapLegendOptions): TemplateResult;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The data on the map, drawn by the design system itself into Leaflet's svg: the land, then every
3
+ * drawing in the host's order, the first at the bottom. Geometry is projected once, at the zoom
4
+ * the surface took as its reference; a pan or a zoom moves the group that holds it, so a mark
5
+ * with a pixel size (a point, the destination of the flows) is a `__symbol` the surface places
6
+ * and scales back by itself. Every event a mark answers stops at the mark: the map's own click
7
+ * clears the selection, and its double click zooms.
8
+ */
9
+ import { nothing, type SVGTemplateResult } from 'lit';
10
+ import type { ChartController } from '../shared/controller.js';
11
+ import { type MapDrawing } from './drawings.js';
12
+ import type { MapArea, MapSeriesKey, MapValue } from '../shared/types.js';
13
+ /** Longitude and latitude to the surface's reference pixels. */
14
+ export type Project = (lon: number, lat: number) => [number, number];
15
+ /** A shape of the map's own geometry, as a path in reference pixels. */
16
+ export interface LandShape {
17
+ id: string;
18
+ name: string;
19
+ d: string;
20
+ }
21
+ export declare const CLASSES: string[];
22
+ export declare function classFor(value: number, max: number): number;
23
+ /** What every mark draws with. */
24
+ export interface MarksContext {
25
+ /** The controller's id, which names the hatch pattern. */
26
+ id: string;
27
+ active: string | null;
28
+ /** The marks a drawn area chose: outlined as a chosen mark is, the flows beside them muted. */
29
+ chosen: Set<string>;
30
+ controller: ChartController;
31
+ select: (value: MapValue) => void;
32
+ project: Project;
33
+ /** On a basemap the tiles are the land: only the areas with a row are drawn. */
34
+ tiled: boolean;
35
+ /** The series the legend switched off, as `seriesKey(drawing, series)`: not drawn. */
36
+ hidden: Set<string>;
37
+ /** The layers the legend switched off, by their place in the stack: drawn `is-off`, so they can go with a motion. */
38
+ hiddenLayers: Set<number>;
39
+ }
40
+ /** The radius of a point with a figure: between 3 and 18 px, by the square root of its share. */
41
+ export declare function pointRadius(value: number, max: number): number;
42
+ /** A series of one layer, as the legend switches it: a colour may serve several layers. */
43
+ export declare const seriesKey: (drawing: MapDrawing, series: MapSeriesKey) => string;
44
+ /** A drawn area, in the reference pixels; a circle with its middle. `draft` is the area while it is drawn. */
45
+ export declare function renderRegion(area: MapArea | null, project: Project, draft?: boolean): SVGTemplateResult | typeof nothing;
46
+ /** The whole drawing: the hatch, the land, then the drawings in order, each as one of three kinds. */
47
+ export declare function renderData(land: LandShape[], drawings: MapDrawing[], context: MarksContext, area?: MapArea | null): SVGTemplateResult;
@@ -11,7 +11,7 @@ export interface Box {
11
11
  /** How far a revealed mark stands off the overlay or edge it passed, in px. */
12
12
  export declare const REVEAL_MARGIN = 8;
13
13
  /** What stands over the drawing: the tile's own overlays and Leaflet's credit. */
14
- export declare const OVERLAYS = ".lintje-map-chart__layers, .lintje-map-chart__zoom, .lintje-map-chart__legend, .lintje-map-chart__selection, .leaflet-control";
14
+ export declare const OVERLAYS = ".lintje-map-chart__layers, .lintje-map-chart__zoom, .lintje-map-chart__selection, .lintje-map-chart__scale-bar, .leaflet-control";
15
15
  /** The overlays in `area`, as boxes in client pixels; one that is not drawn has no size. */
16
16
  export declare function overlayBoxes(area: Element): Box[];
17
17
  /**
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Scatter plot: two value axes, a point per record. A series is a colour and the shape that
3
+ * colour has on a map (rule 13); a point without both values is not drawn (rule 15).
4
+ */
5
+ import { type TemplateResult } from 'lit';
6
+ import { type PlotArea } from '../shared/scale.js';
7
+ import { type ChartOptions } from '../shared/controller.js';
8
+ import type { ChartSpec } from '../shared/types.js';
9
+ type ScatterSpec = Extract<ChartSpec, {
10
+ kind: 'scatter';
11
+ }>;
12
+ interface DataLabel {
13
+ label: string;
14
+ x: number;
15
+ y: number;
16
+ anchor: 'start' | 'end';
17
+ }
18
+ /**
19
+ * The named points' labels, above-left of their point or above-right where the left has no
20
+ * room. A label must stay in the drawing, clear of the other labels and of every other point;
21
+ * when one cannot, none shows (all or nothing).
22
+ */
23
+ export declare function placeDataLabels(points: {
24
+ label: string;
25
+ x: number;
26
+ y: number;
27
+ }[], names: string[], area: PlotArea, fontFamily: string): DataLabel[];
28
+ export declare function renderScatterChart(spec: ScatterSpec, options: ChartOptions): TemplateResult;
29
+ export {};
@@ -8,26 +8,41 @@ export type SvgSlot = SVGTemplateResult | typeof nothing | false | null | undefi
8
8
  export interface LegendItem {
9
9
  label: string;
10
10
  color?: string;
11
- shape?: 'square' | 'line' | 'dashed';
11
+ /** `point`: the series' symbol alone, as a scatter plot or a map draws it; `hatch` is "no data". */
12
+ shape?: 'square' | 'line' | 'dashed' | 'point' | 'hatch';
12
13
  /** The shape the line carries at its end, drawn on its line marker (rule 13). */
13
14
  symbol?: SeriesKey;
14
15
  hidden?: boolean;
16
+ /** Not a series but a reference, such as a norm: never a toggle. */
17
+ fixed?: boolean;
18
+ /** What `onToggle` receives; without it the label. */
19
+ key?: string;
15
20
  }
21
+ /**
22
+ * A series' symbol as a scatter plot draws it, for a marker: its shape in `currentColor`, and a
23
+ * dark-yellow one with the edge of its text colour (`lineCasing`).
24
+ */
25
+ export declare function renderSymbol(symbol: SeriesKey, color: string | undefined, centre: number): SVGTemplateResult;
16
26
  export declare function renderLegend({ items, onToggle, position, }: {
17
27
  items: LegendItem[];
18
28
  onToggle?: (label: string) => void;
19
29
  position?: 'top' | 'bottom' | 'right';
20
30
  }): TemplateResult;
31
+ type XAnchor = 'start' | 'middle' | 'end';
21
32
  export interface ChartFrameOptions {
22
33
  area?: PlotArea;
23
34
  ticks: number[];
24
35
  max: number;
25
36
  /** Unit above the axis, e.g. "Afgehandelde aanvragen". */
26
37
  axisTitle?: string;
38
+ /** `anchor` defaults to the middle; the last label of a value axis ends at the plot's edge. */
27
39
  xLabels?: {
28
40
  label: string;
29
41
  x: number;
42
+ anchor?: XAnchor;
30
43
  }[];
44
+ /** The title of a value axis along the bottom, under its labels at the right. */
45
+ xTitle?: string;
31
46
  /** Description for screen readers; replaces the chart in the accessibility tree. */
32
47
  description: string;
33
48
  height?: number;
@@ -57,14 +72,15 @@ export declare function renderFocusRing(id: string): SVGTemplateResult;
57
72
  export declare function focusRingStyle(id: string): Record<string, string>;
58
73
  /**
59
74
  * The x labels that fit: every one while no two neighbours touch, otherwise every second,
60
- * third, … from the first on. Neighbours are measured pair by pair, so one long name beside
61
- * a short one can fit where equal day labels do not.
75
+ * third, … from the first on. Neighbours are measured pair by pair, each where its anchor puts
76
+ * it, so one long name beside a short one can fit where equal day labels do not.
62
77
  */
63
78
  export declare function thinLabels<T extends {
64
79
  label: string;
65
80
  x: number;
81
+ anchor?: XAnchor;
66
82
  }>(labels: T[], fontFamily?: string): T[];
67
- export declare function renderChartFrame({ area, ticks, max, axisTitle, xLabels, description, defs, zeroLine, formatTick, id, height, fontFamily, interactive, keys, }: ChartFrameOptions, children: SvgSlot): TemplateResult;
83
+ export declare function renderChartFrame({ area, ticks, max, axisTitle, xLabels, xTitle, description, defs, zeroLine, formatTick, id, height, fontFamily, interactive, keys, }: ChartFrameOptions, children: SvgSlot): TemplateResult;
68
84
  /**
69
85
  * The as-of marker. Up to 6 pending hours (tail) it draws nothing and the missing hours are
70
86
  * hatched; beyond that (early) the series is cut off, with a line, a label and a note.
@@ -77,3 +93,4 @@ export declare function renderAsOfMarker({ area, index, count, label, lastValue,
77
93
  lastValue?: string;
78
94
  pendingHours: number;
79
95
  }): SvgSlot;
96
+ export {};
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { type TemplateResult } from 'lit';
7
7
  /** One icon, or the text that stands in for it while no file has that name. */
8
- export declare function chartIcon(name: string, text: string, size?: number): TemplateResult | string;
8
+ export declare function chartIcon(name: string, text: string, size?: number, flip?: 'horizontal' | 'vertical'): TemplateResult | string;
9
9
  /** The map's zoom controls, in the order the map and its skeleton draw them. */
10
10
  export declare const ZOOM_CONTROLS: readonly [{
11
11
  readonly action: 'in';
@@ -19,7 +19,8 @@ export declare const ZOOM_CONTROLS: readonly [{
19
19
  readonly label: 'Uitzoomen';
20
20
  }, {
21
21
  readonly action: 'home';
22
- readonly name: 'functioneel-home';
22
+ readonly name: 'functioneel-refresh';
23
+ readonly flip: 'horizontal';
23
24
  readonly text: 'Terug';
24
- readonly label: 'Terug naar het hele gebied';
25
+ readonly label: 'Kaart terugzetten';
25
26
  }];
@@ -1,6 +1,8 @@
1
1
  import { type PlotArea } from './scale.js';
2
2
  import type { LeafletSurface } from '../map-chart/leaflet.js';
3
3
  import type { ChartSelection } from './mark-select.js';
4
+ import type { SeriesKey } from './series-shapes.js';
5
+ import type { MapArea, MapTool } from './types.js';
4
6
  /** What every `render*` takes besides its data. */
5
7
  export interface ChartOptions {
6
8
  /** The state this chart keeps between renders. One per chart. */
@@ -27,7 +29,10 @@ export declare function chartArea(options: ChartOptions, margins?: Partial<PlotA
27
29
  export interface TooltipRow {
28
30
  label: string;
29
31
  value: string;
30
- color: string;
32
+ /** The swatch; a row without one is a plain figure. */
33
+ color?: string;
34
+ /** The series' shape instead of a square swatch, as its legend draws it. */
35
+ symbol?: SeriesKey;
31
36
  }
32
37
  export interface TooltipContent {
33
38
  title: string;
@@ -59,27 +64,32 @@ export declare class ChartController {
59
64
  /** What the keyboard's tooltip says, for the chart's status region; empty otherwise. */
60
65
  status: string;
61
66
  hiddenSeries: string[];
67
+ /** The layers of a stacked map switched off in its legend, by their place in the stack. */
68
+ hiddenLayers: number[];
62
69
  hoverSegment: number | null;
63
70
  selectedCell: {
64
71
  row: number;
65
72
  column: number;
66
73
  } | null;
67
74
  dimmedClass: number | null;
68
- zoom: number;
69
- /** The centre of the zoomed svg map, in its own units; `null` is the map's middle. */
70
- mapCentre: {
71
- x: number;
72
- y: number;
73
- } | null;
74
- /** How far a revealed mark moved the view past the map's edge, in its units; `null` for none. */
75
- mapNudge: {
76
- x: number;
77
- y: number;
78
- } | null;
75
+ /** What a wheel without its modifier shows, until its timer clears it. */
76
+ mapHint: string | null;
77
+ mapHintTimer: ReturnType<typeof setTimeout> | null;
79
78
  mapSelection: string | null;
79
+ /** The drawing tool that is on: a pointer on the map then draws instead of panning. */
80
+ mapTool: MapTool | null;
81
+ /** The tool the map's one select button shows: the last one used, until a shape is chosen. */
82
+ mapLastTool: MapTool | null;
83
+ /** The menu of tools stands open, and which row takes the focus once it has drawn. */
84
+ mapMenuOpen: boolean;
85
+ mapMenuFocus: 'first' | 'last' | 'checked' | null;
86
+ /** A legend of more than three layers is unfolded. */
87
+ mapLegendOpen: boolean;
88
+ /** The area that chose marks, and the last one the host sent, compared as JSON. */
89
+ mapArea: MapArea | null;
90
+ hostArea: string | undefined;
80
91
  hostSelection: string | null | undefined;
81
- legendOpen: boolean | null;
82
- /** The Leaflet map, created lazily when the data carries a basemap; `detach()` destroys it. */
92
+ /** The map's surface, created on the first render; `detach()` destroys it. */
83
93
  leaflet: LeafletSurface | null;
84
94
  /** Centre and zoom of the Leaflet map. `detach()` keeps it so a re-attach does not reset. */
85
95
  leafletView: {
@@ -88,7 +98,8 @@ export declare class ChartController {
88
98
  zoom: number;
89
99
  } | null;
90
100
  private readonly notify;
91
- private element;
101
+ /** The chart's box, once attached; the map finds its own buttons in it. */
102
+ element: HTMLElement | null;
92
103
  private measuring;
93
104
  private resizeObserver;
94
105
  private intersectionObserver;
@@ -128,6 +139,7 @@ export declare class ChartController {
128
139
  private watching;
129
140
  private watchEscape;
130
141
  private unwatchEscape;
142
+ toggleLayer(index: number): void;
131
143
  toggleSeries(label: string): void;
132
144
  private read;
133
145
  /**