layerchart 2.0.0-next.34 → 2.0.0-next.35

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.
@@ -1,9 +1,10 @@
1
1
  <script lang="ts" module>
2
- import { scaleLinear, scaleOrdinal, scaleSqrt } from 'd3-scale';
2
+ import { scaleOrdinal, scaleSqrt } from 'd3-scale';
3
3
  import { type Accessor, accessor, chartDataArray } from '../utils/common.js';
4
4
  import { printDebug } from '../utils/debug.js';
5
5
  import { filterObject } from '../utils/filterObject.js';
6
6
  import {
7
+ autoScale,
7
8
  createScale,
8
9
  getRange,
9
10
  isScaleBand,
@@ -421,21 +422,21 @@
421
422
  /**
422
423
  * The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
423
424
  * you want to override the default or you want to extra options.
424
- * @default scaleLinear
425
+ * @default autoScale
425
426
  */
426
427
  xScale?: XScale;
427
428
 
428
429
  /**
429
430
  * The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
430
431
  * you want to override the default or you want to extra options.
431
- * @default scaleLinear
432
+ * @default autoScale
432
433
  */
433
434
  yScale?: YScale;
434
435
 
435
436
  /**
436
437
  * The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
437
438
  * you want to override the default or you want to extra options.
438
- * @default scaleLinear
439
+ * @default autoScale
439
440
  */
440
441
  zScale?: AnyScale;
441
442
 
@@ -449,14 +450,14 @@
449
450
  /**
450
451
  * The D3 scale that should be used for the x1-dimension. Pass in an instantiated D3 scale if
451
452
  * you want to override the default or you want to extra options.
452
- * @default scaleLinear
453
+ * @default autoScale
453
454
  */
454
455
  x1Scale?: AnyScale;
455
456
 
456
457
  /**
457
458
  * The D3 scale that should be used for the y1-dimension. Pass in an instantiated D3 scale if
458
459
  * you want to override the default or you want to extra options.
459
- * @default scaleLinear
460
+ * @default autoScale
460
461
  */
461
462
  y1Scale?: AnyScale;
462
463
 
@@ -717,6 +718,7 @@
717
718
  z: zProp,
718
719
  r: rProp,
719
720
  data = [],
721
+ flatData: flatDataProp,
720
722
  xDomain: xDomainProp,
721
723
  yDomain: yDomainProp,
722
724
  zDomain: zDomainProp,
@@ -730,12 +732,12 @@
730
732
  zPadding,
731
733
  rPadding,
732
734
  // @ts-expect-error shh
733
- xScale: xScaleProp = scaleLinear(),
735
+ xScale: xScaleProp = autoScale(xDomainProp, flatDataProp ?? data, xProp),
736
+ // @ts-expect-error shh
737
+ yScale: yScaleProp = autoScale(yDomainProp, flatDataProp ?? data, yProp),
734
738
  // @ts-expect-error shh
735
- yScale: yScaleProp = scaleLinear(),
736
- zScale: zScaleProp = scaleLinear(),
739
+ zScale: zScaleProp = autoScale(zDomainProp, flatDataProp ?? data, zProp),
737
740
  rScale: rScaleProp = scaleSqrt(),
738
- flatData: flatDataProp,
739
741
  padding: paddingProp = {},
740
742
  verbose = true,
741
743
  debug = false,
@@ -1009,24 +1011,36 @@
1009
1011
  const rGet = $derived(createGetter(r, rScale));
1010
1012
 
1011
1013
  const x1Scale = $derived(
1012
- x1ScaleProp && x1RangeProp
1013
- ? createScale(x1ScaleProp, x1Domain, x1RangeProp, {
1014
- xScale: xScale,
1015
- width,
1016
- height,
1017
- })
1014
+ x1RangeProp
1015
+ ? createScale(
1016
+ // @ts-expect-error shh
1017
+ x1ScaleProp ?? autoScale(x1DomainProp, flatDataProp ?? data, x1Prop),
1018
+ x1Domain,
1019
+ x1RangeProp,
1020
+ {
1021
+ xScale,
1022
+ width,
1023
+ height,
1024
+ }
1025
+ )
1018
1026
  : null
1019
1027
  );
1020
1028
 
1021
1029
  const x1Get = $derived(createGetter(x1, x1Scale));
1022
1030
 
1023
1031
  const y1Scale = $derived(
1024
- y1ScaleProp && y1RangeProp
1025
- ? createScale(y1ScaleProp, y1Domain, y1RangeProp, {
1026
- yScale: yScale,
1027
- width,
1028
- height,
1029
- })
1032
+ y1RangeProp
1033
+ ? createScale(
1034
+ // @ts-expect-error shh
1035
+ y1ScaleProp ?? autoScale(y1DomainProp, flatDataProp ?? data, y1Prop),
1036
+ y1Domain,
1037
+ y1RangeProp,
1038
+ {
1039
+ yScale,
1040
+ width,
1041
+ height,
1042
+ }
1043
+ )
1030
1044
  : null
1031
1045
  );
1032
1046
 
@@ -288,19 +288,19 @@ export type ChartPropsWithoutHTML<T, XScale extends AnyScale = AnyScale, YScale
288
288
  /**
289
289
  * The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
290
290
  * you want to override the default or you want to extra options.
291
- * @default scaleLinear
291
+ * @default autoScale
292
292
  */
293
293
  xScale?: XScale;
294
294
  /**
295
295
  * The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
296
296
  * you want to override the default or you want to extra options.
297
- * @default scaleLinear
297
+ * @default autoScale
298
298
  */
299
299
  yScale?: YScale;
300
300
  /**
301
301
  * The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
302
302
  * you want to override the default or you want to extra options.
303
- * @default scaleLinear
303
+ * @default autoScale
304
304
  */
305
305
  zScale?: AnyScale;
306
306
  /**
@@ -312,13 +312,13 @@ export type ChartPropsWithoutHTML<T, XScale extends AnyScale = AnyScale, YScale
312
312
  /**
313
313
  * The D3 scale that should be used for the x1-dimension. Pass in an instantiated D3 scale if
314
314
  * you want to override the default or you want to extra options.
315
- * @default scaleLinear
315
+ * @default autoScale
316
316
  */
317
317
  x1Scale?: AnyScale;
318
318
  /**
319
319
  * The D3 scale that should be used for the y1-dimension. Pass in an instantiated D3 scale if
320
320
  * you want to override the default or you want to extra options.
321
- * @default scaleLinear
321
+ * @default autoScale
322
322
  */
323
323
  y1Scale?: AnyScale;
324
324
  /**
@@ -122,7 +122,6 @@
122
122
  renderContext = 'svg',
123
123
  profile = false,
124
124
  debug = false,
125
- xScale: xScaleProp,
126
125
  children: childrenProp,
127
126
  aboveContext,
128
127
  belowContext,
@@ -196,11 +195,6 @@
196
195
  return _chartData;
197
196
  });
198
197
 
199
- // Default xScale based on first data's `x` value
200
- const xScale = $derived(
201
- xScaleProp ?? (accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinear())
202
- );
203
-
204
198
  function isStackData(d: TData): d is TData & { stackData: any[] } {
205
199
  return d && typeof d === 'object' && 'stackData' in d;
206
200
  }
@@ -433,7 +427,6 @@
433
427
  data={chartData}
434
428
  {x}
435
429
  {xDomain}
436
- {xScale}
437
430
  y={resolveAccessor(y)}
438
431
  yBaseline={0}
439
432
  yNice
@@ -69,7 +69,6 @@
69
69
 
70
70
  <script lang="ts" generics="TData">
71
71
  import { onMount, type ComponentProps } from 'svelte';
72
- import { scaleLinear, scaleTime } from 'd3-scale';
73
72
  import { cls } from '@layerstack/tailwind';
74
73
 
75
74
  import Axis from '../Axis.svelte';
@@ -124,7 +123,6 @@
124
123
  renderContext = 'svg',
125
124
  profile = false,
126
125
  debug = false,
127
- xScale: xScaleProp,
128
126
  tooltip = true,
129
127
  children: childrenProp,
130
128
  aboveContext,
@@ -159,11 +157,6 @@
159
157
  : chartDataArray(data)) as Array<TData>
160
158
  );
161
159
 
162
- // Default xScale based on first data's `x` value
163
- const xScale = $derived(
164
- xScaleProp ?? (accessor(xProp)(chartData[0]) instanceof Date ? scaleTime() : scaleLinear())
165
- );
166
-
167
160
  function getSplineProps(s: SeriesData<TData, typeof Spline>, i: number) {
168
161
  const splineProps: ComponentProps<typeof Spline> = {
169
162
  data: s.data,
@@ -333,7 +326,6 @@
333
326
  data={chartData}
334
327
  x={xProp}
335
328
  {xDomain}
336
- {xScale}
337
329
  y={yProp ?? series.map((s) => s.value ?? s.key)}
338
330
  yBaseline={0}
339
331
  yNice
@@ -44,7 +44,6 @@
44
44
  </script>
45
45
 
46
46
  <script lang="ts" generics="TData">
47
- import { scaleLinear, scaleTime } from 'd3-scale';
48
47
  import { format } from '@layerstack/utils';
49
48
  import { cls } from '@layerstack/tailwind';
50
49
 
@@ -88,8 +87,6 @@
88
87
  renderContext = 'svg',
89
88
  profile = false,
90
89
  debug = false,
91
- xScale: xScaleProp,
92
- yScale: yScaleProp,
93
90
  children: childrenProp,
94
91
  aboveContext,
95
92
  belowContext,
@@ -107,18 +104,6 @@
107
104
 
108
105
  const seriesState = new SeriesState(() => series);
109
106
 
110
- // Default xScale based on first data's `x` value
111
- const xScale = $derived(
112
- xScaleProp ??
113
- (accessor(xProp)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear())
114
- );
115
-
116
- // Default yScale based on first data's `y` value
117
- const yScale = $derived(
118
- yScaleProp ??
119
- (accessor(yProp)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear())
120
- );
121
-
122
107
  const chartData = $derived(
123
108
  seriesState.visibleSeries
124
109
  .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d })))
@@ -241,10 +226,8 @@
241
226
  data={chartData}
242
227
  x={xProp}
243
228
  {xDomain}
244
- {xScale}
245
229
  y={yProp}
246
230
  {yDomain}
247
- {yScale}
248
231
  yNice
249
232
  c={yProp}
250
233
  cRange={['var(--color-primary)']}
@@ -1,6 +1,6 @@
1
1
  import { type ScaleBand, type ScaleTime } from 'd3-scale';
2
2
  import { type MotionProp, type MotionOptions, type SpringOptions, type TweenOptions } from './motion.svelte.js';
3
- import type { Accessor } from './common.js';
3
+ import { type Accessor } from './common.js';
4
4
  import type { OnlyObjects } from './types.js';
5
5
  export type AnyScale<TInput extends SingleDomainType = any, TOutput extends SingleDomainType = any, TScaleArgs extends any[] | readonly any[] = any[]> = {
6
6
  (value: TInput): TOutput;
@@ -55,6 +55,10 @@ export declare function scaleBandInvert(scale: ScaleBand<any>): (value: number)
55
55
  export declare function scaleInvert(scale: AnyScale<any, any>, value: number): any;
56
56
  /** Create new copy of scale with domain and range */
57
57
  export declare function createScale(scale: AnyScale, domain: DomainType, range: any[] | readonly any[] | Function, context?: Record<any, any>): AnyScale<any, any, any[]>;
58
+ /**
59
+ * Auto-detect scale type based on domain values or data values
60
+ */
61
+ export declare function autoScale(domain?: DomainType, data?: any[], propAccessor?: Accessor<any>): AnyScale;
58
62
  /**
59
63
  * Create a `scaleBand()` within another scaleBand()'s bandwidth
60
64
  * (typically a x1 of an x0 scale, used for grouping)
@@ -1,7 +1,8 @@
1
1
  import { unique } from '@layerstack/utils';
2
- import { scaleBand } from 'd3-scale';
2
+ import { scaleBand, scaleLinear, scaleTime } from 'd3-scale';
3
3
  import { createControlledMotion, } from './motion.svelte.js';
4
4
  import { Spring, Tween } from 'svelte/motion';
5
+ import { accessor } from './common.js';
5
6
  function isAnyScale(scale) {
6
7
  return typeof scale === 'function' && typeof scale.range === 'function';
7
8
  }
@@ -91,6 +92,40 @@ export function createScale(scale, domain, range, context) {
91
92
  }
92
93
  return scaleCopy;
93
94
  }
95
+ /**
96
+ * Auto-detect scale type based on domain values or data values
97
+ */
98
+ export function autoScale(domain, data, propAccessor) {
99
+ let values = null;
100
+ if (domain && domain.length > 0) {
101
+ // Determine based on domain values
102
+ values = domain;
103
+ }
104
+ else if (data && data.length > 0 && propAccessor) {
105
+ // Determine based on data values
106
+ const value = accessor(propAccessor)(data[0]);
107
+ // If accessor defined with an array (ex. `x={['start', 'end']}`) use both values
108
+ if (Array.isArray(value)) {
109
+ values = value;
110
+ }
111
+ else {
112
+ values = [value];
113
+ }
114
+ }
115
+ if (values) {
116
+ if (values.some((v) => v instanceof Date)) {
117
+ return scaleTime();
118
+ }
119
+ else if (values.some((v) => typeof v === 'number')) {
120
+ return scaleLinear();
121
+ }
122
+ else if (values.some((v) => typeof v === 'string')) {
123
+ return scaleBand();
124
+ }
125
+ }
126
+ // fallback to linear scale
127
+ return scaleLinear();
128
+ }
94
129
  /**
95
130
  * Create a `scaleBand()` within another scaleBand()'s bandwidth
96
131
  * (typically a x1 of an x0 scale, used for grouping)
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "author": "Sean Lynch <techniq35@gmail.com>",
5
5
  "license": "MIT",
6
6
  "repository": "techniq/layerchart",
7
- "version": "2.0.0-next.34",
7
+ "version": "2.0.0-next.35",
8
8
  "devDependencies": {
9
9
  "@changesets/cli": "^2.29.4",
10
10
  "@iconify-json/lucide": "^1.2.48",
@@ -55,7 +55,7 @@
55
55
  "svelte": "5.34.1",
56
56
  "svelte-check": "^4.2.1",
57
57
  "svelte-json-tree": "^2.2.0",
58
- "svelte-ux": "2.0.0-next.14",
58
+ "svelte-ux": "2.0.0-next.17",
59
59
  "svelte2tsx": "^0.7.39",
60
60
  "tailwindcss": "^4.1.10",
61
61
  "topojson-client": "^3.1.0",