svelteplot 0.1.3-next.7 → 0.1.3-next.8

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/dist/Mark.svelte CHANGED
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { getContext, untrack, type Snippet } from 'svelte';
3
3
 
4
- import { CHANNEL_SCALE } from './constants.js';
4
+ import { CHANNEL_SCALE, INDEX } from './constants.js';
5
5
  import type {
6
6
  ScaledChannelName,
7
7
  MarkType,
@@ -78,6 +78,8 @@
78
78
  }
79
79
  }
80
80
 
81
+
82
+
81
83
  const mark = new Mark(type);
82
84
 
83
85
  $effect(() => {
@@ -126,7 +128,7 @@
126
128
  const testFacet = $derived(getTestFacet());
127
129
 
128
130
  const resolvedData: ResolvedDataRecord[] = $derived(
129
- data.flatMap((row) => {
131
+ data.map((d,i) => ({...d, [INDEX]: i})).flatMap((row) => {
130
132
  const channels = options as Record<ChannelName, ChannelAccessor>;
131
133
  if (!testFacet(row, channels) || !testFilter(row, channels)) return [];
132
134
  const out: ResolvedDataRecord = {
@@ -12,3 +12,4 @@ export declare const CSS_COLOR_MIX: RegExp;
12
12
  export declare const CSS_COLOR_CONTRAST: RegExp;
13
13
  export declare const CSS_RGBA: RegExp;
14
14
  export declare const CSS_URL: RegExp;
15
+ export declare const INDEX: unique symbol;
package/dist/constants.js CHANGED
@@ -94,6 +94,7 @@ export const CSS_COLOR_MIX = /^color-mix\(/; // just check for prefix
94
94
  export const CSS_COLOR_CONTRAST = /^color-contrast\(/; // just check for prefix
95
95
  export const CSS_RGBA = /^rgba\(/; // just check for prefix
96
96
  export const CSS_URL = /^url\(#/; // just check for prefix
97
+ export const INDEX = Symbol('index');
97
98
  // export const CHANNEL_MAP: Record<ScaleName, ValueOf<typeof SCALE_TYPES>> = {
98
99
  // x: SCALE_TYPES.x,
99
100
  // y: SCALE_TYPES.y,
@@ -108,8 +108,6 @@
108
108
  inset?: number;
109
109
  };
110
110
 
111
- let scaleCounter = $state(0);
112
-
113
111
  /**
114
112
  * the marks used in the plot
115
113
  */
@@ -158,7 +156,7 @@
158
156
  explicitDomains,
159
157
  hasProjection: !!initialOpts.projection,
160
158
  margins: initialOpts.margins,
161
- inset: initialOpts.inset
159
+ inset: initialOpts.inset,
162
160
  })
163
161
  );
164
162
 
@@ -1,5 +1,6 @@
1
1
  import { resolveProp } from './resolve.js';
2
2
  import { isDate } from './typeChecks';
3
+ import { RAW_VALUE } from '../transforms/recordize.js';
3
4
  /**
4
5
  * Returns first argument that is not null or undefined
5
6
  */
@@ -12,7 +13,8 @@ export function coalesce(...args) {
12
13
  return null; // Return null if all arguments are null or undefined
13
14
  }
14
15
  export function testFilter(datum, options) {
15
- return options.filter == null || resolveProp(options.filter, datum);
16
+ return (options.filter == null ||
17
+ resolveProp(options.filter, datum?.hasOwnProperty(RAW_VALUE) ? datum[RAW_VALUE] : datum));
16
18
  }
17
19
  export function randomId() {
18
20
  return Math.ceil(1e9 + Math.random() * 1e9).toString(36);
@@ -147,7 +147,7 @@ export function createScale(name, scaleOptions, marks, plotOptions, plotWidth, p
147
147
  valueArr.sort(ascending);
148
148
  }
149
149
  const domain = scaleOptions.domain
150
- ? scaleOptions.domain
150
+ ? extent(scaleOptions.zero ? [0, ...scaleOptions.domain] : scaleOptions.domain)
151
151
  : type === 'band' ||
152
152
  type === 'point' ||
153
153
  type === 'ordinal' ||
@@ -46,6 +46,8 @@
46
46
  stack
47
47
  )
48
48
  );
49
+
50
+ $inspect({args})
49
51
  </script>
50
52
 
51
53
  <Mark
@@ -71,7 +73,7 @@
71
73
  transform="translate({[minx + dx, d.y + inset + dy - bw * 0.5]})"
72
74
  use:addEventHandlers={{
73
75
  getPlotState,
74
- options: mark.options,
76
+ options: args,
75
77
  datum: d.datum
76
78
  }} />
77
79
  {/if}
@@ -85,7 +85,7 @@
85
85
  transform="translate({[d.x + inset + dx - bw * 0.5, miny + dy]})"
86
86
  use:addEventHandlers={{
87
87
  getPlotState,
88
- options: mark.options,
88
+ options: args,
89
89
  datum: d.datum
90
90
  }} />
91
91
  {/if}
@@ -93,7 +93,7 @@
93
93
  ]})"
94
94
  use:addEventHandlers={{
95
95
  getPlotState,
96
- options: mark.options,
96
+ options: args,
97
97
  datum: d.datum
98
98
  }} />
99
99
  {/if}
@@ -123,7 +123,7 @@
123
123
  {style}
124
124
  use:addEventHandlers={{
125
125
  getPlotState,
126
- options: mark.options,
126
+ options: args,
127
127
  datum: d.datum
128
128
  }} />
129
129
  {/if}
@@ -79,7 +79,7 @@
79
79
  )}
80
80
  use:addEventHandlers={{
81
81
  getPlotState,
82
- options: mark.options,
82
+ options: args,
83
83
  datum
84
84
  }}>
85
85
  {#if title}<title>{title}</title>{/if}
@@ -156,7 +156,7 @@
156
156
  )}
157
157
 
158
158
  <MarkerPath
159
- {mark}
159
+ mark={{...mark, options: args}}
160
160
  scales={plot.scales}
161
161
  markerStart={args.markerStart}
162
162
  markerEnd={args.markerEnd}
@@ -48,6 +48,7 @@
48
48
  import Mark from '../Mark.svelte';
49
49
  //import DotCanvas from './helpers/DotCanvas.svelte';
50
50
  import { maybeData, testFilter, isValid } from '../helpers/index.js';
51
+ import { addEventHandlers } from './helpers/events.js';
51
52
 
52
53
  const defaultRadius = 3.5;
53
54
 
@@ -198,6 +199,11 @@
198
199
  ? `translate(0, ${d.length})`
199
200
  : `translate(0, ${d.length / 2})`}"
200
201
  {style}
202
+ use:addEventHandlers={{
203
+ getPlotState,
204
+ options: args,
205
+ datum: d.datum
206
+ }}
201
207
  class={[styleClass]} />
202
208
  {/if}
203
209
  {/each}
@@ -1,4 +1,6 @@
1
- import { pick } from 'es-toolkit';
1
+ import { invert, pick } from 'es-toolkit';
2
+ import { RAW_VALUE } from '../../transforms/recordize.js';
3
+ import { INDEX } from '../../constants.js';
2
4
  export function addEventHandlers(node, { options, datum, getPlotState }) {
3
5
  const events = pick(options, [
4
6
  'onclick',
@@ -38,13 +40,11 @@ export function addEventHandlers(node, { options, datum, getPlotState }) {
38
40
  origEvent.dataY = y;
39
41
  }
40
42
  else {
41
- origEvent.dataX =
42
- scales.x.fn.invert && scales.x.fn.invert(origEvent.layerX);
43
- origEvent.dataY =
44
- scales.y.fn.invert && scales.y.fn.invert(origEvent.layerY);
43
+ origEvent.dataX = invertScale(scales.x, origEvent.layerX);
44
+ origEvent.dataY = invertScale(scales.y, origEvent.layerY);
45
45
  }
46
46
  }
47
- eventHandler(origEvent, datum.___orig___ !== undefined ? datum.___orig___ : datum);
47
+ eventHandler(origEvent, datum.hasOwnProperty(RAW_VALUE) ? datum[RAW_VALUE] : datum, datum[INDEX]);
48
48
  };
49
49
  listeners.set(eventName, wrappedHandler);
50
50
  node.addEventListener(eventName.substring(2), wrappedHandler);
@@ -62,3 +62,13 @@ export function addEventHandlers(node, { options, datum, getPlotState }) {
62
62
  }
63
63
  };
64
64
  }
65
+ function invertScale(scale, position) {
66
+ if (scale.type === 'band') {
67
+ // invert band scale since scaleBand doesn't have an invert function
68
+ const eachBand = scale.fn.step();
69
+ console.log({ eachBand, position });
70
+ const index = Math.floor(position / eachBand);
71
+ return scale.fn.domain()[index];
72
+ }
73
+ return scale.fn.invert ? scale.fn.invert(position) : undefined;
74
+ }
@@ -1,4 +1,5 @@
1
1
  import type { TransformArgsRow, TransformArgsRecord } from '../types.js';
2
+ export declare const RAW_VALUE: unique symbol;
2
3
  export declare function recordizeX({ data, ...channels }: TransformArgsRow, { withIndex }?: {
3
4
  withIndex: boolean;
4
5
  }): TransformArgsRecord;
@@ -1,4 +1,5 @@
1
1
  import isDataRecord from '../helpers/isDataRecord.js';
2
+ export const RAW_VALUE = Symbol();
2
3
  /*
3
4
  * This transform takes an array of raw values as input and returns data records
4
5
  * in which the values are interpreted as x channel and their index as y
@@ -10,6 +11,8 @@ export function recordizeX({ data, ...channels }, { withIndex } = { withIndex: t
10
11
  data: data.map((value, index) => ({
11
12
  __value: value,
12
13
  ...(withIndex ? { __index: index } : {}),
14
+ [RAW_VALUE]: value,
15
+ // TODO: remove ___orig___ references
13
16
  ___orig___: value
14
17
  })),
15
18
  ...channels,
@@ -32,6 +35,7 @@ export function recordizeY({ data, ...channels }, { withIndex } = { withIndex: t
32
35
  data: Array.from(data).map((value, index) => ({
33
36
  __value: value,
34
37
  ...(withIndex ? { __index: index } : {}),
38
+ [RAW_VALUE]: value,
35
39
  ___orig___: value
36
40
  })),
37
41
  ...channels,
@@ -1,10 +1,10 @@
1
1
  import type { DataRecord, DataRow, TransformArg } from '../types.js';
2
+ export declare const SORT_KEY: unique symbol;
2
3
  export declare function sort({ data, ...channels }: TransformArg<DataRecord>, options?: {
3
4
  reverse?: boolean;
4
5
  }): {
5
6
  sort: null;
6
7
  data: {
7
- __sortkey: import("../types.js").RawValue;
8
8
  ___orig___?: import("../types.js").RawValue | [import("../types.js").RawValue, import("../types.js").RawValue];
9
9
  }[];
10
10
  } | {
@@ -2,6 +2,7 @@ import isDataRecord from '../helpers/isDataRecord.js';
2
2
  import { resolveChannel } from '../helpers/resolve.js';
3
3
  import { shuffler } from 'd3-array';
4
4
  import { randomLcg } from 'd3-random';
5
+ export const SORT_KEY = Symbol('sortKey');
5
6
  export function sort({ data, ...channels }, options = {}) {
6
7
  if (!Array.isArray(data))
7
8
  return { data, ...channels };
@@ -16,11 +17,15 @@ export function sort({ data, ...channels }, options = {}) {
16
17
  // sort data
17
18
  return {
18
19
  data: data
19
- .map((d) => ({ ...d, __sortkey: resolveChannel('sort', d, { ...channels, sort }) }))
20
- .toSorted((a, b) => (a.__sortkey > b.__sortkey ? 1 : a.__sortkey < b.__sortkey ? -1 : 0) *
20
+ .map((d) => ({
21
+ ...d,
22
+ [SORT_KEY]: resolveChannel('sort', d, { ...channels, sort })
23
+ }))
24
+ .toSorted((a, b) => (a[SORT_KEY] > b[SORT_KEY] ? 1 : a[SORT_KEY] < b[SORT_KEY] ? -1 : 0) *
21
25
  (options.reverse || (isDataRecord(sort) && sort?.order === 'descending')
22
26
  ? -1
23
- : 1)),
27
+ : 1))
28
+ .map(({ [SORT_KEY]: a, ...rest }) => rest),
24
29
  ...channels,
25
30
  // set the sort channel to null to disable the implicit alphabetical
26
31
  // ordering of ordinal domains, and also to avoid double sorting in case
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteplot",
3
- "version": "0.1.3-next.7",
3
+ "version": "0.1.3-next.8",
4
4
  "license": "ISC",
5
5
  "author": {
6
6
  "name": "Gregor Aisch",
@@ -67,12 +67,12 @@
67
67
  "@types/d3-scale": "^4.0.9",
68
68
  "@types/d3-scale-chromatic": "^3.1.0",
69
69
  "@types/d3-shape": "^3.1.7",
70
- "@typescript-eslint/eslint-plugin": "^8.30.1",
71
- "@typescript-eslint/parser": "^8.30.1",
70
+ "@typescript-eslint/eslint-plugin": "^8.31.1",
71
+ "@typescript-eslint/parser": "^8.31.1",
72
72
  "d3-dsv": "^3.0.1",
73
73
  "d3-fetch": "^3.0.1",
74
74
  "d3-force": "^3.0.0",
75
- "eslint": "^9.25.0",
75
+ "eslint": "^9.25.1",
76
76
  "eslint-config-prettier": "^10.1.2",
77
77
  "eslint-plugin-svelte": "3.5.1",
78
78
  "jsdom": "^26.1.0",
@@ -81,17 +81,17 @@
81
81
  "remark-code-extra": "^1.0.1",
82
82
  "remark-code-frontmatter": "^1.0.0",
83
83
  "resize-observer-polyfill": "^1.5.1",
84
- "sass": "^1.86.3",
84
+ "sass": "^1.87.0",
85
85
  "svelte-check": "^4.1.6",
86
86
  "svelte-eslint-parser": "1.1.3",
87
87
  "svelte-highlight": "^7.8.3",
88
88
  "topojson-client": "^3.1.0",
89
89
  "tslib": "^2.8.1",
90
90
  "typedoc": "^0.28.3",
91
- "typedoc-plugin-markdown": "^4.6.2",
91
+ "typedoc-plugin-markdown": "^4.6.3",
92
92
  "typescript": "^5.8.3",
93
- "vite": "^6.3.2",
94
- "vitest": "^3.1.1"
93
+ "vite": "^6.3.3",
94
+ "vitest": "^3.1.2"
95
95
  },
96
96
  "types": "./dist/index.d.ts",
97
97
  "type": "module",
@@ -109,9 +109,9 @@
109
109
  "d3-scale-chromatic": "^3.1.0",
110
110
  "d3-shape": "^3.2.0",
111
111
  "d3-time": "^3.1.0",
112
- "es-toolkit": "^1.35.0",
112
+ "es-toolkit": "^1.36.0",
113
113
  "fast-equals": "^5.2.2",
114
114
  "merge-deep": "^3.0.3",
115
- "svelte": "5.28.1"
115
+ "svelte": "5.28.2"
116
116
  }
117
117
  }