svelteplot 0.4.2-pr-192.0 → 0.4.2-pr-193.0

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.
@@ -136,11 +136,11 @@
136
136
  class={['svelteplot-area', className, styleClass]}
137
137
  clip-path={options.clipPath}
138
138
  d={areaPath(areaData)}
139
- use:addEventHandlers={{
139
+ {@attach addEventHandlers({
140
140
  getPlotState,
141
141
  options,
142
- datum: datum.datum
143
- }}
142
+ datum: datum?.datum
143
+ })}
144
144
  {style}
145
145
  >{#if title}<title>{title}</title>{/if}</path>
146
146
  </Anchor>
@@ -131,11 +131,11 @@
131
131
  )}
132
132
  <g
133
133
  class={[className]}
134
- use:addEventHandlers={{
134
+ {@attach addEventHandlers({
135
135
  getPlotState,
136
- options: args,
137
- datum: d.datum
138
- }}>
136
+ options,
137
+ datum: d?.datum
138
+ })}>
139
139
  {#if options.onmouseenter || options.onclick}
140
140
  <!-- add invisible path in bg for easier mouse access -->
141
141
  <path
@@ -107,11 +107,11 @@
107
107
  styleClass
108
108
  ]}
109
109
  {style}
110
- use:addEventHandlers={{
110
+ {@attach addEventHandlers({
111
111
  getPlotState,
112
112
  options: args,
113
- datum: d.datum
114
- }} />
113
+ datum: d?.datum
114
+ })} />
115
115
  </Anchor>
116
116
  {/if}
117
117
  {/each}
@@ -111,11 +111,11 @@
111
111
  d={path(geometry)}
112
112
  {style}
113
113
  class={[styleClass]}
114
- use:addEventHandlers={{
114
+ {@attach addEventHandlers({
115
115
  getPlotState,
116
116
  options: args,
117
- datum: d.datum
118
- }}>
117
+ datum: d?.datum
118
+ })}>
119
119
  {#if title}<title>{title}</title>{/if}
120
120
  </path>
121
121
  </Anchor>
@@ -201,11 +201,11 @@
201
201
  ? `translate(0, ${d.length})`
202
202
  : `translate(0, ${d.length / 2})`}"
203
203
  {style}
204
- use:addEventHandlers={{
204
+ {@attach addEventHandlers({
205
205
  getPlotState,
206
206
  options: args,
207
- datum: d.datum
208
- }}
207
+ datum: d?.datum
208
+ })}
209
209
  class={[styleClass]} />
210
210
  {/if}
211
211
  {/each}
@@ -95,7 +95,11 @@
95
95
  {transform}
96
96
  class={className}
97
97
  stroke-width={strokeWidth_}
98
- use:addEventHandlers={{ getPlotState, options: mark.options, datum }}>
98
+ {@attach addEventHandlers({
99
+ getPlotState,
100
+ options: mark.options,
101
+ datum: datum
102
+ })}>
99
103
  {#each Object.entries( { start: markerStart, mid: markerMid, end: markerEnd, all: marker } ) as [key, marker] (key)}
100
104
  {@const markerId = `marker-${key === 'all' ? '' : `${key}-`}${id}`}
101
105
  {#if isSnippet(marker)}
@@ -122,7 +126,11 @@
122
126
  marker-end={markerEnd || marker ? `url(#marker-${markerEnd ? 'end-' : ''}${id})` : null}
123
127
  {d}
124
128
  {style}
125
- use:addEventHandlers={{ getPlotState, options: mark.options, datum }} />
129
+ {@attach addEventHandlers({
130
+ getPlotState,
131
+ options: mark.options,
132
+ datum: datum
133
+ })} />
126
134
  {#if text}
127
135
  <!-- since textPath.side is not yet supported, we have to use an invisible
128
136
  path in order to keep the text from turning upside down -->
@@ -34,6 +34,7 @@ Helper component for rendering rectangular marks in SVG
34
34
  import type { BaseMarkProps, BaseRectMarkProps, BorderRadius } from '../../types/mark.js';
35
35
  import type { DataRecord, ScaledDataRecord } from '../../types/data.js';
36
36
  import type { PlotContext, UsedScales } from '../../types/index.js';
37
+ import { RAW_VALUE } from '../../transforms/recordize.js';
37
38
 
38
39
  let {
39
40
  datum,
@@ -110,11 +111,11 @@ Helper component for rendering rectangular marks in SVG
110
111
  )}
111
112
  class={[styleClass, className]}
112
113
  {style}
113
- use:addEventHandlers={{
114
+ {@attach addEventHandlers({
114
115
  getPlotState,
115
116
  options,
116
117
  datum: datum?.datum
117
- }} />
118
+ })} />
118
119
  {:else}
119
120
  <rect
120
121
  transform="translate({x + insetLeft},{y + insetBottom})"
@@ -122,10 +123,10 @@ Helper component for rendering rectangular marks in SVG
122
123
  height={height - insetTop - insetBottom}
123
124
  class={[styleClass, className]}
124
125
  {style}
125
- use:addEventHandlers={{
126
+ {@attach addEventHandlers({
126
127
  getPlotState,
127
128
  options,
128
129
  datum: datum?.datum
129
- }} />
130
+ })} />
130
131
  {/if}
131
132
  </Anchor>
@@ -1,4 +1,5 @@
1
- import type { BaseMarkProps, DataRecord, PlotState } from '../../types/index.js';
1
+ import type { BaseMarkProps, DataRecord, DataRow, PlotState } from '../../types/index.js';
2
+ import type { Attachment } from 'svelte/attachments';
2
3
  declare global {
3
4
  interface MouseEvent {
4
5
  layerX?: number;
@@ -12,10 +13,8 @@ declare global {
12
13
  * of the plot frame, regardless of which element triggered the event
13
14
  */
14
15
  export declare function clientToLayerCoordinates(event: MouseEvent, plotBody: HTMLElement | null | undefined): [number, number];
15
- export declare function addEventHandlers(node: SVGElement, { options, datum, getPlotState }: {
16
- options: BaseMarkProps;
16
+ export declare function addEventHandlers<T extends DataRow>({ options, datum, getPlotState }: {
17
+ options: BaseMarkProps<T>;
17
18
  datum: DataRecord;
18
19
  getPlotState: () => PlotState;
19
- }): {
20
- destroy(): void;
21
- };
20
+ }): Attachment;
@@ -19,7 +19,7 @@ export function clientToLayerCoordinates(event, plotBody) {
19
19
  // Calculate the coordinates relative to the plot body
20
20
  return [event.clientX - plotBodyRect.left, event.clientY - plotBodyRect.top];
21
21
  }
22
- export function addEventHandlers(node, { options, datum, getPlotState }) {
22
+ export function addEventHandlers({ options, datum, getPlotState }) {
23
23
  const events = pick(options, [
24
24
  'onclick',
25
25
  'oncontextmenu',
@@ -51,51 +51,51 @@ export function addEventHandlers(node, { options, datum, getPlotState }) {
51
51
  'ontouchmove',
52
52
  'onwheel'
53
53
  ]);
54
- const listeners = new Map();
55
- // attach event handlers
56
- for (const [eventName, eventHandler] of Object.entries(events)) {
57
- if (eventHandler) {
58
- const wrappedHandler = (origEvent) => {
59
- const { scales, body, options } = getPlotState();
60
- if (origEvent instanceof MouseEvent || origEvent instanceof PointerEvent) {
61
- let facetEl = origEvent.target;
62
- while (facetEl &&
63
- !facetEl.classList.contains('facet') &&
64
- facetEl.parentElement) {
65
- // ensure that parentElement is SVGElement
66
- if (!(facetEl.parentElement instanceof SVGElement))
67
- break;
68
- facetEl = facetEl.parentElement;
54
+ return (node) => {
55
+ const listeners = new Map();
56
+ // attach event handlers
57
+ for (const [eventName, eventHandler] of Object.entries(events)) {
58
+ if (eventHandler) {
59
+ const wrappedHandler = (origEvent) => {
60
+ const { scales, body, options } = getPlotState();
61
+ if (origEvent instanceof MouseEvent || origEvent instanceof PointerEvent) {
62
+ let facetEl = origEvent.target;
63
+ while (facetEl &&
64
+ !facetEl.classList.contains('facet') &&
65
+ facetEl.parentElement) {
66
+ // ensure that parentElement is SVGElement
67
+ if (!(facetEl.parentElement instanceof SVGElement))
68
+ break;
69
+ facetEl = facetEl.parentElement;
70
+ }
71
+ const facetRect = (facetEl?.firstElementChild ?? body).getBoundingClientRect();
72
+ const relativeX = origEvent.clientX - facetRect.left + (options.marginLeft ?? 0);
73
+ const relativeY = origEvent.clientY - facetRect.top + (options.marginTop ?? 0);
74
+ if (scales.projection) {
75
+ const [x, y] = scales.projection.invert([relativeX, relativeY]);
76
+ origEvent.dataX = x;
77
+ origEvent.dataY = y;
78
+ }
79
+ else {
80
+ origEvent.dataX = invertScale(scales.x, relativeX);
81
+ origEvent.dataY = invertScale(scales.y, relativeY);
82
+ }
69
83
  }
70
- const facetRect = (facetEl?.firstElementChild ?? body).getBoundingClientRect();
71
- const relativeX = origEvent.clientX - facetRect.left + (options.marginLeft ?? 0);
72
- const relativeY = origEvent.clientY - facetRect.top + (options.marginTop ?? 0);
73
- if (scales.projection) {
74
- const [x, y] = scales.projection.invert([relativeX, relativeY]);
75
- origEvent.dataX = x;
76
- origEvent.dataY = y;
77
- }
78
- else {
79
- origEvent.dataX = invertScale(scales.x, relativeX);
80
- origEvent.dataY = invertScale(scales.y, relativeY);
81
- }
82
- }
83
- eventHandler(origEvent, datum.hasOwnProperty(RAW_VALUE) ? datum[RAW_VALUE] : datum, datum[INDEX]);
84
- };
85
- listeners.set(eventName, wrappedHandler);
86
- node.addEventListener(eventName.substring(2), wrappedHandler);
84
+ eventHandler(origEvent, datum.hasOwnProperty(RAW_VALUE) ? datum[RAW_VALUE] : datum, datum[INDEX]);
85
+ };
86
+ listeners.set(eventName, wrappedHandler);
87
+ node.addEventListener(eventName.substring(2), wrappedHandler);
88
+ }
87
89
  }
88
- }
89
- if (events.onclick || events.onmousedown || events.onmouseup) {
90
- // force role button
91
- node.setAttribute('role', 'button');
92
- }
93
- return {
94
- destroy() {
90
+ if (events.onclick || events.onmousedown || events.onmouseup) {
91
+ // force role button
92
+ node.setAttribute('role', 'button');
93
+ }
94
+ return () => {
95
95
  for (const [eventName, handler] of listeners.entries()) {
96
96
  node.removeEventListener(eventName.substring(2), handler);
97
97
  }
98
- }
98
+ };
99
99
  };
100
100
  }
101
101
  function invertScale(scale, position) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteplot",
3
- "version": "0.4.2-pr-192.0",
3
+ "version": "0.4.2-pr-193.0",
4
4
  "license": "ISC",
5
5
  "author": {
6
6
  "name": "Gregor Aisch",