@sqlrooms/deck 0.29.0-rc.7 → 0.29.0-rc.9
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.
- package/LICENSE.md +2 -1
- package/README.md +31 -6
- package/dist/DeckJsonMap.d.ts +2 -2
- package/dist/DeckJsonMap.d.ts.map +1 -1
- package/dist/DeckJsonMap.js +204 -17
- package/dist/DeckJsonMap.js.map +1 -1
- package/dist/DeckJsonMapSpec.d.ts +36 -36
- package/dist/DeckJsonMapSpec.d.ts.map +1 -1
- package/dist/DeckJsonMapSpec.js +1 -0
- package/dist/DeckJsonMapSpec.js.map +1 -1
- package/dist/MapSettings.d.ts.map +1 -1
- package/dist/MapSettings.js +203 -25
- package/dist/MapSettings.js.map +1 -1
- package/dist/ai.d.ts +55 -8
- package/dist/ai.d.ts.map +1 -1
- package/dist/ai.js +190 -41
- package/dist/ai.js.map +1 -1
- package/dist/block.d.ts +20 -0
- package/dist/block.d.ts.map +1 -0
- package/dist/block.js +119 -0
- package/dist/block.js.map +1 -0
- package/dist/dashboard.d.ts +2 -0
- package/dist/dashboard.d.ts.map +1 -1
- package/dist/dashboard.js +194 -285
- package/dist/dashboard.js.map +1 -1
- package/dist/dashboardConfig.d.ts +11 -3
- package/dist/dashboardConfig.d.ts.map +1 -1
- package/dist/dashboardConfig.js +82 -7
- package/dist/dashboardConfig.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/json/aggregateWaypoints.d.ts +14 -0
- package/dist/json/aggregateWaypoints.d.ts.map +1 -0
- package/dist/json/aggregateWaypoints.js +190 -0
- package/dist/json/aggregateWaypoints.js.map +1 -0
- package/dist/json/compileColorScale.d.ts +1 -1
- package/dist/json/compileColorScale.d.ts.map +1 -1
- package/dist/json/compileColorScale.js +42 -20
- package/dist/json/compileColorScale.js.map +1 -1
- package/dist/json/createDeckJsonConfiguration.d.ts.map +1 -1
- package/dist/json/createDeckJsonConfiguration.js +106 -8
- package/dist/json/createDeckJsonConfiguration.js.map +1 -1
- package/dist/json/defaultClasses.d.ts +5 -4
- package/dist/json/defaultClasses.d.ts.map +1 -1
- package/dist/json/defaultClasses.js +9 -4
- package/dist/json/defaultClasses.js.map +1 -1
- package/dist/json/extractColorScaleLegends.d.ts.map +1 -1
- package/dist/json/extractColorScaleLegends.js +43 -5
- package/dist/json/extractColorScaleLegends.js.map +1 -1
- package/dist/json/heatmapDefaults.d.ts +8 -0
- package/dist/json/heatmapDefaults.d.ts.map +1 -0
- package/dist/json/heatmapDefaults.js +14 -0
- package/dist/json/heatmapDefaults.js.map +1 -0
- package/dist/json/layerCompatibility.d.ts.map +1 -1
- package/dist/json/layerCompatibility.js +5 -1
- package/dist/json/layerCompatibility.js.map +1 -1
- package/dist/json/layers/DeckColumnLayer.d.ts +12 -0
- package/dist/json/layers/DeckColumnLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckColumnLayer.js +26 -0
- package/dist/json/layers/DeckColumnLayer.js.map +1 -0
- package/dist/json/layers/DeckH3HexagonLayer.d.ts +37 -0
- package/dist/json/layers/DeckH3HexagonLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckH3HexagonLayer.js +96 -0
- package/dist/json/layers/DeckH3HexagonLayer.js.map +1 -0
- package/dist/json/layers/DeckTripsLayer.d.ts +45 -0
- package/dist/json/layers/DeckTripsLayer.d.ts.map +1 -0
- package/dist/json/layers/DeckTripsLayer.js +169 -0
- package/dist/json/layers/DeckTripsLayer.js.map +1 -0
- package/dist/json/layers/index.d.ts +4 -0
- package/dist/json/layers/index.d.ts.map +1 -0
- package/dist/json/layers/index.js +4 -0
- package/dist/json/layers/index.js.map +1 -0
- package/dist/json/rewriteGeoArrowAccessors.d.ts.map +1 -1
- package/dist/json/rewriteGeoArrowAccessors.js +5 -0
- package/dist/json/rewriteGeoArrowAccessors.js.map +1 -1
- package/dist/mapConfigUtils.d.ts +102 -1
- package/dist/mapConfigUtils.d.ts.map +1 -1
- package/dist/mapConfigUtils.js +21 -3
- package/dist/mapConfigUtils.js.map +1 -1
- package/dist/mapLayerConfigUtils.d.ts +15 -0
- package/dist/mapLayerConfigUtils.d.ts.map +1 -1
- package/dist/mapLayerConfigUtils.js +109 -7
- package/dist/mapLayerConfigUtils.js.map +1 -1
- package/dist/prepare/detectGeometryColumn.d.ts +10 -1
- package/dist/prepare/detectGeometryColumn.d.ts.map +1 -1
- package/dist/prepare/detectGeometryColumn.js +48 -6
- package/dist/prepare/detectGeometryColumn.js.map +1 -1
- package/dist/prepare/wkbDecoder.d.ts.map +1 -1
- package/dist/prepare/wkbDecoder.js +88 -1
- package/dist/prepare/wkbDecoder.js.map +1 -1
- package/dist/prepare/wkbParser.d.ts +5 -0
- package/dist/prepare/wkbParser.d.ts.map +1 -1
- package/dist/prepare/wkbParser.js +24 -0
- package/dist/prepare/wkbParser.js.map +1 -1
- package/dist/types.d.ts +14 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/useDeckMapDatasets.d.ts +17 -0
- package/dist/useDeckMapDatasets.d.ts.map +1 -0
- package/dist/useDeckMapDatasets.js +69 -0
- package/dist/useDeckMapDatasets.js.map +1 -0
- package/dist/useDeckMapFitToBounds.d.ts +29 -0
- package/dist/useDeckMapFitToBounds.d.ts.map +1 -0
- package/dist/useDeckMapFitToBounds.js +333 -0
- package/dist/useDeckMapFitToBounds.js.map +1 -0
- package/package.json +7 -6
package/dist/MapSettings.js
CHANGED
|
@@ -1,13 +1,54 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useState } from 'react';
|
|
3
|
-
import { Field, ColumnSelector, ColumnsProvider, useStoreWithMosaicDashboard,
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { Field, ColumnSelector, ColumnsProvider, useStoreWithMosaicDashboard, QUANTITATIVE_COLUMN_TYPES, } from '@sqlrooms/mosaic';
|
|
4
|
+
import { useDataTable } from '@sqlrooms/duckdb';
|
|
5
|
+
import { binnedNumericSchemes, categoricalSchemes, continuousDivergingSchemes, continuousSequentialSchemes, continuousSequentialInterpolators, parseColorString, } from '@sqlrooms/color-scales';
|
|
6
|
+
import { Button, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Slider, Switch, } from '@sqlrooms/ui';
|
|
6
7
|
import { XIcon } from 'lucide-react';
|
|
7
8
|
import { LatitudeSelector } from './LatitudeSelector';
|
|
8
9
|
import { LongitudeSelector } from './LongitudeSelector';
|
|
9
|
-
import {
|
|
10
|
-
|
|
10
|
+
import { clearDeckMapLayerColorScale, createDeckMapLayerColorScale, DECK_MAP_COLOR_SCALE_TYPE_OPTIONS, DECK_MAP_LAYER_TYPE_OPTIONS, getDeckMapColorAccessorOptions, getDeckMapLayerDatasetId, getDeckMapLayerColorScale, getDeckMapLayerRecords, setDeckMapLayerColorScale, setDeckMapLayerGeometryColumn, setDeckMapLayerHexagonColumn, setDeckMapLayerArcColumns, setDeckMapLayerType, updateDeckMapLayer, usesGeometryColumnSetting, usesH3ColumnSetting, usesArcColumnSetting, usesRadiusSetting, usesColumnRadiusSetting, usesTripsSettings, usesExtrusionSettings, } from './mapLayerConfigUtils';
|
|
11
|
+
/**
|
|
12
|
+
* Extracts the primary table name from a simple SQL query.
|
|
13
|
+
* Handles patterns like: `SELECT ... FROM tableName ...`
|
|
14
|
+
* and `SELECT ... FROM "tableName" ...`
|
|
15
|
+
*/
|
|
16
|
+
function extractTableFromSqlQuery(sqlQuery) {
|
|
17
|
+
if (!sqlQuery)
|
|
18
|
+
return undefined;
|
|
19
|
+
const match = sqlQuery.match(/\bFROM\s+(?:"([^"]+)"|(\w[\w.]*))/i);
|
|
20
|
+
return match?.[1] ?? match?.[2];
|
|
21
|
+
}
|
|
22
|
+
const HEATMAP_COLOR_STEPS = 6;
|
|
23
|
+
function schemeToColorRange(scheme) {
|
|
24
|
+
const interpolator = continuousSequentialInterpolators[scheme];
|
|
25
|
+
if (!interpolator) {
|
|
26
|
+
return continuousSequentialInterpolators.YlOrRd
|
|
27
|
+
? Array.from({ length: HEATMAP_COLOR_STEPS }, (_, i) => parseColorString(continuousSequentialInterpolators.YlOrRd(i / (HEATMAP_COLOR_STEPS - 1))))
|
|
28
|
+
: [];
|
|
29
|
+
}
|
|
30
|
+
return Array.from({ length: HEATMAP_COLOR_STEPS }, (_, i) => parseColorString(interpolator(i / (HEATMAP_COLOR_STEPS - 1))));
|
|
31
|
+
}
|
|
32
|
+
function detectHeatmapScheme(colorRange) {
|
|
33
|
+
if (!Array.isArray(colorRange) || colorRange.length === 0)
|
|
34
|
+
return 'YlOrRd';
|
|
35
|
+
for (const scheme of continuousSequentialSchemes) {
|
|
36
|
+
const sampled = schemeToColorRange(scheme);
|
|
37
|
+
if (sampled.length === colorRange.length) {
|
|
38
|
+
const matches = sampled.every((color, idx) => {
|
|
39
|
+
const actual = colorRange[idx];
|
|
40
|
+
if (!Array.isArray(actual))
|
|
41
|
+
return false;
|
|
42
|
+
return (Math.abs(color[0] - actual[0]) < 2 &&
|
|
43
|
+
Math.abs(color[1] - actual[1]) < 2 &&
|
|
44
|
+
Math.abs(color[2] - actual[2]) < 2);
|
|
45
|
+
});
|
|
46
|
+
if (matches)
|
|
47
|
+
return scheme;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return 'YlOrRd';
|
|
51
|
+
}
|
|
11
52
|
function getSchemeOptions(type) {
|
|
12
53
|
if (type === 'categorical') {
|
|
13
54
|
return categoricalSchemes;
|
|
@@ -23,8 +64,7 @@ function getSchemeOptions(type) {
|
|
|
23
64
|
export const MapSettingsPanel = ({ dashboardId, panel, onClose, }) => {
|
|
24
65
|
const [layerIndex, setLayerIndex] = useState(0);
|
|
25
66
|
const [colorAccessor, setColorAccessor] = useState('getFillColor');
|
|
26
|
-
const
|
|
27
|
-
const dataTable = useDataTable(tableName);
|
|
67
|
+
const dashboardSelectedTable = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.config.dashboardsById[dashboardId]?.selectedTable);
|
|
28
68
|
const updatePanel = useStoreWithMosaicDashboard((state) => state.mosaicDashboard.updatePanel);
|
|
29
69
|
const mapConfig = panel.config;
|
|
30
70
|
const layers = getDeckMapLayerRecords(mapConfig);
|
|
@@ -34,7 +74,21 @@ export const MapSettingsPanel = ({ dashboardId, panel, onClose, }) => {
|
|
|
34
74
|
const activeLayerDataset = activeLayerDatasetId
|
|
35
75
|
? mapConfig.datasets?.[activeLayerDatasetId]
|
|
36
76
|
: undefined;
|
|
77
|
+
// Resolve the table for column listing: prefer the dashboard's selected
|
|
78
|
+
// table (which represents the user's active choice), falling back to the
|
|
79
|
+
// dataset's explicit source table when no dashboard table is selected.
|
|
80
|
+
const fallbackTableName = activeLayerDataset?.source?.tableName ||
|
|
81
|
+
extractTableFromSqlQuery(activeLayerDataset?.source?.sqlQuery);
|
|
82
|
+
const primaryTable = useDataTable(dashboardSelectedTable);
|
|
83
|
+
const fallbackTable = useDataTable(fallbackTableName);
|
|
84
|
+
const dataTable = primaryTable ?? fallbackTable;
|
|
37
85
|
const showGeometryColumnSetting = usesGeometryColumnSetting(activeLayer?.['@@type']);
|
|
86
|
+
const showH3ColumnSetting = usesH3ColumnSetting(activeLayer?.['@@type']);
|
|
87
|
+
const showArcColumnSetting = usesArcColumnSetting(activeLayer?.['@@type']);
|
|
88
|
+
const showRadiusSetting = usesRadiusSetting(activeLayer?.['@@type']);
|
|
89
|
+
const showColumnRadiusSetting = usesColumnRadiusSetting(activeLayer?.['@@type']);
|
|
90
|
+
const showTripsSettings = usesTripsSettings(activeLayer?.['@@type']);
|
|
91
|
+
const showExtrusionSettings = usesExtrusionSettings(activeLayer?.['@@type']);
|
|
38
92
|
const colorAccessorOptions = getDeckMapColorAccessorOptions(activeLayer?.['@@type']);
|
|
39
93
|
const effectiveColorAccessor = colorAccessorOptions.find((option) => option.value === colorAccessor)
|
|
40
94
|
?.value ?? colorAccessorOptions[0]?.value;
|
|
@@ -43,8 +97,30 @@ export const MapSettingsPanel = ({ dashboardId, panel, onClose, }) => {
|
|
|
43
97
|
: undefined;
|
|
44
98
|
const colorScaleType = colorScale?.type ?? 'sequential';
|
|
45
99
|
const schemeOptions = getSchemeOptions(colorScaleType);
|
|
100
|
+
const isHeatmapLayer = activeLayer?.['@@type'] === 'GeoArrowHeatmapLayer';
|
|
46
101
|
const firstColumnName = dataTable?.columns[0]?.name;
|
|
47
|
-
|
|
102
|
+
// Width/radius values can be either numeric constants (e.g. getWidth: 3)
|
|
103
|
+
// or string accessor expressions (e.g. getRadius: '@@=Magnitude').
|
|
104
|
+
// For pixel-unit layers, prefer getWidth/getRadius over widthMinPixels/radiusMinPixels
|
|
105
|
+
// since that's the actual rendered value. When the accessor is a string expression,
|
|
106
|
+
// hide the slider entirely to avoid displaying invalid values or accidentally
|
|
107
|
+
// overwriting data-driven accessors with a constant on first interaction.
|
|
108
|
+
const isWidthInPixels = activeLayer?.widthUnits === 'pixels';
|
|
109
|
+
const rawWidth = activeLayer?.getWidth;
|
|
110
|
+
const numericWidth = typeof rawWidth === 'number' ? rawWidth : undefined;
|
|
111
|
+
const lineWidthValue = isWidthInPixels
|
|
112
|
+
? (numericWidth ?? activeLayer?.widthMinPixels ?? 1)
|
|
113
|
+
: (numericWidth ?? 1);
|
|
114
|
+
const isRadiusInPixels = activeLayer?.radiusUnits === 'pixels';
|
|
115
|
+
const rawRadius = activeLayer?.getRadius;
|
|
116
|
+
const numericRadius = typeof rawRadius === 'number' ? rawRadius : undefined;
|
|
117
|
+
const pointRadiusValue = isRadiusInPixels
|
|
118
|
+
? (numericRadius ??
|
|
119
|
+
activeLayer?.radiusMinPixels ??
|
|
120
|
+
2)
|
|
121
|
+
: (numericRadius ?? 100);
|
|
122
|
+
const isAccessorBasedRadius = typeof rawRadius === 'string';
|
|
123
|
+
const isAccessorBasedWidth = typeof rawWidth === 'string';
|
|
48
124
|
const applyConfig = useCallback((config) => {
|
|
49
125
|
updatePanel(dashboardId, panel.id, {
|
|
50
126
|
config: { ...config, settingsOpen: mapConfig.settingsOpen },
|
|
@@ -54,11 +130,22 @@ export const MapSettingsPanel = ({ dashboardId, panel, onClose, }) => {
|
|
|
54
130
|
const field = patch.field ?? colorScale?.field ?? firstColumnName;
|
|
55
131
|
if (!field || !effectiveColorAccessor)
|
|
56
132
|
return;
|
|
57
|
-
|
|
133
|
+
let type = patch.type ?? colorScale?.type ?? 'sequential';
|
|
134
|
+
// Auto-detect scale type when user changes the field
|
|
135
|
+
if (patch.field && !patch.type && dataTable) {
|
|
136
|
+
const col = dataTable.columns.find((c) => c.name === patch.field);
|
|
137
|
+
if (col) {
|
|
138
|
+
const normalized = col.type.split('(')[0].toUpperCase();
|
|
139
|
+
const isQuantitative = QUANTITATIVE_COLUMN_TYPES.includes(normalized);
|
|
140
|
+
type = isQuantitative ? 'sequential' : 'categorical';
|
|
141
|
+
}
|
|
142
|
+
}
|
|
58
143
|
const scheme = patch.scheme ??
|
|
59
144
|
(patch.type && patch.type !== colorScale?.type
|
|
60
145
|
? undefined
|
|
61
|
-
: colorScale?.
|
|
146
|
+
: type !== colorScale?.type
|
|
147
|
+
? undefined
|
|
148
|
+
: colorScale?.scheme);
|
|
62
149
|
applyConfig(setDeckMapLayerColorScale(mapConfig, activeLayerIndex, effectiveColorAccessor, createDeckMapLayerColorScale({
|
|
63
150
|
field,
|
|
64
151
|
type,
|
|
@@ -66,9 +153,30 @@ export const MapSettingsPanel = ({ dashboardId, panel, onClose, }) => {
|
|
|
66
153
|
title: field,
|
|
67
154
|
})));
|
|
68
155
|
};
|
|
69
|
-
return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-3 py-1.5 text-xs font-medium", children: [_jsx("div", { className: "flex items-center", children: "Map settings" }), onClose && (_jsx(Button, { variant: "ghost", size: "icon", className: "h-5 w-5", onClick: onClose, "aria-label": "Close", children: _jsx(XIcon, { className: "h-3.5 w-3.5" }) }))] }), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-2", children: [layers.length > 0 && (_jsxs("div", { className: "flex flex-col gap-3", children: [layers.length > 1 && (_jsx(Field, { label: "Layer", children: _jsxs(Select, { value: String(activeLayerIndex), onValueChange: (value) => setLayerIndex(Number(value)), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: layers.map((layer, index) => (_jsx(SelectItem, { value: String(index), children: String(layer.id ?? `Layer ${index + 1}`) }, index))) })] }) })), _jsx(
|
|
156
|
+
return (_jsxs("div", { className: "flex h-full flex-col", children: [_jsxs("div", { className: "flex items-center justify-between border-b px-3 py-1.5 text-xs font-medium", children: [_jsx("div", { className: "flex items-center", children: "Map settings" }), onClose && (_jsx(Button, { variant: "ghost", size: "icon", className: "h-5 w-5", onClick: onClose, "aria-label": "Close", children: _jsx(XIcon, { className: "h-3.5 w-3.5" }) }))] }), _jsxs("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-2", children: [layers.length > 0 && (_jsxs("div", { className: "flex flex-col gap-3", children: [layers.length > 1 && (_jsx(Field, { label: "Layer", children: _jsxs(Select, { value: String(activeLayerIndex), onValueChange: (value) => setLayerIndex(Number(value)), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: layers.map((layer, index) => (_jsx(SelectItem, { value: String(index), children: String(layer.id ?? `Layer ${index + 1}`) }, index))) })] }) })), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium", children: "Visible" }), _jsx(Switch, { checked: activeLayer?.visible !== false, onCheckedChange: (checked) => applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
157
|
+
...layer,
|
|
158
|
+
visible: checked,
|
|
159
|
+
}))) })] }), _jsx(Field, { label: "Layer type", children: _jsxs(Select, { value: typeof activeLayer?.['@@type'] === 'string'
|
|
70
160
|
? activeLayer['@@type']
|
|
71
|
-
: undefined, onValueChange: (value) => applyConfig(setDeckMapLayerType(mapConfig, activeLayerIndex, value)), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, { placeholder: "Select layer type" }) }), _jsx(SelectContent, { children: DECK_MAP_LAYER_TYPE_OPTIONS.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] }) }),
|
|
161
|
+
: undefined, onValueChange: (value) => applyConfig(setDeckMapLayerType(mapConfig, activeLayerIndex, value)), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, { placeholder: "Select layer type" }) }), _jsx(SelectContent, { children: DECK_MAP_LAYER_TYPE_OPTIONS.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] }) }), showTripsSettings && !isAccessorBasedWidth && (_jsx(Field, { label: `Line width: ${lineWidthValue}${isWidthInPixels ? 'px' : 'm'}`, children: _jsx("div", { className: "pt-0.5", children: _jsx(Slider, { min: 1, max: isWidthInPixels ? 20 : 10000, step: isWidthInPixels ? 1 : 10, value: [lineWidthValue], onValueChange: (values) => {
|
|
162
|
+
const value = values[0] ?? 3;
|
|
163
|
+
applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
164
|
+
...layer,
|
|
165
|
+
...(isWidthInPixels ? { widthMinPixels: value } : {}),
|
|
166
|
+
getWidth: value,
|
|
167
|
+
})));
|
|
168
|
+
} }) }) })), showTripsSettings && (_jsx(Field, { label: `Trail length: ${Math.round((activeLayer?._trailLengthFactor ?? 0.4) * 100)}%`, children: _jsx("div", { className: "pt-0.5", children: _jsx(Slider, { min: 5, max: 100, step: 5, value: [
|
|
169
|
+
Math.round((activeLayer?._trailLengthFactor ?? 0.4) * 100),
|
|
170
|
+
], onValueChange: (values) => {
|
|
171
|
+
const value = (values[0] ?? 40) / 100;
|
|
172
|
+
applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
173
|
+
...layer,
|
|
174
|
+
_trailLengthFactor: value,
|
|
175
|
+
})));
|
|
176
|
+
} }) }) })), isHeatmapLayer ? (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-2", children: [_jsx("span", { className: "text-xs font-medium", children: "Color scheme (density)" }), _jsx(Field, { label: "Scheme", children: _jsxs(Select, { value: detectHeatmapScheme(activeLayer?.colorRange), onValueChange: (value) => applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
177
|
+
...layer,
|
|
178
|
+
colorRange: schemeToColorRange(value),
|
|
179
|
+
}))), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: continuousSequentialSchemes.map((scheme) => (_jsx(SelectItem, { value: scheme, children: scheme }, scheme))) })] }) })] })) : (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: "text-xs font-medium", children: "Color scale" }), _jsx(Switch, { checked: Boolean(colorScale), onCheckedChange: (checked) => {
|
|
72
180
|
if (!effectiveColorAccessor)
|
|
73
181
|
return;
|
|
74
182
|
if (checked) {
|
|
@@ -76,19 +184,89 @@ export const MapSettingsPanel = ({ dashboardId, panel, onClose, }) => {
|
|
|
76
184
|
return;
|
|
77
185
|
}
|
|
78
186
|
applyConfig(clearDeckMapLayerColorScale(mapConfig, activeLayerIndex, effectiveColorAccessor));
|
|
79
|
-
}, disabled: !firstColumnName || !effectiveColorAccessor })] }), effectiveColorAccessor && (_jsx(Field, { label: "Color property", children: _jsxs(Select, { value: effectiveColorAccessor, onValueChange: (value) => setColorAccessor(value), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: colorAccessorOptions.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] }) })), colorScale && dataTable && (_jsx(ColumnsProvider, { columns: dataTable.columns, children: _jsx(Field, { label: "Color field", required: true, children:
|
|
187
|
+
}, disabled: !firstColumnName || !effectiveColorAccessor })] }), effectiveColorAccessor && (_jsx(Field, { label: "Color property", children: _jsxs(Select, { value: effectiveColorAccessor, onValueChange: (value) => setColorAccessor(value), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: colorAccessorOptions.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] }) })), colorScale && dataTable && (_jsx(ColumnsProvider, { columns: dataTable.columns, children: _jsx(Field, { label: "Color field", required: true, children: _jsx(ColumnSelector, { value: colorScale.field, onChange: (field) => updateColorScale({ field }) }) }) })), colorScale && (_jsxs(_Fragment, { children: [_jsx(Field, { label: "Scale type", children: _jsxs(Select, { value: colorScaleType, onValueChange: (value) => updateColorScale({
|
|
80
188
|
type: value,
|
|
81
|
-
}), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: DECK_MAP_COLOR_SCALE_TYPE_OPTIONS.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] }) }), _jsx(Field, { label: "Scheme", children: _jsxs(Select, { value: colorScale.scheme, onValueChange: (value) => updateColorScale({ scheme: value }), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: schemeOptions.map((scheme) => (_jsx(SelectItem, { value: scheme, children: scheme }, scheme))) })] }) })] }))] })] })),
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
189
|
+
}), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: DECK_MAP_COLOR_SCALE_TYPE_OPTIONS.map((option) => (_jsx(SelectItem, { value: option.value, children: option.label }, option.value))) })] }) }), _jsx(Field, { label: "Scheme", children: _jsxs(Select, { value: colorScale.scheme, onValueChange: (value) => updateColorScale({ scheme: value }), children: [_jsx(SelectTrigger, { className: "w-full", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: schemeOptions.map((scheme) => (_jsx(SelectItem, { value: scheme, children: scheme }, scheme))) })] }) })] }))] }))] })), isHeatmapLayer && (_jsx(Field, { label: `Radius: ${activeLayer?.radiusPixels ?? 30}px`, children: _jsx("div", { className: "pt-0.5", children: _jsx(Slider, { min: 1, max: 100, step: 1, value: [
|
|
190
|
+
activeLayer?.radiusPixels ?? 30,
|
|
191
|
+
], onValueChange: (values) => {
|
|
192
|
+
const value = values[0] ?? 30;
|
|
193
|
+
applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
194
|
+
...layer,
|
|
195
|
+
radiusPixels: value,
|
|
196
|
+
})));
|
|
197
|
+
} }) }) })), showRadiusSetting && !isAccessorBasedRadius && (_jsx(Field, { label: `Point radius: ${pointRadiusValue}${isRadiusInPixels ? 'px' : 'm'}`, children: _jsx("div", { className: "pt-0.5", children: _jsx(Slider, { min: 1, max: isRadiusInPixels ? 50 : 10000, step: isRadiusInPixels ? 1 : 10, value: [pointRadiusValue], onValueChange: (values) => {
|
|
198
|
+
const value = values[0] ?? (isRadiusInPixels ? 2 : 100);
|
|
199
|
+
applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
200
|
+
...layer,
|
|
201
|
+
getRadius: value,
|
|
202
|
+
...(isRadiusInPixels
|
|
203
|
+
? {
|
|
204
|
+
radiusMinPixels: 1,
|
|
205
|
+
radiusMaxPixels: Math.max(value, layer.radiusMaxPixels ??
|
|
206
|
+
value),
|
|
207
|
+
}
|
|
208
|
+
: {}),
|
|
209
|
+
})));
|
|
210
|
+
} }) }) })), showColumnRadiusSetting && (_jsx(Field, { label: `Column radius: ${activeLayer?.radius ?? 50}m`, children: _jsx("div", { className: "pt-0.5", children: _jsx(Slider, { min: 1, max: 10000, step: 1, value: [activeLayer?.radius ?? 50], onValueChange: (values) => {
|
|
211
|
+
const value = values[0] ?? 50;
|
|
212
|
+
applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
213
|
+
...layer,
|
|
214
|
+
radius: value,
|
|
215
|
+
})));
|
|
216
|
+
} }) }) })), dataTable && showGeometryColumnSetting && (_jsx(ColumnsProvider, { columns: dataTable.columns, children: _jsx(Field, { label: "Geometry column", required: true, children: _jsx(ColumnSelector, { value: activeLayer?._sqlroomsBinding
|
|
217
|
+
?.geometryColumn ??
|
|
218
|
+
activeLayerDataset?.geometryColumn, onChange: (geometryColumn) => applyConfig(setDeckMapLayerGeometryColumn(mapConfig, activeLayerIndex, geometryColumn)), placeholder: "Select geometry column..." }) }) })), dataTable && showH3ColumnSetting && (_jsx(ColumnsProvider, { columns: dataTable.columns, children: _jsx(Field, { label: "H3 column", required: true, children: _jsx(ColumnSelector, { value: activeLayer?._sqlroomsBinding
|
|
219
|
+
?.hexagonColumn, onChange: (hexagonColumn) => applyConfig(setDeckMapLayerHexagonColumn(mapConfig, activeLayerIndex, hexagonColumn)), placeholder: "Select H3 index column..." }) }) })), dataTable && showArcColumnSetting && (_jsxs(ColumnsProvider, { columns: dataTable.columns, children: [_jsx(Field, { label: "Source latitude", required: true, children: _jsx(ColumnSelector, { value: activeLayer?._sqlroomsBinding
|
|
220
|
+
?.sourceLatitudeColumn, onChange: (sourceLatitudeColumn) => applyConfig(setDeckMapLayerArcColumns(mapConfig, activeLayerIndex, {
|
|
221
|
+
sourceLatitudeColumn,
|
|
222
|
+
})), placeholder: "Select source latitude..." }) }), _jsx(Field, { label: "Source longitude", required: true, children: _jsx(ColumnSelector, { value: activeLayer?._sqlroomsBinding
|
|
223
|
+
?.sourceLongitudeColumn, onChange: (sourceLongitudeColumn) => applyConfig(setDeckMapLayerArcColumns(mapConfig, activeLayerIndex, {
|
|
224
|
+
sourceLongitudeColumn,
|
|
225
|
+
})), placeholder: "Select source longitude..." }) }), _jsx(Field, { label: "Target latitude", required: true, children: _jsx(ColumnSelector, { value: activeLayer?._sqlroomsBinding
|
|
226
|
+
?.targetLatitudeColumn, onChange: (targetLatitudeColumn) => applyConfig(setDeckMapLayerArcColumns(mapConfig, activeLayerIndex, {
|
|
227
|
+
targetLatitudeColumn,
|
|
228
|
+
})), placeholder: "Select target latitude..." }) }), _jsx(Field, { label: "Target longitude", required: true, children: _jsx(ColumnSelector, { value: activeLayer?._sqlroomsBinding
|
|
229
|
+
?.targetLongitudeColumn, onChange: (targetLongitudeColumn) => applyConfig(setDeckMapLayerArcColumns(mapConfig, activeLayerIndex, {
|
|
230
|
+
targetLongitudeColumn,
|
|
231
|
+
})), placeholder: "Select target longitude..." }) })] })), showArcColumnSetting && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-xs font-medium", children: "Flat lines" }), _jsx(Switch, { checked: activeLayer?.getHeight === 0, onCheckedChange: (checked) => applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
232
|
+
...layer,
|
|
233
|
+
getHeight: checked ? 0 : undefined,
|
|
234
|
+
}))) })] })), showArcColumnSetting && !isAccessorBasedWidth && (_jsx(Field, { label: `Line width: ${lineWidthValue}${isWidthInPixels ? 'px' : 'm'}`, children: _jsx("div", { className: "pt-0.5", children: _jsx(Slider, { min: 1, max: isWidthInPixels ? 20 : 10000, step: isWidthInPixels ? 1 : 10, value: [lineWidthValue], onValueChange: (values) => {
|
|
235
|
+
const value = values[0] ?? 1;
|
|
236
|
+
applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
237
|
+
...layer,
|
|
238
|
+
...(isWidthInPixels ? { widthMinPixels: value } : {}),
|
|
239
|
+
getWidth: value,
|
|
240
|
+
})));
|
|
241
|
+
} }) }) })), showExtrusionSettings && (_jsxs("div", { className: "flex flex-col gap-2 rounded-md border p-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-2", children: [_jsx("span", { className: "text-xs font-medium", children: "Extrusion" }), _jsx(Switch, { checked: Boolean(activeLayer?.extruded), onCheckedChange: (checked) => applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
242
|
+
...layer,
|
|
243
|
+
extruded: checked,
|
|
244
|
+
}))) })] }), Boolean(activeLayer?.extruded) && dataTable && (_jsx(ColumnsProvider, { columns: dataTable.columns, children: _jsx(Field, { label: "Elevation column", children: _jsx(ColumnSelector.Numeric, { value: (() => {
|
|
245
|
+
const elev = activeLayer?.getElevation;
|
|
246
|
+
if (elev &&
|
|
247
|
+
typeof elev === 'object' &&
|
|
248
|
+
'@@function' in elev) {
|
|
249
|
+
return elev.field;
|
|
250
|
+
}
|
|
251
|
+
if (typeof elev === 'string' && elev.startsWith('@@=')) {
|
|
252
|
+
return elev.slice(3);
|
|
253
|
+
}
|
|
254
|
+
return undefined;
|
|
255
|
+
})(), onChange: (elevationColumn) => applyConfig(updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({
|
|
256
|
+
...layer,
|
|
257
|
+
getElevation: elevationColumn
|
|
258
|
+
? {
|
|
259
|
+
'@@function': 'scale',
|
|
260
|
+
field: elevationColumn,
|
|
261
|
+
type: 'linear',
|
|
262
|
+
domain: 'auto',
|
|
263
|
+
range: [0, 200],
|
|
264
|
+
}
|
|
265
|
+
: undefined,
|
|
266
|
+
elevationScale: layer.elevationScale ?? 1,
|
|
267
|
+
}))), placeholder: "Select elevation column..." }) }) }))] })), dataTable &&
|
|
268
|
+
!showGeometryColumnSetting &&
|
|
269
|
+
!showH3ColumnSetting &&
|
|
270
|
+
!showArcColumnSetting && (_jsxs(ColumnsProvider, { columns: dataTable.columns, children: [_jsx(Field, { label: "Latitude column", required: true, children: _jsx(LatitudeSelector, { dashboardId: dashboardId, panel: panel, currentTable: dataTable }) }), _jsx(Field, { label: "Longitude column", required: true, children: _jsx(LongitudeSelector, { dashboardId: dashboardId, panel: panel, currentTable: dataTable }) })] }))] })] }));
|
|
93
271
|
};
|
|
94
272
|
//# sourceMappingURL=MapSettings.js.map
|
package/dist/MapSettings.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MapSettings.js","sourceRoot":"","sources":["../src/MapSettings.tsx"],"names":[],"mappings":"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","sourcesContent":["import {FC, useCallback, useState} from 'react';\nimport {\n Field,\n ColumnSelector,\n ColumnsProvider,\n useStoreWithMosaicDashboard,\n useDataTable,\n} from '@sqlrooms/mosaic';\nimport type {MosaicDashboardPanelConfigType} from '@sqlrooms/mosaic';\nimport {\n binnedNumericSchemes,\n categoricalSchemes,\n continuousDivergingSchemes,\n continuousSequentialSchemes,\n} from '@sqlrooms/color-scales';\nimport type {ColorScaleConfig, ColorScaleScheme} from '@sqlrooms/color-scales';\nimport {\n Button,\n Input,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Switch,\n} from '@sqlrooms/ui';\nimport {XIcon} from 'lucide-react';\nimport {LatitudeSelector} from './LatitudeSelector';\nimport {LongitudeSelector} from './LongitudeSelector';\nimport type {DeckMapDashboardPanelConfig} from './dashboardConfig';\nimport {DEFAULT_DECK_MAP_MAX_DATA_POINTS} from './dashboardConfig';\nimport {\n clearDeckMapLayerColorScale,\n createDeckMapLayerColorScale,\n DECK_MAP_COLOR_SCALE_TYPE_OPTIONS,\n DECK_MAP_LAYER_TYPE_OPTIONS,\n getDeckMapColorAccessorOptions,\n getDeckMapLayerDatasetId,\n getDeckMapLayerColorScale,\n getDeckMapLayerRecords,\n setDeckMapLayerColorScale,\n setDeckMapLayerGeometryColumn,\n setDeckMapLayerType,\n type DeckMapLayerColorAccessor,\n usesGeometryColumnSetting,\n} from './mapLayerConfigUtils';\n\ninterface MapSettingsPanelProps {\n dashboardId: string;\n panel: MosaicDashboardPanelConfigType;\n onClose?: () => void;\n}\n\nfunction getSchemeOptions(type: ColorScaleConfig['type']) {\n if (type === 'categorical') {\n return categoricalSchemes;\n }\n if (type === 'diverging') {\n return continuousDivergingSchemes;\n }\n if (type === 'sequential') {\n return continuousSequentialSchemes;\n }\n return binnedNumericSchemes;\n}\n\nexport const MapSettingsPanel: FC<MapSettingsPanelProps> = ({\n dashboardId,\n panel,\n onClose,\n}) => {\n const [layerIndex, setLayerIndex] = useState(0);\n const [colorAccessor, setColorAccessor] =\n useState<DeckMapLayerColorAccessor>('getFillColor');\n\n const tableName = useStoreWithMosaicDashboard(\n (state) =>\n state.mosaicDashboard.config.dashboardsById[dashboardId]?.selectedTable,\n );\n\n const dataTable = useDataTable(tableName);\n\n const updatePanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updatePanel,\n );\n\n const mapConfig = panel.config as DeckMapDashboardPanelConfig;\n const layers = getDeckMapLayerRecords(mapConfig);\n const activeLayerIndex = Math.min(layerIndex, Math.max(layers.length - 1, 0));\n const activeLayer = layers[activeLayerIndex];\n const activeLayerDatasetId = getDeckMapLayerDatasetId(activeLayer);\n const activeLayerDataset = activeLayerDatasetId\n ? mapConfig.datasets?.[activeLayerDatasetId]\n : undefined;\n const showGeometryColumnSetting = usesGeometryColumnSetting(\n activeLayer?.['@@type'],\n );\n const colorAccessorOptions = getDeckMapColorAccessorOptions(\n activeLayer?.['@@type'],\n );\n const effectiveColorAccessor =\n colorAccessorOptions.find((option) => option.value === colorAccessor)\n ?.value ?? colorAccessorOptions[0]?.value;\n const colorScale = effectiveColorAccessor\n ? getDeckMapLayerColorScale(activeLayer, effectiveColorAccessor)\n : undefined;\n const colorScaleType = colorScale?.type ?? 'sequential';\n const schemeOptions = getSchemeOptions(colorScaleType);\n const firstColumnName = dataTable?.columns[0]?.name;\n const maxRows =\n mapConfig.dataPolicy?.maxRows ?? DEFAULT_DECK_MAP_MAX_DATA_POINTS;\n\n const applyConfig = useCallback(\n (config: DeckMapDashboardPanelConfig) => {\n updatePanel(dashboardId, panel.id, {\n config: {...config, settingsOpen: mapConfig.settingsOpen} as any,\n });\n },\n [dashboardId, mapConfig.settingsOpen, panel.id, updatePanel],\n );\n\n const updateColorScale = (patch: {\n field?: string;\n type?: ColorScaleConfig['type'];\n scheme?: ColorScaleScheme;\n }) => {\n const field = patch.field ?? colorScale?.field ?? firstColumnName;\n if (!field || !effectiveColorAccessor) return;\n\n const type = patch.type ?? colorScale?.type ?? 'sequential';\n const scheme =\n patch.scheme ??\n (patch.type && patch.type !== colorScale?.type\n ? undefined\n : colorScale?.scheme);\n\n applyConfig(\n setDeckMapLayerColorScale(\n mapConfig,\n activeLayerIndex,\n effectiveColorAccessor,\n createDeckMapLayerColorScale({\n field,\n type,\n scheme,\n title: field,\n }),\n ),\n );\n };\n\n return (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex items-center justify-between border-b px-3 py-1.5 text-xs font-medium\">\n <div className=\"flex items-center\">Map settings</div>\n {onClose && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-5 w-5\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <XIcon className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-2\">\n {layers.length > 0 && (\n <div className=\"flex flex-col gap-3\">\n {layers.length > 1 && (\n <Field label=\"Layer\">\n <Select\n value={String(activeLayerIndex)}\n onValueChange={(value) => setLayerIndex(Number(value))}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {layers.map((layer, index) => (\n <SelectItem key={index} value={String(index)}>\n {String(layer.id ?? `Layer ${index + 1}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n\n <Field label=\"Layer type\">\n <Select\n value={\n typeof activeLayer?.['@@type'] === 'string'\n ? activeLayer['@@type']\n : undefined\n }\n onValueChange={(value) =>\n applyConfig(\n setDeckMapLayerType(mapConfig, activeLayerIndex, value),\n )\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder=\"Select layer type\" />\n </SelectTrigger>\n <SelectContent>\n {DECK_MAP_LAYER_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n\n <div className=\"flex flex-col gap-2 rounded-md border p-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium\">Color scale</span>\n <Switch\n checked={Boolean(colorScale)}\n onCheckedChange={(checked) => {\n if (!effectiveColorAccessor) return;\n if (checked) {\n updateColorScale({});\n return;\n }\n applyConfig(\n clearDeckMapLayerColorScale(\n mapConfig,\n activeLayerIndex,\n effectiveColorAccessor,\n ),\n );\n }}\n disabled={!firstColumnName || !effectiveColorAccessor}\n />\n </div>\n\n {effectiveColorAccessor && (\n <Field label=\"Color property\">\n <Select\n value={effectiveColorAccessor}\n onValueChange={(value) =>\n setColorAccessor(value as DeckMapLayerColorAccessor)\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {colorAccessorOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n\n {colorScale && dataTable && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Color field\" required>\n {colorScaleType === 'categorical' ? (\n <ColumnSelector.Categorical\n value={colorScale.field}\n onChange={(field) => updateColorScale({field})}\n />\n ) : (\n <ColumnSelector.Quantitative\n value={colorScale.field}\n onChange={(field) => updateColorScale({field})}\n />\n )}\n </Field>\n </ColumnsProvider>\n )}\n\n {colorScale && (\n <>\n <Field label=\"Scale type\">\n <Select\n value={colorScaleType}\n onValueChange={(value) =>\n updateColorScale({\n type: value as ColorScaleConfig['type'],\n })\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DECK_MAP_COLOR_SCALE_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n\n <Field label=\"Scheme\">\n <Select\n value={colorScale.scheme}\n onValueChange={(value) =>\n updateColorScale({scheme: value as ColorScaleScheme})\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {schemeOptions.map((scheme) => (\n <SelectItem key={scheme} value={scheme}>\n {scheme}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n </>\n )}\n </div>\n </div>\n )}\n\n {dataTable && showGeometryColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Geometry column\" required>\n <ColumnSelector\n value={activeLayerDataset?.geometryColumn}\n onChange={(geometryColumn) =>\n applyConfig(\n setDeckMapLayerGeometryColumn(\n mapConfig,\n activeLayerIndex,\n geometryColumn,\n ),\n )\n }\n placeholder=\"Select geometry column...\"\n />\n </Field>\n </ColumnsProvider>\n )}\n\n {dataTable && !showGeometryColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Latitude column\" required>\n <LatitudeSelector\n dashboardId={dashboardId}\n panel={panel}\n currentTable={dataTable}\n />\n </Field>\n <Field label=\"Longitude column\" required>\n <LongitudeSelector\n dashboardId={dashboardId}\n panel={panel}\n currentTable={dataTable}\n />\n </Field>\n </ColumnsProvider>\n )}\n\n <Field label=\"Max rows\">\n <Input\n type=\"number\"\n min={1}\n value={maxRows}\n className=\"no-spinner\"\n onChange={(event) => {\n const parsed = Number.parseInt(event.target.value, 10);\n if (!Number.isFinite(parsed) || parsed < 1) return;\n applyConfig({\n ...mapConfig,\n dataPolicy: {\n ...mapConfig.dataPolicy,\n maxRows: parsed,\n },\n });\n }}\n placeholder={String(DEFAULT_DECK_MAP_MAX_DATA_POINTS)}\n />\n </Field>\n </div>\n </div>\n );\n};\n"]}
|
|
1
|
+
{"version":3,"file":"MapSettings.js","sourceRoot":"","sources":["../src/MapSettings.tsx"],"names":[],"mappings":"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","sourcesContent":["import {FC, useCallback, useState} from 'react';\nimport {\n Field,\n ColumnSelector,\n ColumnsProvider,\n useStoreWithMosaicDashboard,\n QUANTITATIVE_COLUMN_TYPES,\n} from '@sqlrooms/mosaic';\nimport {useDataTable} from '@sqlrooms/duckdb';\nimport type {MosaicDashboardPanelConfigType} from '@sqlrooms/mosaic';\nimport {\n binnedNumericSchemes,\n categoricalSchemes,\n continuousDivergingSchemes,\n continuousSequentialSchemes,\n continuousSequentialInterpolators,\n parseColorString,\n} from '@sqlrooms/color-scales';\nimport type {ColorScaleConfig, ColorScaleScheme} from '@sqlrooms/color-scales';\nimport {\n Button,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Slider,\n Switch,\n} from '@sqlrooms/ui';\nimport {XIcon} from 'lucide-react';\nimport {LatitudeSelector} from './LatitudeSelector';\nimport {LongitudeSelector} from './LongitudeSelector';\nimport type {DeckMapDashboardPanelConfig} from './dashboardConfig';\nimport {\n clearDeckMapLayerColorScale,\n createDeckMapLayerColorScale,\n DECK_MAP_COLOR_SCALE_TYPE_OPTIONS,\n DECK_MAP_LAYER_TYPE_OPTIONS,\n getDeckMapColorAccessorOptions,\n getDeckMapLayerDatasetId,\n getDeckMapLayerColorScale,\n getDeckMapLayerRecords,\n setDeckMapLayerColorScale,\n setDeckMapLayerGeometryColumn,\n setDeckMapLayerHexagonColumn,\n setDeckMapLayerArcColumns,\n setDeckMapLayerType,\n updateDeckMapLayer,\n type DeckMapLayerColorAccessor,\n usesGeometryColumnSetting,\n usesH3ColumnSetting,\n usesArcColumnSetting,\n usesRadiusSetting,\n usesColumnRadiusSetting,\n usesTripsSettings,\n usesExtrusionSettings,\n} from './mapLayerConfigUtils';\n\n/**\n * Extracts the primary table name from a simple SQL query.\n * Handles patterns like: `SELECT ... FROM tableName ...`\n * and `SELECT ... FROM \"tableName\" ...`\n */\nfunction extractTableFromSqlQuery(\n sqlQuery: string | undefined,\n): string | undefined {\n if (!sqlQuery) return undefined;\n const match = sqlQuery.match(/\\bFROM\\s+(?:\"([^\"]+)\"|(\\w[\\w.]*))/i);\n return match?.[1] ?? match?.[2];\n}\n\nconst HEATMAP_COLOR_STEPS = 6;\n\nfunction schemeToColorRange(\n scheme: string,\n): Array<[number, number, number, number]> {\n const interpolator =\n continuousSequentialInterpolators[\n scheme as keyof typeof continuousSequentialInterpolators\n ];\n if (!interpolator) {\n return continuousSequentialInterpolators.YlOrRd\n ? Array.from({length: HEATMAP_COLOR_STEPS}, (_, i) =>\n parseColorString(\n continuousSequentialInterpolators.YlOrRd(\n i / (HEATMAP_COLOR_STEPS - 1),\n ),\n ),\n )\n : [];\n }\n return Array.from({length: HEATMAP_COLOR_STEPS}, (_, i) =>\n parseColorString(interpolator(i / (HEATMAP_COLOR_STEPS - 1))),\n );\n}\n\nfunction detectHeatmapScheme(colorRange: unknown): string {\n if (!Array.isArray(colorRange) || colorRange.length === 0) return 'YlOrRd';\n for (const scheme of continuousSequentialSchemes) {\n const sampled = schemeToColorRange(scheme);\n if (sampled.length === colorRange.length) {\n const matches = sampled.every((color, idx) => {\n const actual = colorRange[idx];\n if (!Array.isArray(actual)) return false;\n return (\n Math.abs(color[0] - actual[0]) < 2 &&\n Math.abs(color[1] - actual[1]) < 2 &&\n Math.abs(color[2] - actual[2]) < 2\n );\n });\n if (matches) return scheme;\n }\n }\n return 'YlOrRd';\n}\n\ninterface MapSettingsPanelProps {\n dashboardId: string;\n panel: MosaicDashboardPanelConfigType;\n onClose?: () => void;\n}\n\nfunction getSchemeOptions(type: ColorScaleConfig['type']) {\n if (type === 'categorical') {\n return categoricalSchemes;\n }\n if (type === 'diverging') {\n return continuousDivergingSchemes;\n }\n if (type === 'sequential') {\n return continuousSequentialSchemes;\n }\n return binnedNumericSchemes;\n}\n\nexport const MapSettingsPanel: FC<MapSettingsPanelProps> = ({\n dashboardId,\n panel,\n onClose,\n}) => {\n const [layerIndex, setLayerIndex] = useState(0);\n const [colorAccessor, setColorAccessor] =\n useState<DeckMapLayerColorAccessor>('getFillColor');\n\n const dashboardSelectedTable = useStoreWithMosaicDashboard(\n (state) =>\n state.mosaicDashboard.config.dashboardsById[dashboardId]?.selectedTable,\n );\n\n const updatePanel = useStoreWithMosaicDashboard(\n (state) => state.mosaicDashboard.updatePanel,\n );\n\n const mapConfig = panel.config as DeckMapDashboardPanelConfig;\n const layers = getDeckMapLayerRecords(mapConfig);\n const activeLayerIndex = Math.min(layerIndex, Math.max(layers.length - 1, 0));\n const activeLayer = layers[activeLayerIndex];\n const activeLayerDatasetId = getDeckMapLayerDatasetId(activeLayer);\n const activeLayerDataset = activeLayerDatasetId\n ? mapConfig.datasets?.[activeLayerDatasetId]\n : undefined;\n\n // Resolve the table for column listing: prefer the dashboard's selected\n // table (which represents the user's active choice), falling back to the\n // dataset's explicit source table when no dashboard table is selected.\n const fallbackTableName =\n activeLayerDataset?.source?.tableName ||\n extractTableFromSqlQuery(activeLayerDataset?.source?.sqlQuery);\n const primaryTable = useDataTable(dashboardSelectedTable);\n const fallbackTable = useDataTable(fallbackTableName);\n const dataTable = primaryTable ?? fallbackTable;\n\n const showGeometryColumnSetting = usesGeometryColumnSetting(\n activeLayer?.['@@type'],\n );\n const showH3ColumnSetting = usesH3ColumnSetting(activeLayer?.['@@type']);\n const showArcColumnSetting = usesArcColumnSetting(activeLayer?.['@@type']);\n const showRadiusSetting = usesRadiusSetting(activeLayer?.['@@type']);\n const showColumnRadiusSetting = usesColumnRadiusSetting(\n activeLayer?.['@@type'],\n );\n const showTripsSettings = usesTripsSettings(activeLayer?.['@@type']);\n const showExtrusionSettings = usesExtrusionSettings(activeLayer?.['@@type']);\n const colorAccessorOptions = getDeckMapColorAccessorOptions(\n activeLayer?.['@@type'],\n );\n const effectiveColorAccessor =\n colorAccessorOptions.find((option) => option.value === colorAccessor)\n ?.value ?? colorAccessorOptions[0]?.value;\n const colorScale = effectiveColorAccessor\n ? getDeckMapLayerColorScale(activeLayer, effectiveColorAccessor)\n : undefined;\n const colorScaleType = colorScale?.type ?? 'sequential';\n const schemeOptions = getSchemeOptions(colorScaleType);\n const isHeatmapLayer = activeLayer?.['@@type'] === 'GeoArrowHeatmapLayer';\n const firstColumnName = dataTable?.columns[0]?.name;\n\n // Width/radius values can be either numeric constants (e.g. getWidth: 3)\n // or string accessor expressions (e.g. getRadius: '@@=Magnitude').\n // For pixel-unit layers, prefer getWidth/getRadius over widthMinPixels/radiusMinPixels\n // since that's the actual rendered value. When the accessor is a string expression,\n // hide the slider entirely to avoid displaying invalid values or accidentally\n // overwriting data-driven accessors with a constant on first interaction.\n const isWidthInPixels = activeLayer?.widthUnits === 'pixels';\n const rawWidth = activeLayer?.getWidth;\n const numericWidth = typeof rawWidth === 'number' ? rawWidth : undefined;\n const lineWidthValue = isWidthInPixels\n ? (numericWidth ?? (activeLayer?.widthMinPixels as number | undefined) ?? 1)\n : (numericWidth ?? 1);\n\n const isRadiusInPixels = activeLayer?.radiusUnits === 'pixels';\n const rawRadius = activeLayer?.getRadius;\n const numericRadius = typeof rawRadius === 'number' ? rawRadius : undefined;\n const pointRadiusValue = isRadiusInPixels\n ? (numericRadius ??\n (activeLayer?.radiusMinPixels as number | undefined) ??\n 2)\n : (numericRadius ?? 100);\n const isAccessorBasedRadius = typeof rawRadius === 'string';\n const isAccessorBasedWidth = typeof rawWidth === 'string';\n\n const applyConfig = useCallback(\n (config: DeckMapDashboardPanelConfig) => {\n updatePanel(dashboardId, panel.id, {\n config: {...config, settingsOpen: mapConfig.settingsOpen} as any,\n });\n },\n [dashboardId, mapConfig.settingsOpen, panel.id, updatePanel],\n );\n\n const updateColorScale = (patch: {\n field?: string;\n type?: ColorScaleConfig['type'];\n scheme?: ColorScaleScheme;\n }) => {\n const field = patch.field ?? colorScale?.field ?? firstColumnName;\n if (!field || !effectiveColorAccessor) return;\n\n let type = patch.type ?? colorScale?.type ?? 'sequential';\n\n // Auto-detect scale type when user changes the field\n if (patch.field && !patch.type && dataTable) {\n const col = dataTable.columns.find((c) => c.name === patch.field);\n if (col) {\n const normalized = col.type.split('(')[0]!.toUpperCase();\n const isQuantitative = QUANTITATIVE_COLUMN_TYPES.includes(normalized);\n type = isQuantitative ? 'sequential' : 'categorical';\n }\n }\n\n const scheme =\n patch.scheme ??\n (patch.type && patch.type !== colorScale?.type\n ? undefined\n : type !== colorScale?.type\n ? undefined\n : colorScale?.scheme);\n\n applyConfig(\n setDeckMapLayerColorScale(\n mapConfig,\n activeLayerIndex,\n effectiveColorAccessor,\n createDeckMapLayerColorScale({\n field,\n type,\n scheme,\n title: field,\n }),\n ),\n );\n };\n\n return (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex items-center justify-between border-b px-3 py-1.5 text-xs font-medium\">\n <div className=\"flex items-center\">Map settings</div>\n {onClose && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"h-5 w-5\"\n onClick={onClose}\n aria-label=\"Close\"\n >\n <XIcon className=\"h-3.5 w-3.5\" />\n </Button>\n )}\n </div>\n <div className=\"flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-2\">\n {layers.length > 0 && (\n <div className=\"flex flex-col gap-3\">\n {layers.length > 1 && (\n <Field label=\"Layer\">\n <Select\n value={String(activeLayerIndex)}\n onValueChange={(value) => setLayerIndex(Number(value))}\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {layers.map((layer, index) => (\n <SelectItem key={index} value={String(index)}>\n {String(layer.id ?? `Layer ${index + 1}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium\">Visible</span>\n <Switch\n checked={activeLayer?.visible !== false}\n onCheckedChange={(checked) =>\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n visible: checked,\n }),\n ),\n )\n }\n />\n </div>\n\n <Field label=\"Layer type\">\n <Select\n value={\n typeof activeLayer?.['@@type'] === 'string'\n ? activeLayer['@@type']\n : undefined\n }\n onValueChange={(value) =>\n applyConfig(\n setDeckMapLayerType(mapConfig, activeLayerIndex, value),\n )\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue placeholder=\"Select layer type\" />\n </SelectTrigger>\n <SelectContent>\n {DECK_MAP_LAYER_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n\n {showTripsSettings && !isAccessorBasedWidth && (\n <Field\n label={`Line width: ${lineWidthValue}${isWidthInPixels ? 'px' : 'm'}`}\n >\n <div className=\"pt-0.5\">\n <Slider\n min={1}\n max={isWidthInPixels ? 20 : 10000}\n step={isWidthInPixels ? 1 : 10}\n value={[lineWidthValue]}\n onValueChange={(values) => {\n const value = values[0] ?? 3;\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n ...(isWidthInPixels ? {widthMinPixels: value} : {}),\n getWidth: value,\n }),\n ),\n );\n }}\n />\n </div>\n </Field>\n )}\n {showTripsSettings && (\n <Field\n label={`Trail length: ${Math.round(((activeLayer?._trailLengthFactor as number | undefined) ?? 0.4) * 100)}%`}\n >\n <div className=\"pt-0.5\">\n <Slider\n min={5}\n max={100}\n step={5}\n value={[\n Math.round(\n ((activeLayer?._trailLengthFactor as\n | number\n | undefined) ?? 0.4) * 100,\n ),\n ]}\n onValueChange={(values) => {\n const value = (values[0] ?? 40) / 100;\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n _trailLengthFactor: value,\n }),\n ),\n );\n }}\n />\n </div>\n </Field>\n )}\n\n {isHeatmapLayer ? (\n <div className=\"flex flex-col gap-2 rounded-md border p-2\">\n <span className=\"text-xs font-medium\">\n Color scheme (density)\n </span>\n <Field label=\"Scheme\">\n <Select\n value={detectHeatmapScheme(activeLayer?.colorRange)}\n onValueChange={(value) =>\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n colorRange: schemeToColorRange(value),\n }),\n ),\n )\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {continuousSequentialSchemes.map((scheme) => (\n <SelectItem key={scheme} value={scheme}>\n {scheme}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n </div>\n ) : (\n <div className=\"flex flex-col gap-2 rounded-md border p-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium\">Color scale</span>\n <Switch\n checked={Boolean(colorScale)}\n onCheckedChange={(checked) => {\n if (!effectiveColorAccessor) return;\n if (checked) {\n updateColorScale({});\n return;\n }\n applyConfig(\n clearDeckMapLayerColorScale(\n mapConfig,\n activeLayerIndex,\n effectiveColorAccessor,\n ),\n );\n }}\n disabled={!firstColumnName || !effectiveColorAccessor}\n />\n </div>\n\n {effectiveColorAccessor && (\n <Field label=\"Color property\">\n <Select\n value={effectiveColorAccessor}\n onValueChange={(value) =>\n setColorAccessor(value as DeckMapLayerColorAccessor)\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {colorAccessorOptions.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n )}\n\n {colorScale && dataTable && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Color field\" required>\n <ColumnSelector\n value={colorScale.field}\n onChange={(field) => updateColorScale({field})}\n />\n </Field>\n </ColumnsProvider>\n )}\n\n {colorScale && (\n <>\n <Field label=\"Scale type\">\n <Select\n value={colorScaleType}\n onValueChange={(value) =>\n updateColorScale({\n type: value as ColorScaleConfig['type'],\n })\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {DECK_MAP_COLOR_SCALE_TYPE_OPTIONS.map((option) => (\n <SelectItem key={option.value} value={option.value}>\n {option.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n\n <Field label=\"Scheme\">\n <Select\n value={colorScale.scheme}\n onValueChange={(value) =>\n updateColorScale({scheme: value as ColorScaleScheme})\n }\n >\n <SelectTrigger className=\"w-full\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {schemeOptions.map((scheme) => (\n <SelectItem key={scheme} value={scheme}>\n {scheme}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </Field>\n </>\n )}\n </div>\n )}\n </div>\n )}\n\n {isHeatmapLayer && (\n <Field\n label={`Radius: ${(activeLayer?.radiusPixels as number | undefined) ?? 30}px`}\n >\n <div className=\"pt-0.5\">\n <Slider\n min={1}\n max={100}\n step={1}\n value={[\n (activeLayer?.radiusPixels as number | undefined) ?? 30,\n ]}\n onValueChange={(values) => {\n const value = values[0] ?? 30;\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n radiusPixels: value,\n }),\n ),\n );\n }}\n />\n </div>\n </Field>\n )}\n\n {showRadiusSetting && !isAccessorBasedRadius && (\n <Field\n label={`Point radius: ${pointRadiusValue}${isRadiusInPixels ? 'px' : 'm'}`}\n >\n <div className=\"pt-0.5\">\n <Slider\n min={1}\n max={isRadiusInPixels ? 50 : 10000}\n step={isRadiusInPixels ? 1 : 10}\n value={[pointRadiusValue]}\n onValueChange={(values) => {\n const value = values[0] ?? (isRadiusInPixels ? 2 : 100);\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n getRadius: value,\n ...(isRadiusInPixels\n ? {\n radiusMinPixels: 1,\n radiusMaxPixels: Math.max(\n value,\n (layer.radiusMaxPixels as number | undefined) ??\n value,\n ),\n }\n : {}),\n }),\n ),\n );\n }}\n />\n </div>\n </Field>\n )}\n\n {showColumnRadiusSetting && (\n <Field\n label={`Column radius: ${(activeLayer?.radius as number | undefined) ?? 50}m`}\n >\n <div className=\"pt-0.5\">\n <Slider\n min={1}\n max={10000}\n step={1}\n value={[(activeLayer?.radius as number | undefined) ?? 50]}\n onValueChange={(values) => {\n const value = values[0] ?? 50;\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n radius: value,\n }),\n ),\n );\n }}\n />\n </div>\n </Field>\n )}\n\n {dataTable && showGeometryColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Geometry column\" required>\n <ColumnSelector\n value={\n ((activeLayer?._sqlroomsBinding as Record<string, unknown>)\n ?.geometryColumn as string | undefined) ??\n activeLayerDataset?.geometryColumn\n }\n onChange={(geometryColumn) =>\n applyConfig(\n setDeckMapLayerGeometryColumn(\n mapConfig,\n activeLayerIndex,\n geometryColumn,\n ),\n )\n }\n placeholder=\"Select geometry column...\"\n />\n </Field>\n </ColumnsProvider>\n )}\n\n {dataTable && showH3ColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"H3 column\" required>\n <ColumnSelector\n value={\n (activeLayer?._sqlroomsBinding as Record<string, unknown>)\n ?.hexagonColumn as string | undefined\n }\n onChange={(hexagonColumn) =>\n applyConfig(\n setDeckMapLayerHexagonColumn(\n mapConfig,\n activeLayerIndex,\n hexagonColumn,\n ),\n )\n }\n placeholder=\"Select H3 index column...\"\n />\n </Field>\n </ColumnsProvider>\n )}\n\n {dataTable && showArcColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Source latitude\" required>\n <ColumnSelector\n value={\n (activeLayer?._sqlroomsBinding as Record<string, unknown>)\n ?.sourceLatitudeColumn as string | undefined\n }\n onChange={(sourceLatitudeColumn) =>\n applyConfig(\n setDeckMapLayerArcColumns(mapConfig, activeLayerIndex, {\n sourceLatitudeColumn,\n }),\n )\n }\n placeholder=\"Select source latitude...\"\n />\n </Field>\n <Field label=\"Source longitude\" required>\n <ColumnSelector\n value={\n (activeLayer?._sqlroomsBinding as Record<string, unknown>)\n ?.sourceLongitudeColumn as string | undefined\n }\n onChange={(sourceLongitudeColumn) =>\n applyConfig(\n setDeckMapLayerArcColumns(mapConfig, activeLayerIndex, {\n sourceLongitudeColumn,\n }),\n )\n }\n placeholder=\"Select source longitude...\"\n />\n </Field>\n <Field label=\"Target latitude\" required>\n <ColumnSelector\n value={\n (activeLayer?._sqlroomsBinding as Record<string, unknown>)\n ?.targetLatitudeColumn as string | undefined\n }\n onChange={(targetLatitudeColumn) =>\n applyConfig(\n setDeckMapLayerArcColumns(mapConfig, activeLayerIndex, {\n targetLatitudeColumn,\n }),\n )\n }\n placeholder=\"Select target latitude...\"\n />\n </Field>\n <Field label=\"Target longitude\" required>\n <ColumnSelector\n value={\n (activeLayer?._sqlroomsBinding as Record<string, unknown>)\n ?.targetLongitudeColumn as string | undefined\n }\n onChange={(targetLongitudeColumn) =>\n applyConfig(\n setDeckMapLayerArcColumns(mapConfig, activeLayerIndex, {\n targetLongitudeColumn,\n }),\n )\n }\n placeholder=\"Select target longitude...\"\n />\n </Field>\n </ColumnsProvider>\n )}\n\n {showArcColumnSetting && (\n <div className=\"flex items-center justify-between\">\n <span className=\"text-xs font-medium\">Flat lines</span>\n <Switch\n checked={activeLayer?.getHeight === 0}\n onCheckedChange={(checked) =>\n applyConfig(\n updateDeckMapLayer(mapConfig, activeLayerIndex, (layer) => ({\n ...layer,\n getHeight: checked ? 0 : undefined,\n })),\n )\n }\n />\n </div>\n )}\n\n {showArcColumnSetting && !isAccessorBasedWidth && (\n <Field\n label={`Line width: ${lineWidthValue}${isWidthInPixels ? 'px' : 'm'}`}\n >\n <div className=\"pt-0.5\">\n <Slider\n min={1}\n max={isWidthInPixels ? 20 : 10000}\n step={isWidthInPixels ? 1 : 10}\n value={[lineWidthValue]}\n onValueChange={(values) => {\n const value = values[0] ?? 1;\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n ...(isWidthInPixels ? {widthMinPixels: value} : {}),\n getWidth: value,\n }),\n ),\n );\n }}\n />\n </div>\n </Field>\n )}\n\n {showExtrusionSettings && (\n <div className=\"flex flex-col gap-2 rounded-md border p-2\">\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"text-xs font-medium\">Extrusion</span>\n <Switch\n checked={Boolean(activeLayer?.extruded)}\n onCheckedChange={(checked) =>\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n extruded: checked,\n }),\n ),\n )\n }\n />\n </div>\n\n {Boolean(activeLayer?.extruded) && dataTable && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Elevation column\">\n <ColumnSelector.Numeric\n value={(() => {\n const elev = activeLayer?.getElevation;\n if (\n elev &&\n typeof elev === 'object' &&\n '@@function' in (elev as object)\n ) {\n return (elev as Record<string, unknown>).field as\n | string\n | undefined;\n }\n if (typeof elev === 'string' && elev.startsWith('@@=')) {\n return elev.slice(3);\n }\n return undefined;\n })()}\n onChange={(elevationColumn) =>\n applyConfig(\n updateDeckMapLayer(\n mapConfig,\n activeLayerIndex,\n (layer) => ({\n ...layer,\n getElevation: elevationColumn\n ? {\n '@@function': 'scale',\n field: elevationColumn,\n type: 'linear',\n domain: 'auto',\n range: [0, 200],\n }\n : undefined,\n elevationScale: layer.elevationScale ?? 1,\n }),\n ),\n )\n }\n placeholder=\"Select elevation column...\"\n />\n </Field>\n </ColumnsProvider>\n )}\n </div>\n )}\n\n {dataTable &&\n !showGeometryColumnSetting &&\n !showH3ColumnSetting &&\n !showArcColumnSetting && (\n <ColumnsProvider columns={dataTable.columns}>\n <Field label=\"Latitude column\" required>\n <LatitudeSelector\n dashboardId={dashboardId}\n panel={panel}\n currentTable={dataTable}\n />\n </Field>\n <Field label=\"Longitude column\" required>\n <LongitudeSelector\n dashboardId={dashboardId}\n panel={panel}\n currentTable={dataTable}\n />\n </Field>\n </ColumnsProvider>\n )}\n </div>\n </div>\n );\n};\n"]}
|