@kanaries/graphic-walker 0.4.2 → 0.4.4

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.
@@ -270,6 +270,7 @@ export interface IChartExportResult<T extends 'svg' | 'data-url' = 'svg' | 'data
270
270
  canvas(): HTMLCanvasElement | null;
271
271
  }[];
272
272
  container(): HTMLDivElement | null;
273
+ chartType?: string;
273
274
  }
274
275
  interface IExportChart {
275
276
  <T extends Extract<IChartExportResult['mode'], 'svg'>>(mode?: T): Promise<IChartExportResult<T>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kanaries/graphic-walker",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "scripts": {
5
5
  "dev:front_end": "vite --host",
6
6
  "dev": "npm run dev:front_end",
@@ -7,9 +7,11 @@ import { getMeaAggKey } from "../../utils";
7
7
  import { useColorScale, useOpacityScale } from "./encodings";
8
8
  import { isValidLatLng } from "./POIRenderer";
9
9
  import { TooltipContent } from "./tooltip";
10
+ import { useAppRootContext } from "../appRoot";
10
11
 
11
12
 
12
13
  export interface IChoroplethRendererProps {
14
+ name?: string;
13
15
  data: IRow[];
14
16
  allFields: DeepReadonly<IViewField[]>;
15
17
  features: FeatureCollection | undefined;
@@ -86,7 +88,7 @@ const resolveCenter = (coordinates: [lat: number, lng: number][]): [lng: number,
86
88
  };
87
89
 
88
90
  const ChoroplethRenderer = forwardRef<IChoroplethRendererRef, IChoroplethRendererProps>(function ChoroplethRenderer (props, ref) {
89
- const { data, allFields, features, geoKey, defaultAggregated, geoId, color, opacity, text, details, vegaConfig, scaleIncludeUnmatchedChoropleth } = props;
91
+ const { name, data, allFields, features, geoKey, defaultAggregated, geoId, color, opacity, text, details, vegaConfig, scaleIncludeUnmatchedChoropleth } = props;
90
92
 
91
93
  useImperativeHandle(ref, () => ({}));
92
94
 
@@ -190,6 +192,23 @@ const ChoroplethRenderer = forwardRef<IChoroplethRendererRef, IChoroplethRendere
190
192
  };
191
193
  }
192
194
  });
195
+
196
+ const appRef = useAppRootContext();
197
+
198
+ useEffect(() => {
199
+ const ctx = appRef.current;
200
+ if (ctx) {
201
+ ctx.exportChart = async (mode) => ({
202
+ mode,
203
+ title: name || 'untitled',
204
+ nCols: 0,
205
+ nRows: 0,
206
+ charts: [],
207
+ container: () => mapRef.current?.getContainer() as HTMLDivElement ?? null,
208
+ chartType: 'map'
209
+ })
210
+ }
211
+ }, []);
193
212
 
194
213
  useEffect(() => {
195
214
  mapRef.current?.flyToBounds(bounds);
@@ -5,9 +5,11 @@ import type { DeepReadonly, IRow, IViewField, VegaGlobalConfig } from "../../int
5
5
  import { getMeaAggKey } from "../../utils";
6
6
  import { useColorScale, useOpacityScale, useSizeScale } from "./encodings";
7
7
  import { TooltipContent } from "./tooltip";
8
+ import { useAppRootContext } from "../appRoot";
8
9
 
9
10
 
10
11
  export interface IPOIRendererProps {
12
+ name?: string;
11
13
  data: IRow[];
12
14
  allFields: DeepReadonly<IViewField[]>;
13
15
  defaultAggregated: boolean;
@@ -39,7 +41,7 @@ const formatCoerceLatLng = (latRaw: unknown, lngRaw: unknown) => {
39
41
  const debugMaxLen = 20;
40
42
 
41
43
  const POIRenderer = forwardRef<IPOIRendererRef, IPOIRendererProps>(function POIRenderer (props, ref) {
42
- const { data, allFields, latitude, longitude, color, opacity, size, details, defaultAggregated, vegaConfig } = props;
44
+ const { name, data, allFields, latitude, longitude, color, opacity, size, details, defaultAggregated, vegaConfig } = props;
43
45
 
44
46
  const lngLat = useMemo<[lat: number, lng: number][]>(() => {
45
47
  if (longitude && latitude) {
@@ -100,6 +102,23 @@ const POIRenderer = forwardRef<IPOIRendererRef, IPOIRendererProps>(function POIR
100
102
  }
101
103
  });
102
104
 
105
+ const appRef = useAppRootContext();
106
+
107
+ useEffect(() => {
108
+ const ctx = appRef.current;
109
+ if (ctx) {
110
+ ctx.exportChart = async (mode) => ({
111
+ mode,
112
+ title: name || 'untitled',
113
+ nCols: 0,
114
+ nRows: 0,
115
+ charts: [],
116
+ container: () => mapRef.current?.getContainer() as HTMLDivElement ?? null,
117
+ chartType: 'map',
118
+ })
119
+ }
120
+ }, []);
121
+
103
122
  useEffect(() => {
104
123
  mapRef.current?.flyToBounds(bounds);
105
124
  }, [`${bounds[0][0]},${bounds[0][1]},${bounds[1][0]},${bounds[1][1]}`]);
@@ -5,6 +5,7 @@ import ChoroplethRenderer from "./ChoroplethRenderer";
5
5
 
6
6
 
7
7
  export interface ILeafletRendererProps {
8
+ name?: string;
8
9
  vegaConfig?: VegaGlobalConfig;
9
10
  draggableFieldState: DeepReadonly<DraggableFieldState>;
10
11
  visualConfig: DeepReadonly<IVisualConfig>;
@@ -17,7 +18,7 @@ export const LEAFLET_DEFAULT_WIDTH = 800;
17
18
  export const LEAFLET_DEFAULT_HEIGHT = 600;
18
19
 
19
20
  const LeafletRenderer = forwardRef<ILeafletRendererRef, ILeafletRendererProps>(function LeafletRenderer (props, ref) {
20
- const { draggableFieldState, data, visualConfig, vegaConfig = {} } = props;
21
+ const { name, draggableFieldState, data, visualConfig, vegaConfig = {} } = props;
21
22
  const { latitude: [lat], longitude: [lng], geoId: [geoId], dimensions, measures, size: [size], color: [color], opacity: [opacity], text: [text], details } = draggableFieldState;
22
23
  const { defaultAggregated, geoms: [markType], geojson, geoKey = '', scaleIncludeUnmatchedChoropleth = false } = visualConfig;
23
24
  const allFields = useMemo(() => [...dimensions, ...measures], [dimensions, measures]);
@@ -29,6 +30,7 @@ const LeafletRenderer = forwardRef<ILeafletRendererRef, ILeafletRendererProps>(f
29
30
  if (markType === 'poi') {
30
31
  return (
31
32
  <POIRenderer
33
+ name={name}
32
34
  data={data}
33
35
  allFields={allFields}
34
36
  defaultAggregated={defaultAggregated}
@@ -44,6 +46,7 @@ const LeafletRenderer = forwardRef<ILeafletRendererRef, ILeafletRendererProps>(f
44
46
  } else if (markType === 'choropleth') {
45
47
  return (
46
48
  <ChoroplethRenderer
49
+ name={name}
47
50
  data={data}
48
51
  allFields={allFields}
49
52
  features={geojson}
@@ -1,7 +1,11 @@
1
1
  import React from 'react';
2
+ import Spinner from './spinner';
2
3
 
3
4
  export default function LoadingLayer () {
4
5
  return <div className="bg-gray-100/50 dark:bg-gray-700/50 absolute top-0 left-0 right-0 bottom-0 z-50 flex items-center justify-center">
5
- Loading...
6
+ <Spinner className="text-indigo-500" />
7
+ <span className="text-sm text-indigo-500">
8
+ Loading...
9
+ </span>
6
10
  </div>
7
11
  }
@@ -1,8 +1,9 @@
1
1
  import React from 'react';
2
2
 
3
- export default function Spinner() {
3
+ export default function Spinner(props: { className?: string }) {
4
+ const className = props.className || 'text-white';
4
5
  return (
5
- <svg className="animate-spin ml-2 mr-2 h-5 w-5 text-white" viewBox="0 0 24 24">
6
+ <svg className={`animate-spin ml-2 mr-2 h-5 w-5 ${className}`} viewBox="0 0 24 24">
6
7
  <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
7
8
  <path
8
9
  className="opacity-75"
package/src/interfaces.ts CHANGED
@@ -311,6 +311,7 @@ export interface IChartExportResult<T extends 'svg' | 'data-url' = 'svg' | 'data
311
311
  canvas(): HTMLCanvasElement | null;
312
312
  }[];
313
313
  container(): HTMLDivElement | null;
314
+ chartType?: string;
314
315
  }
315
316
 
316
317
  interface IExportChart {
@@ -76,7 +76,7 @@ const Renderer = forwardRef<IReactVegaHandler, RendererProps>(function (props, r
76
76
  setViewConfig(latestFromRef.current.visualConfig);
77
77
  });
78
78
  }
79
- }, [waiting, vizStore]);
79
+ }, [waiting, data, vizStore]);
80
80
 
81
81
  useChartIndexControl({
82
82
  count: visList.length,
@@ -107,6 +107,7 @@ const PureRenderer = forwardRef<IReactVegaHandler, IPureRendererProps>(function
107
107
  <div className="relative">
108
108
  {isSpatial && (
109
109
  <LeafletRenderer
110
+ name={name}
110
111
  data={data}
111
112
  draggableFieldState={visualState}
112
113
  visualConfig={visualConfig}
@@ -146,6 +146,7 @@ const SpecRenderer = forwardRef<IReactVegaHandler, SpecRendererProps>(function (
146
146
  {loading && <LoadingLayer />}
147
147
  {isSpatial && (
148
148
  <LeafletRenderer
149
+ name={name}
149
150
  data={data}
150
151
  draggableFieldState={draggableFieldState}
151
152
  visualConfig={visualConfig}
@@ -89,6 +89,7 @@ export const useVegaExportApi = (
89
89
  nCols: 0,
90
90
  nRows: 0,
91
91
  charts: [],
92
+ chartType: 'vega',
92
93
  };
93
94
  }
94
95
  if (ctx.renderStatus !== 'idle') {
@@ -114,6 +115,7 @@ export const useVegaExportApi = (
114
115
  nCols: 0,
115
116
  nRows: 0,
116
117
  charts: [],
118
+ chartType: 'vega',
117
119
  };
118
120
  } finally {
119
121
  dispose?.();
@@ -139,6 +141,7 @@ export const useVegaExportApi = (
139
141
  container() {
140
142
  return containerRef.current;
141
143
  },
144
+ chartType: 'vega',
142
145
  };
143
146
  if (mode === 'data-url') {
144
147
  const imgData = await renderHandle.getCanvasData();