@kanaries/graphic-walker 0.3.12 → 0.3.14

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.
@@ -22,7 +22,7 @@ import {
22
22
  } from '@heroicons/react/24/outline';
23
23
  import { observer } from 'mobx-react-lite';
24
24
  import React, { SVGProps, useCallback, useMemo } from 'react';
25
- import styled from 'styled-components'
25
+ import styled from 'styled-components';
26
26
  import { useTranslation } from 'react-i18next';
27
27
  import { ResizeDialog } from '../components/sizeSetting';
28
28
  import { GEMO_TYPES, STACK_MODE, CHART_LAYOUT_TYPE } from '../config';
@@ -33,7 +33,8 @@ import Toolbar, { ToolbarItemProps } from '../components/toolbar';
33
33
  import { ButtonWithShortcut } from './menubar';
34
34
  import { useCurrentMediaTheme } from '../utils/media';
35
35
  import throttle from '../utils/throttle';
36
-
36
+ import KanariesLogo from '../assets/kanaries.png';
37
+ import { ImageWithFallback } from '../components/timeoutImg';
37
38
 
38
39
  const Invisible = styled.div`
39
40
  clip: rect(1px, 1px, 1px, 1px);
@@ -65,24 +66,39 @@ interface IVisualSettings {
65
66
  extra?: ToolbarItemProps[];
66
67
  }
67
68
 
68
- const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePreference, extra = [], exclude = [] }) => {
69
+ const VisualSettings: React.FC<IVisualSettings> = ({
70
+ rendererHandler,
71
+ darkModePreference,
72
+ extra = [],
73
+ exclude = [],
74
+ }) => {
69
75
  const { vizStore, commonStore } = useGlobalStore();
70
76
  const { visualConfig, canUndo, canRedo } = vizStore;
71
77
  const { t: tGlobal } = useTranslation();
72
78
  const { t } = useTranslation('translation', { keyPrefix: 'main.tabpanel.settings' });
73
79
 
74
80
  const {
75
- defaultAggregated, geoms: [markType], stack, interactiveScale, size: { mode: sizeMode, width, height },
81
+ defaultAggregated,
82
+ geoms: [markType],
83
+ stack,
84
+ interactiveScale,
85
+ size: { mode: sizeMode, width, height },
76
86
  showActions,
77
87
  } = visualConfig;
78
88
 
79
- const downloadPNG = useCallback(throttle(() => {
80
- rendererHandler?.current?.downloadPNG();
81
- }, 200), [rendererHandler]);
89
+ const downloadPNG = useCallback(
90
+ throttle(() => {
91
+ rendererHandler?.current?.downloadPNG();
92
+ }, 200),
93
+ [rendererHandler]
94
+ );
82
95
 
83
- const downloadSVG = useCallback(throttle(() => {
84
- rendererHandler?.current?.downloadSVG();
85
- }, 200), [rendererHandler]);
96
+ const downloadSVG = useCallback(
97
+ throttle(() => {
98
+ rendererHandler?.current?.downloadSVG();
99
+ }, 200),
100
+ [rendererHandler]
101
+ );
86
102
 
87
103
  const dark = useCurrentMediaTheme(darkModePreference) === 'dark';
88
104
 
@@ -132,7 +148,7 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
132
148
  label: t('toggle.aggregation'),
133
149
  icon: CubeIcon,
134
150
  checked: defaultAggregated,
135
- onChange: checked => {
151
+ onChange: (checked) => {
136
152
  vizStore.setVisualConfig('defaultAggregated', checked);
137
153
  },
138
154
  },
@@ -145,27 +161,195 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
145
161
  color: 'rgb(294,115,22)',
146
162
  },
147
163
  },
148
- options: GEMO_TYPES.map(g => ({
164
+ options: GEMO_TYPES.map((g) => ({
149
165
  key: g,
150
166
  label: tGlobal(`constant.mark_type.${g}`),
151
167
  icon: {
152
168
  auto: LightBulbIcon,
153
- bar: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M9,4v16h6v-16Z" /></svg>,
154
- line: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M5,6L19,18" /></svg>,
155
- area: (props: SVGProps<SVGSVGElement>) => <svg stroke="none" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M5,20v-17l14,4V20Z" /></svg>,
156
- trail: (props: SVGProps<SVGSVGElement>) => <svg stroke="none" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M5,6l7,4l7-2v2l-7,4l-7,-4z" /></svg>,
157
- point: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M9,12 A3,3,0,0,1,16,12 A3,3,0,0,1,9,12" /></svg>,
158
- circle: (props: SVGProps<SVGSVGElement>) => <svg stroke="none" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M6,12 A6,6,0,0,1,18,12 A6,6,0,0,1,6,12" /></svg>,
159
- tick: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M5,12h14" /></svg>,
160
- rect: (props: SVGProps<SVGSVGElement>) => <svg stroke="none" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M5,5v14h14v-14z" /></svg>,
161
- text: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M10.5 21l5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 016-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 01-3.827-5.802" /></svg>,
162
- arc: (props: SVGProps<SVGSVGElement>) => <svg stroke="none" fill="currentColor" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M12,21l-9,-15a12,12,0,0,1,18,0Z" /></svg>,
163
- boxplot: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M7,7v9h10v-9Zm0,4h8M12,7v-6m-3,0h6M12,16v7m-3,0h6" /></svg>,
164
- table: (props: SVGProps<SVGSVGElement>) => <svg stroke="currentColor" fill="none" strokeWidth="1.5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden {...props}><path strokeLinecap="round" strokeLinejoin="round" d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 01-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0112 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5" /></svg>
169
+ bar: (props: SVGProps<SVGSVGElement>) => (
170
+ <svg
171
+ stroke="currentColor"
172
+ fill="none"
173
+ strokeWidth="1.5"
174
+ xmlns="http://www.w3.org/2000/svg"
175
+ viewBox="0 0 24 24"
176
+ aria-hidden
177
+ {...props}
178
+ >
179
+ <path strokeLinecap="round" strokeLinejoin="round" d="M9,4v16h6v-16Z" />
180
+ </svg>
181
+ ),
182
+ line: (props: SVGProps<SVGSVGElement>) => (
183
+ <svg
184
+ stroke="currentColor"
185
+ fill="none"
186
+ strokeWidth="1.5"
187
+ xmlns="http://www.w3.org/2000/svg"
188
+ viewBox="0 0 24 24"
189
+ aria-hidden
190
+ {...props}
191
+ >
192
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5,6L19,18" />
193
+ </svg>
194
+ ),
195
+ area: (props: SVGProps<SVGSVGElement>) => (
196
+ <svg
197
+ stroke="none"
198
+ fill="currentColor"
199
+ strokeWidth="1.5"
200
+ xmlns="http://www.w3.org/2000/svg"
201
+ viewBox="0 0 24 24"
202
+ aria-hidden
203
+ {...props}
204
+ >
205
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5,20v-17l14,4V20Z" />
206
+ </svg>
207
+ ),
208
+ trail: (props: SVGProps<SVGSVGElement>) => (
209
+ <svg
210
+ stroke="none"
211
+ fill="currentColor"
212
+ strokeWidth="1.5"
213
+ xmlns="http://www.w3.org/2000/svg"
214
+ viewBox="0 0 24 24"
215
+ aria-hidden
216
+ {...props}
217
+ >
218
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5,6l7,4l7-2v2l-7,4l-7,-4z" />
219
+ </svg>
220
+ ),
221
+ point: (props: SVGProps<SVGSVGElement>) => (
222
+ <svg
223
+ stroke="currentColor"
224
+ fill="none"
225
+ strokeWidth="1.5"
226
+ xmlns="http://www.w3.org/2000/svg"
227
+ viewBox="0 0 24 24"
228
+ aria-hidden
229
+ {...props}
230
+ >
231
+ <path
232
+ strokeLinecap="round"
233
+ strokeLinejoin="round"
234
+ d="M9,12 A3,3,0,0,1,16,12 A3,3,0,0,1,9,12"
235
+ />
236
+ </svg>
237
+ ),
238
+ circle: (props: SVGProps<SVGSVGElement>) => (
239
+ <svg
240
+ stroke="none"
241
+ fill="currentColor"
242
+ strokeWidth="1.5"
243
+ xmlns="http://www.w3.org/2000/svg"
244
+ viewBox="0 0 24 24"
245
+ aria-hidden
246
+ {...props}
247
+ >
248
+ <path
249
+ strokeLinecap="round"
250
+ strokeLinejoin="round"
251
+ d="M6,12 A6,6,0,0,1,18,12 A6,6,0,0,1,6,12"
252
+ />
253
+ </svg>
254
+ ),
255
+ tick: (props: SVGProps<SVGSVGElement>) => (
256
+ <svg
257
+ stroke="currentColor"
258
+ fill="none"
259
+ strokeWidth="1.5"
260
+ xmlns="http://www.w3.org/2000/svg"
261
+ viewBox="0 0 24 24"
262
+ aria-hidden
263
+ {...props}
264
+ >
265
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5,12h14" />
266
+ </svg>
267
+ ),
268
+ rect: (props: SVGProps<SVGSVGElement>) => (
269
+ <svg
270
+ stroke="none"
271
+ fill="currentColor"
272
+ strokeWidth="1.5"
273
+ xmlns="http://www.w3.org/2000/svg"
274
+ viewBox="0 0 24 24"
275
+ aria-hidden
276
+ {...props}
277
+ >
278
+ <path strokeLinecap="round" strokeLinejoin="round" d="M5,5v14h14v-14z" />
279
+ </svg>
280
+ ),
281
+ text: (props: SVGProps<SVGSVGElement>) => (
282
+ <svg
283
+ stroke="currentColor"
284
+ fill="currentColor"
285
+ strokeWidth="1.5"
286
+ xmlns="http://www.w3.org/2000/svg"
287
+ viewBox="0 0 24 24"
288
+ aria-hidden
289
+ {...props}
290
+ >
291
+ <path
292
+ strokeLinecap="round"
293
+ strokeLinejoin="round"
294
+ d="M10.5 21l5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 016-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 01-3.827-5.802"
295
+ />
296
+ </svg>
297
+ ),
298
+ arc: (props: SVGProps<SVGSVGElement>) => (
299
+ <svg
300
+ stroke="none"
301
+ fill="currentColor"
302
+ strokeWidth="1.5"
303
+ xmlns="http://www.w3.org/2000/svg"
304
+ viewBox="0 0 24 24"
305
+ aria-hidden
306
+ {...props}
307
+ >
308
+ <path
309
+ strokeLinecap="round"
310
+ strokeLinejoin="round"
311
+ d="M12,21l-9,-15a12,12,0,0,1,18,0Z"
312
+ />
313
+ </svg>
314
+ ),
315
+ boxplot: (props: SVGProps<SVGSVGElement>) => (
316
+ <svg
317
+ stroke="currentColor"
318
+ fill="none"
319
+ strokeWidth="1.5"
320
+ xmlns="http://www.w3.org/2000/svg"
321
+ viewBox="0 0 24 24"
322
+ aria-hidden
323
+ {...props}
324
+ >
325
+ <path
326
+ strokeLinecap="round"
327
+ strokeLinejoin="round"
328
+ d="M7,7v9h10v-9Zm0,4h8M12,7v-6m-3,0h6M12,16v7m-3,0h6"
329
+ />
330
+ </svg>
331
+ ),
332
+ table: (props: SVGProps<SVGSVGElement>) => (
333
+ <svg
334
+ stroke="currentColor"
335
+ fill="none"
336
+ strokeWidth="1.5"
337
+ xmlns="http://www.w3.org/2000/svg"
338
+ viewBox="0 0 24 24"
339
+ aria-hidden
340
+ {...props}
341
+ >
342
+ <path
343
+ strokeLinecap="round"
344
+ strokeLinejoin="round"
345
+ d="M3.375 19.5h17.25m-17.25 0a1.125 1.125 0 01-1.125-1.125M3.375 19.5h7.5c.621 0 1.125-.504 1.125-1.125m-9.75 0V5.625m0 12.75v-1.5c0-.621.504-1.125 1.125-1.125m18.375 2.625V5.625m0 12.75c0 .621-.504 1.125-1.125 1.125m1.125-1.125v-1.5c0-.621-.504-1.125-1.125-1.125m0 3.75h-7.5A1.125 1.125 0 0112 18.375m9.75-12.75c0-.621-.504-1.125-1.125-1.125H3.375c-.621 0-1.125.504-1.125 1.125m19.5 0v1.5c0 .621-.504 1.125-1.125 1.125M2.25 5.625v1.5c0 .621.504 1.125 1.125 1.125m0 0h17.25m-17.25 0h7.5c.621 0 1.125.504 1.125 1.125M3.375 8.25c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125m17.25-3.75h-7.5c-.621 0-1.125.504-1.125 1.125m8.625-1.125c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125v1.5c0 .621.504 1.125 1.125 1.125M12 10.875v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 10.875c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125M13.125 12h7.5m-7.5 0c-.621 0-1.125.504-1.125 1.125M20.625 12c.621 0 1.125.504 1.125 1.125v1.5c0 .621-.504 1.125-1.125 1.125m-17.25 0h7.5M12 14.625v-1.5m0 1.5c0 .621-.504 1.125-1.125 1.125M12 14.625c0 .621.504 1.125 1.125 1.125m-2.25 0c.621 0 1.125.504 1.125 1.125m0 1.5v-1.5m0 0c0-.621.504-1.125 1.125-1.125m0 0h7.5"
346
+ />
347
+ </svg>
348
+ ),
165
349
  }[g],
166
350
  })),
167
351
  value: markType,
168
- onSelect: value => {
352
+ onSelect: (value) => {
169
353
  vizStore.setVisualConfig('geoms', [value]);
170
354
  },
171
355
  },
@@ -173,7 +357,7 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
173
357
  key: 'stack_mode',
174
358
  label: tGlobal('constant.stack_mode.__enum__'),
175
359
  icon: Square3Stack3DIcon,
176
- options: STACK_MODE.map(g => ({
360
+ options: STACK_MODE.map((g) => ({
177
361
  key: g,
178
362
  label: tGlobal(`constant.stack_mode.${g}`),
179
363
  icon: {
@@ -183,7 +367,7 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
183
367
  }[g],
184
368
  })),
185
369
  value: stack,
186
- onSelect: value => {
370
+ onSelect: (value) => {
187
371
  vizStore.setVisualConfig('stack', value as IStackMode);
188
372
  },
189
373
  },
@@ -212,7 +396,7 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
212
396
  label: t('toggle.axes_resize'),
213
397
  icon: ChevronUpDownIcon,
214
398
  checked: interactiveScale,
215
- onChange: checked => {
399
+ onChange: (checked) => {
216
400
  vizStore.setVisualConfig('interactiveScale', checked);
217
401
  },
218
402
  },
@@ -220,13 +404,13 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
220
404
  key: 'scale',
221
405
  icon: ArrowsPointingOutIcon,
222
406
  label: tGlobal(`constant.layout_type.__enum__`),
223
- options: CHART_LAYOUT_TYPE.map(g => ({
407
+ options: CHART_LAYOUT_TYPE.map((g) => ({
224
408
  key: g,
225
409
  label: tGlobal(`constant.layout_type.${g}`),
226
410
  icon: g === 'auto' ? LockClosedIcon : LockOpenIcon,
227
411
  })),
228
412
  value: sizeMode,
229
- onSelect: key => {
413
+ onSelect: (key) => {
230
414
  vizStore.setChartLayout({ mode: key as 'fixed' | 'auto' });
231
415
  },
232
416
  form: (
@@ -236,14 +420,14 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
236
420
  height={height}
237
421
  onHeightChange={(v) => {
238
422
  vizStore.setChartLayout({
239
- mode: "fixed",
240
- height: v
423
+ mode: 'fixed',
424
+ height: v,
241
425
  });
242
426
  }}
243
427
  onWidthChange={(v) => {
244
428
  vizStore.setChartLayout({
245
- mode: "fixed",
246
- width: v
429
+ mode: 'fixed',
430
+ width: v,
247
431
  });
248
432
  }}
249
433
  />
@@ -256,7 +440,7 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
256
440
  label: t('toggle.debug'),
257
441
  icon: WrenchIcon,
258
442
  checked: showActions,
259
- onChange: checked => {
443
+ onChange: (checked) => {
260
444
  vizStore.setVisualConfig('showActions', checked);
261
445
  },
262
446
  },
@@ -267,14 +451,22 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
267
451
  form: (
268
452
  <FormContainer className={dark ? 'dark' : ''}>
269
453
  <button
270
- className={`text-xs pt-1 pb-1 pl-6 pr-6 ${dark ? 'dark bg-zinc-900 text-gray-100 hover:bg-gray-700' : 'bg-white hover:bg-gray-200 text-gray-800'}`}
454
+ className={`text-xs pt-1 pb-1 pl-6 pr-6 ${
455
+ dark
456
+ ? 'dark bg-zinc-900 text-gray-100 hover:bg-gray-700'
457
+ : 'bg-white hover:bg-gray-200 text-gray-800'
458
+ }`}
271
459
  aria-label={t('button.export_chart_as', { type: 'png' })}
272
460
  onClick={() => downloadPNG()}
273
461
  >
274
462
  {t('button.export_chart_as', { type: 'png' })}
275
463
  </button>
276
464
  <button
277
- className={`text-xs pt-1 pb-1 pl-6 pr-6 ${dark ? 'dark bg-zinc-900 text-gray-100 hover:bg-gray-700' : 'bg-white hover:bg-gray-200 text-gray-800'}`}
465
+ className={`text-xs pt-1 pb-1 pl-6 pr-6 ${
466
+ dark
467
+ ? 'dark bg-zinc-900 text-gray-100 hover:bg-gray-700'
468
+ : 'bg-white hover:bg-gray-200 text-gray-800'
469
+ }`}
278
470
  aria-label={t('button.export_chart_as', { type: 'svg' })}
279
471
  onClick={() => downloadSVG()}
280
472
  >
@@ -289,7 +481,7 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
289
481
  icon: Cog6ToothIcon,
290
482
  onClick: () => {
291
483
  commonStore.setShowVisualConfigPanel(true);
292
- }
484
+ },
293
485
  },
294
486
  {
295
487
  key: 'export_code',
@@ -297,45 +489,79 @@ const VisualSettings: React.FC<IVisualSettings> = ({ rendererHandler, darkModePr
297
489
  icon: CodeBracketSquareIcon,
298
490
  onClick: () => {
299
491
  commonStore.setShowCodeExportPanel(true);
300
- }
492
+ },
493
+ },
494
+ '-',
495
+ {
496
+ key: 'kanaries',
497
+ label: 'kanaries',
498
+ icon: () => (
499
+ // Kanaries brand info is not allowed to be removed or changed unless you are granted with special permission.
500
+ <a href="https://docs.kanaries.net" target="_blank">
501
+ <ImageWithFallback
502
+ id="kanaries-logo"
503
+ className="p-1.5 opacity-70 hover:opacity-100"
504
+ src="https://imagedelivery.net/tSvh1MGEu9IgUanmf58srQ/b6bc899f-a129-4c3a-d08f-d406166d0c00/public"
505
+ fallbackSrc={KanariesLogo}
506
+ timeout={1000}
507
+ alt="kanaries"
508
+ />
509
+ </a>
510
+ ),
301
511
  },
302
512
  ] as ToolbarItemProps[];
303
513
 
304
- const items = builtInItems.filter(item => typeof item === 'string' || !exclude.includes(item.key));
514
+ const items = builtInItems.filter((item) => typeof item === 'string' || !exclude.includes(item.key));
305
515
 
306
516
  if (extra.length > 0) {
307
- items.push(
308
- '-',
309
- ...extra,
310
- );
517
+ items.push('-', ...extra);
311
518
  }
312
519
 
313
520
  return items;
314
- }, [vizStore, canUndo, canRedo, defaultAggregated, markType, stack, interactiveScale, sizeMode, width, height, showActions, downloadPNG, downloadSVG, dark, extra, exclude]);
521
+ }, [
522
+ vizStore,
523
+ canUndo,
524
+ canRedo,
525
+ defaultAggregated,
526
+ markType,
527
+ stack,
528
+ interactiveScale,
529
+ sizeMode,
530
+ width,
531
+ height,
532
+ showActions,
533
+ downloadPNG,
534
+ downloadSVG,
535
+ dark,
536
+ extra,
537
+ exclude,
538
+ ]);
315
539
 
316
- return <div style={{ margin: '0.38em 0.28em 0.2em 0.18em' }}>
317
- <Toolbar
318
- darkModePreference={darkModePreference}
319
- items={items}
320
- styles={{
321
- root: {
322
- '--background-color': '#fff',
323
- '--dark-background-color': '#000',
324
- '--color': '#777',
325
- '--color-hover': '#555',
326
- '--dark-color': '#999',
327
- '--dark-color-hover': '#bbb',
328
- '--blue': 'rgb(79,70,229)',
329
- '--blue-dark': 'rgb(9, 6, 65)',
330
- },
331
- container: {
332
- // border: '1px solid #e5e7eb',
333
- // boxSizing: 'content-box',
334
- // borderRadius: '1px',
335
- },
336
- }}
337
- />
338
- </div>
339
- }
540
+ return (
541
+ <div style={{ margin: '0.38em 0.28em 0.2em 0.18em' }}>
542
+ <Toolbar
543
+ darkModePreference={darkModePreference}
544
+ items={items}
545
+ styles={{
546
+ root: {
547
+ '--background-color': '#fff',
548
+ '--dark-background-color': '#000',
549
+ '--color': '#777',
550
+ '--color-hover': '#555',
551
+ '--dark-color': '#999',
552
+ '--dark-color-hover': '#bbb',
553
+ '--blue': 'rgb(79,70,229)',
554
+ '--blue-dark': 'rgb(9, 6, 65)',
555
+ },
556
+ container: {
557
+ // border: '1px solid #e5e7eb',
558
+ // boxSizing: 'content-box',
559
+ // borderRadius: '1px',
560
+ },
561
+ }}
562
+ />
563
+ </div>
564
+ );
565
+ };
340
566
 
341
- export default observer(VisualSettings);
567
+ export default observer(VisualSettings);
@@ -1 +0,0 @@
1
- {"version":3,"file":"transform.worker-90e4f506.js","sources":["../src/lib/execExp.ts","../src/workers/transform.ts","../src/workers/transform.worker.js"],"sourcesContent":["import { IExpParamter, IExpression, IField, IRow } from \"../interfaces\";\n\ninterface IDataFrame {\n [key: string]: any[];\n}\n\nexport function execExpression (exp: IExpression, dataFrame: IDataFrame, columns: IField[]): IDataFrame {\n const { op, params } = exp;\n const subFrame: IDataFrame = { ...dataFrame };\n const len = dataFrame[Object.keys(dataFrame)[0]].length;\n for (let param of params) {\n switch (param.type) {\n case 'field':\n subFrame[param.value] = dataFrame[param.value];\n break;\n case 'constant':\n subFrame[param.value] = new Array(len).fill(param.value);\n break;\n case 'expression':\n let f = execExpression(param.value, dataFrame, columns);\n Object.keys(f).forEach(key => {\n subFrame[key] = f[key];\n })\n break;\n case 'value':\n default:\n break;\n }\n }\n switch (op) {\n case 'one':\n return one(exp.as, params, subFrame);\n case 'bin':\n return bin(exp.as, params, subFrame);\n case 'log2':\n return log2(exp.as, params, subFrame);\n case 'log10':\n return log10(exp.as, params, subFrame);\n case 'binCount':\n return binCount(exp.as, params, subFrame);\n default:\n return subFrame;\n }\n}\n\nfunction bin(resKey: string, params: IExpParamter[], data: IDataFrame, binSize: number | undefined = 10): IDataFrame {\n const { value: fieldKey } = params[0];\n const fieldValues = data[fieldKey] as number[];\n let _min = Infinity;\n let _max = -Infinity;\n for (let i = 0; i < fieldValues.length; i++) {\n let val = fieldValues[i];\n if (val > _max) _max = val;\n if (val < _min) _min = val;\n }\n const step = (_max - _min) / binSize;\n const beaStep = Math.max(-Math.round(Math.log10(_max - _min)) + 2, 0)\n const newValues = fieldValues.map((v: number) => {\n let bIndex = Math.floor((v - _min) / step);\n if (bIndex === binSize) bIndex = binSize - 1;\n return Number(((bIndex * step + _min)).toFixed(beaStep))\n });\n return {\n ...data,\n [resKey]: newValues,\n }\n}\n\nfunction binCount(resKey: string, params: IExpParamter[], data: IDataFrame, binSize: number | undefined = 10): IDataFrame {\n const { value: fieldKey } = params[0];\n const fieldValues = data[fieldKey] as number[];\n\n const valueWithIndices: {val: number; index: number; orderIndex: number }[] = fieldValues.map((v, i) => ({\n val: v,\n index: i\n })).sort((a, b) => a.val - b.val)\n .map((item, i) => ({\n val: item.val,\n index: item.index,\n orderIndex: i\n }))\n\n const groupSize = valueWithIndices.length / binSize;\n\n const newValues = valueWithIndices.map(item => {\n let bIndex = Math.floor(item.orderIndex / groupSize);\n if (bIndex === binSize) bIndex = binSize - 1;\n return bIndex + 1\n })\n return {\n ...data,\n [resKey]: newValues,\n }\n}\n\nfunction log2(resKey: string, params: IExpParamter[], data: IDataFrame): IDataFrame {\n const { value } = params[0];\n const field = data[value];\n const newField = field.map((v: number) => Math.log2(v));\n return {\n ...data,\n [resKey]: newField,\n }\n}\n\nfunction log10(resKey: string, params: IExpParamter[], data: IDataFrame): IDataFrame {\n const { value: fieldKey } = params[0];\n const fieldValues = data[fieldKey];\n const newField = fieldValues.map((v: number) => Math.log10(v));\n return {\n ...data,\n [resKey]: newField,\n }\n}\n\nfunction one(resKey: string, params: IExpParamter[], data: IDataFrame): IDataFrame {\n // const { value: fieldKey } = params[0];\n if (Object.keys(data).length === 0) return data;\n const len = data[Object.keys(data)[0]].length;\n const newField = new Array(len).fill(1);\n return {\n ...data,\n [resKey]: newField,\n }\n}\n\nexport function dataset2DataFrame(dataset: IRow[], columns: IField[]): IDataFrame {\n const dataFrame: IDataFrame = {};\n columns.forEach((col) => {\n dataFrame[col.fid] = dataset.map((row) => row[col.fid]);\n });\n return dataFrame;\n}\n\nexport function dataframe2Dataset(dataFrame: IDataFrame, columns: IField[]): IRow[] {\n if (columns.length === 0) return [];\n const dataset: IRow[] = [];\n const len = dataFrame[Object.keys(dataFrame)[0]].length;\n for (let i = 0; i < len; i++) {\n const row: IRow = {};\n columns.forEach((col) => {\n row[col.fid] = dataFrame[col.fid][i];\n });\n dataset.push(row);\n }\n return dataset;\n}\n","import { IField, IRow } from \"../interfaces\";\nimport { dataframe2Dataset, dataset2DataFrame, execExpression } from \"../lib/execExp\";\n\nexport function transformData(data: IRow[], columns: IField[]) {\n const computedFields = columns.filter((f) => f.computed);\n let df = dataset2DataFrame(data, columns);\n for (let i = 0; i < computedFields.length; i++) {\n const field = computedFields[i];\n df = execExpression(field.expression!, df, columns);\n }\n return dataframe2Dataset(df, columns);\n}\n","import { transformData } from './transform'\nconst main = e => {\n const { dataSource, columns } = e.data;\n\n try {\n const ans = transformData(dataSource, columns);\n self.postMessage(ans);\n } catch (error) {\n self.postMessage({ error: error.message });\n }\n};\n\nself.addEventListener('message', main, false);"],"names":["execExpression","exp","dataFrame","columns","op","params","subFrame","len","param","f","key","one","bin","log2","log10","binCount","resKey","data","binSize","fieldKey","fieldValues","_min","_max","i","val","step","beaStep","newValues","v","bIndex","valueWithIndices","a","b","item","groupSize","value","newField","dataset2DataFrame","dataset","col","row","dataframe2Dataset","transformData","computedFields","df","field","main","e","dataSource","ans","error"],"mappings":"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"}