layerchart 2.0.0-next.4 → 2.0.0-next.41
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/components/AnnotationLine.svelte +15 -2
- package/dist/components/AnnotationPoint.svelte +29 -11
- package/dist/components/AnnotationRange.svelte +18 -4
- package/dist/components/Arc.svelte +5 -5
- package/dist/components/Area.svelte +10 -2
- package/dist/components/Axis.svelte +175 -58
- package/dist/components/Axis.svelte.d.ts +23 -6
- package/dist/components/Bar.svelte +20 -15
- package/dist/components/Bar.svelte.d.ts +2 -2
- package/dist/components/Bars.svelte +4 -4
- package/dist/components/Blur.svelte +7 -6
- package/dist/components/Blur.svelte.d.ts +2 -5
- package/dist/components/BrushContext.svelte +45 -45
- package/dist/components/Calendar.svelte +31 -10
- package/dist/components/Calendar.svelte.d.ts +2 -1
- package/dist/components/Chart.svelte +76 -27
- package/dist/components/Chart.svelte.d.ts +26 -8
- package/dist/components/ChartClipPath.svelte +1 -1
- package/dist/components/Circle.svelte +44 -3
- package/dist/components/CircleClipPath.svelte +8 -1
- package/dist/components/ClipPath.svelte +1 -2
- package/dist/components/ColorRamp.svelte +1 -1
- package/dist/components/ComputedStyles.svelte +9 -2
- package/dist/components/Connector.svelte +3 -3
- package/dist/components/Connector.svelte.d.ts +1 -1
- package/dist/components/Ellipse.svelte +228 -0
- package/dist/components/Ellipse.svelte.d.ts +64 -0
- package/dist/components/ForceSimulation.svelte +184 -50
- package/dist/components/ForceSimulation.svelte.d.ts +95 -21
- package/dist/components/Frame.svelte +1 -1
- package/dist/components/GeoCircle.svelte +1 -1
- package/dist/components/GeoEdgeFade.svelte +1 -1
- package/dist/components/GeoPath.svelte +30 -8
- package/dist/components/GeoPoint.svelte +4 -5
- package/dist/components/GeoSpline.svelte +5 -5
- package/dist/components/GeoSpline.svelte.d.ts +1 -1
- package/dist/components/GeoTile.svelte +1 -1
- package/dist/components/Graticule.svelte +5 -5
- package/dist/components/Grid.svelte +60 -63
- package/dist/components/Group.svelte +13 -8
- package/dist/components/Group.svelte.d.ts +10 -3
- package/dist/components/Highlight.svelte +55 -28
- package/dist/components/Highlight.svelte.d.ts +4 -0
- package/dist/components/Hull.svelte +12 -5
- package/dist/components/Labels.svelte +24 -13
- package/dist/components/Labels.svelte.d.ts +12 -5
- package/dist/components/Legend.svelte +143 -70
- package/dist/components/Legend.svelte.d.ts +12 -8
- package/dist/components/Line.svelte +40 -3
- package/dist/components/LinearGradient.svelte +35 -4
- package/dist/components/Link.svelte +1 -1
- package/dist/components/Marker.svelte +37 -26
- package/dist/components/MonthPath.svelte +26 -12
- package/dist/components/MonthPath.svelte.d.ts +4 -3
- package/dist/components/MotionPath.svelte +1 -1
- package/dist/components/Pack.svelte.d.ts +10 -3
- package/dist/components/Partition.svelte.d.ts +10 -3
- package/dist/components/Pattern.svelte +5 -5
- package/dist/components/Pie.svelte +1 -2
- package/dist/components/Points.svelte +11 -72
- package/dist/components/Points.svelte.d.ts +1 -8
- package/dist/components/Polygon.svelte +309 -0
- package/dist/components/Polygon.svelte.d.ts +115 -0
- package/dist/components/RadialGradient.svelte +4 -6
- package/dist/components/Rect.svelte +55 -5
- package/dist/components/Rect.svelte.d.ts +2 -2
- package/dist/components/RectClipPath.svelte +4 -3
- package/dist/components/RectClipPath.svelte.d.ts +2 -2
- package/dist/components/Rule.svelte +167 -77
- package/dist/components/Rule.svelte.d.ts +7 -2
- package/dist/components/Spline.svelte +59 -28
- package/dist/components/Spline.svelte.d.ts +12 -4
- package/dist/components/Text.svelte +121 -73
- package/dist/components/Text.svelte.d.ts +6 -0
- package/dist/components/TileImage.svelte +19 -4
- package/dist/components/TransformContext.svelte +9 -3
- package/dist/components/TransformControls.svelte +89 -38
- package/dist/components/Tree.svelte.d.ts +10 -3
- package/dist/components/Treemap.svelte +63 -26
- package/dist/components/Treemap.svelte.d.ts +21 -14
- package/dist/components/Voronoi.svelte +12 -13
- package/dist/components/charts/ArcChart.svelte +43 -71
- package/dist/components/charts/ArcChart.svelte.d.ts +10 -3
- package/dist/components/charts/AreaChart.svelte +29 -59
- package/dist/components/charts/AreaChart.svelte.d.ts +10 -3
- package/dist/components/charts/BarChart.svelte +79 -71
- package/dist/components/charts/BarChart.svelte.d.ts +10 -3
- package/dist/components/charts/DefaultTooltip.svelte +3 -3
- package/dist/components/charts/DefaultTooltip.svelte.d.ts +1 -1
- package/dist/components/charts/LineChart.svelte +69 -75
- package/dist/components/charts/LineChart.svelte.d.ts +21 -8
- package/dist/components/charts/PieChart.svelte +44 -71
- package/dist/components/charts/PieChart.svelte.d.ts +10 -3
- package/dist/components/charts/ScatterChart.svelte +10 -39
- package/dist/components/charts/ScatterChart.svelte.d.ts +10 -3
- package/dist/components/charts/utils.svelte.d.ts +1 -19
- package/dist/components/charts/utils.svelte.js +7 -35
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +5 -1
- package/dist/components/layout/Canvas.svelte +96 -69
- package/dist/components/layout/Canvas.svelte.d.ts +6 -0
- package/dist/components/layout/Html.svelte +15 -9
- package/dist/components/layout/Layer.svelte +6 -4
- package/dist/components/layout/Layer.svelte.d.ts +6 -4
- package/dist/components/layout/Svg.svelte +19 -11
- package/dist/components/layout/WebGL.svelte +26 -6
- package/dist/components/layout/WebGL.svelte.d.ts +5 -2
- package/dist/components/tooltip/Tooltip.svelte +73 -36
- package/dist/components/tooltip/Tooltip.svelte.d.ts +10 -3
- package/dist/components/tooltip/TooltipContext.svelte +167 -54
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +19 -5
- package/dist/components/tooltip/TooltipHeader.svelte +32 -18
- package/dist/components/tooltip/TooltipHeader.svelte.d.ts +3 -3
- package/dist/components/tooltip/TooltipItem.svelte +46 -37
- package/dist/components/tooltip/TooltipItem.svelte.d.ts +3 -3
- package/dist/components/tooltip/TooltipList.svelte +12 -10
- package/dist/components/tooltip/TooltipSeparator.svelte +18 -10
- package/dist/components/tooltip/tooltipMetaContext.d.ts +2 -2
- package/dist/docs/Blockquote.svelte +6 -4
- package/dist/docs/Blockquote.svelte.d.ts +4 -19
- package/dist/docs/Code.svelte +70 -28
- package/dist/docs/Code.svelte.d.ts +9 -24
- package/dist/docs/Header1.svelte +4 -2
- package/dist/docs/Header1.svelte.d.ts +4 -28
- package/dist/docs/Json.svelte +11 -3
- package/dist/docs/Json.svelte.d.ts +9 -21
- package/dist/docs/Layout.svelte +10 -7
- package/dist/docs/Layout.svelte.d.ts +4 -19
- package/dist/docs/Link.svelte +7 -3
- package/dist/docs/Link.svelte.d.ts +4 -38
- package/dist/docs/Preview.svelte +22 -23
- package/dist/docs/Preview.svelte.d.ts +5 -6
- package/dist/docs/TilesetField.svelte +20 -19
- package/dist/docs/TilesetField.svelte.d.ts +5 -22
- package/dist/docs/ViewSourceButton.svelte +10 -7
- package/dist/docs/ViewSourceButton.svelte.d.ts +7 -21
- package/dist/states/series.svelte.d.ts +30 -0
- package/dist/states/series.svelte.js +54 -0
- package/dist/styles/daisyui-5.css +6 -0
- package/dist/styles/shadcn-svelte.css +11 -0
- package/dist/styles/skeleton-3.css +15 -0
- package/dist/utils/arcText.svelte.js +4 -4
- package/dist/utils/array.d.ts +11 -0
- package/dist/utils/array.js +23 -0
- package/dist/utils/array.test.d.ts +1 -0
- package/dist/utils/array.test.js +200 -0
- package/dist/utils/attributes.d.ts +3 -13
- package/dist/utils/attributes.js +4 -18
- package/dist/utils/canvas.d.ts +77 -0
- package/dist/utils/canvas.js +105 -41
- package/dist/utils/common.d.ts +9 -0
- package/dist/utils/common.js +18 -1
- package/dist/utils/common.test.js +26 -1
- package/dist/utils/genData.d.ts +22 -8
- package/dist/utils/genData.js +34 -14
- package/dist/utils/graph/dagre.d.ts +4 -4
- package/dist/utils/graph/dagre.js +5 -7
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/math.d.ts +17 -0
- package/dist/utils/math.js +17 -0
- package/dist/utils/motion.svelte.js +1 -1
- package/dist/utils/path.d.ts +10 -0
- package/dist/utils/path.js +30 -0
- package/dist/utils/rect.svelte.d.ts +2 -2
- package/dist/utils/rect.svelte.js +73 -1
- package/dist/utils/scales.svelte.d.ts +9 -3
- package/dist/utils/scales.svelte.js +47 -4
- package/dist/utils/shape.d.ts +43 -0
- package/dist/utils/shape.js +59 -0
- package/dist/utils/stack.js +1 -1
- package/dist/utils/string.d.ts +49 -0
- package/dist/utils/string.js +4 -2
- package/dist/utils/ticks.d.ts +15 -4
- package/dist/utils/ticks.js +140 -159
- package/dist/utils/ticks.test.js +16 -26
- package/dist/utils/treemap.d.ts +1 -1
- package/dist/utils/types.d.ts +15 -2
- package/package.json +36 -35
- package/dist/utils/object.js +0 -2
|
@@ -64,6 +64,13 @@
|
|
|
64
64
|
*/
|
|
65
65
|
ignoreTransform?: boolean;
|
|
66
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Disable the hit canvas (useful when animations are playing)
|
|
69
|
+
*
|
|
70
|
+
* @default false
|
|
71
|
+
*/
|
|
72
|
+
disableHitCanvas?: boolean;
|
|
73
|
+
|
|
67
74
|
/**
|
|
68
75
|
* Show the hit canvas for debugging purposes.
|
|
69
76
|
*
|
|
@@ -142,15 +149,14 @@
|
|
|
142
149
|
|
|
143
150
|
<script lang="ts">
|
|
144
151
|
import { onMount, untrack, type Snippet } from 'svelte';
|
|
145
|
-
import { cls } from '@layerstack/tailwind';
|
|
146
152
|
import { Logger, localPoint } from '@layerstack/utils';
|
|
147
|
-
import {
|
|
153
|
+
import { MediaQueryPresets } from '@layerstack/svelte-state';
|
|
148
154
|
|
|
149
155
|
import { setRenderContext } from '../Chart.svelte';
|
|
150
156
|
import { getTransformContext } from '../TransformContext.svelte';
|
|
151
157
|
import { getPixelColor, scaleCanvas, type ComputedStylesOptions } from '../../utils/canvas.js';
|
|
152
158
|
import { getColorStr, rgbColorGenerator } from '../../utils/color.js';
|
|
153
|
-
import { Context } from 'runed';
|
|
159
|
+
import { Context, useMutationObserver, watch } from 'runed';
|
|
154
160
|
import type {
|
|
155
161
|
HTMLCanvasAttributes,
|
|
156
162
|
MouseEventHandler,
|
|
@@ -159,7 +165,6 @@
|
|
|
159
165
|
} from 'svelte/elements';
|
|
160
166
|
import type { Without } from '../../utils/types.js';
|
|
161
167
|
import { getChartContext } from '../Chart.svelte';
|
|
162
|
-
import { layerClass } from '../../utils/attributes.js';
|
|
163
168
|
|
|
164
169
|
let {
|
|
165
170
|
ref: refProp = $bindable(),
|
|
@@ -171,6 +176,7 @@
|
|
|
171
176
|
fallback,
|
|
172
177
|
center = false,
|
|
173
178
|
ignoreTransform = false,
|
|
179
|
+
disableHitCanvas = false,
|
|
174
180
|
class: className,
|
|
175
181
|
children,
|
|
176
182
|
onclick,
|
|
@@ -256,6 +262,23 @@
|
|
|
256
262
|
* end HitCanvas
|
|
257
263
|
*/
|
|
258
264
|
|
|
265
|
+
// Invalidate/redraw if color scheme changes, either via browser `prefers-color-scheme` (including emulation) or by changing `<html class="dark">` or `<html data-theme="...">`
|
|
266
|
+
const { dark } = new MediaQueryPresets();
|
|
267
|
+
watch(
|
|
268
|
+
() => dark.current,
|
|
269
|
+
() => {
|
|
270
|
+
canvasContext.invalidate();
|
|
271
|
+
}
|
|
272
|
+
);
|
|
273
|
+
useMutationObserver(
|
|
274
|
+
() => document.documentElement,
|
|
275
|
+
() => canvasContext.invalidate(),
|
|
276
|
+
{
|
|
277
|
+
attributes: true,
|
|
278
|
+
attributeFilter: ['class', 'data-theme'],
|
|
279
|
+
}
|
|
280
|
+
);
|
|
281
|
+
|
|
259
282
|
onMount(() => {
|
|
260
283
|
context = ref?.getContext('2d', { willReadFrequently }) as CanvasRenderingContext2D;
|
|
261
284
|
|
|
@@ -263,22 +286,7 @@
|
|
|
263
286
|
willReadFrequently: false, // Explicitly set to `false` to resolve pixel artifacts between fill and stroke with the same color (issue #372)
|
|
264
287
|
}) as CanvasRenderingContext2D;
|
|
265
288
|
|
|
266
|
-
// Invalidate/redraw if color scheme changes, either via browser `prefers-color-scheme` (including emulation) or by changing `<html class="dark">` or `<html data-theme="...">`
|
|
267
|
-
darkColorScheme.subscribe(() => {
|
|
268
|
-
canvasContext.invalidate();
|
|
269
|
-
});
|
|
270
|
-
|
|
271
|
-
const observer = new MutationObserver(() => {
|
|
272
|
-
canvasContext.invalidate();
|
|
273
|
-
});
|
|
274
|
-
|
|
275
|
-
observer.observe(document.documentElement, {
|
|
276
|
-
attributes: true,
|
|
277
|
-
attributeFilter: ['class', 'data-theme'],
|
|
278
|
-
});
|
|
279
|
-
|
|
280
289
|
return () => {
|
|
281
|
-
observer.disconnect();
|
|
282
290
|
if (frameId) {
|
|
283
291
|
cancelAnimationFrame(frameId);
|
|
284
292
|
}
|
|
@@ -336,45 +344,53 @@
|
|
|
336
344
|
context.restore();
|
|
337
345
|
}
|
|
338
346
|
|
|
339
|
-
|
|
347
|
+
/*
|
|
348
|
+
* Sync hit canvas with main canvas
|
|
349
|
+
*/
|
|
340
350
|
if (hitCanvasContext) {
|
|
341
|
-
// scale hit canvas to match main canvas
|
|
342
|
-
scaleCanvas(hitCanvasContext, ctx.containerWidth, ctx.containerHeight);
|
|
343
|
-
hitCanvasContext.clearRect(0, 0, ctx.containerWidth, ctx.containerHeight);
|
|
344
|
-
|
|
345
|
-
// reset and sync transform to the state after retainState components
|
|
346
|
-
hitCanvasContext.resetTransform();
|
|
347
|
-
hitCanvasContext.setTransform(mainTransformAfterRetain);
|
|
348
|
-
|
|
349
|
-
// reset color generator
|
|
350
|
-
colorGenerator = rgbColorGenerator();
|
|
351
|
-
|
|
352
351
|
const inactiveMoving = !activeCanvas && transformCtx.moving;
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
352
|
+
if (disableHitCanvas || transformCtx.dragging || inactiveMoving) {
|
|
353
|
+
// Skip rendering hit canvas
|
|
354
|
+
hitCanvasContext.clearRect(0, 0, ctx.containerWidth, ctx.containerHeight);
|
|
355
|
+
} else {
|
|
356
|
+
// scale hit canvas to match main canvas
|
|
357
|
+
scaleCanvas(hitCanvasContext, ctx.containerWidth, ctx.containerHeight);
|
|
358
|
+
hitCanvasContext.clearRect(0, 0, ctx.containerWidth, ctx.containerHeight);
|
|
359
|
+
|
|
360
|
+
// reset and sync transform to the state after retainState components
|
|
361
|
+
hitCanvasContext.resetTransform();
|
|
362
|
+
hitCanvasContext.setTransform(mainTransformAfterRetain);
|
|
363
|
+
|
|
364
|
+
// reset color generator
|
|
365
|
+
colorGenerator = rgbColorGenerator();
|
|
366
|
+
|
|
367
|
+
// render retainState components on hit canvas (e.g., Group)
|
|
368
|
+
for (const c of retainStateComponents) {
|
|
369
|
+
const componentHasEvents =
|
|
370
|
+
c.events && Object.values(c.events).filter((d) => d).length > 0;
|
|
371
|
+
|
|
372
|
+
if (componentHasEvents) {
|
|
373
|
+
// since the transform was already applied via setTransform, skip rendering
|
|
374
|
+
// the retainState component's transform again; proceed to its children
|
|
375
|
+
continue;
|
|
376
|
+
}
|
|
362
377
|
}
|
|
363
|
-
}
|
|
364
378
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
379
|
+
// render non-retainState components on hit canvas
|
|
380
|
+
for (const c of nonRetainStateComponents) {
|
|
381
|
+
const componentHasEvents =
|
|
382
|
+
c.events && Object.values(c.events).filter((d) => d).length > 0;
|
|
368
383
|
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
384
|
+
if (componentHasEvents) {
|
|
385
|
+
const color = getColorStr(colorGenerator.next().value);
|
|
386
|
+
const styleOverrides = { styles: { fill: color, stroke: color, _fillOpacity: 0.1 } };
|
|
372
387
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
388
|
+
hitCanvasContext.save();
|
|
389
|
+
c.render(hitCanvasContext, styleOverrides);
|
|
390
|
+
hitCanvasContext.restore();
|
|
376
391
|
|
|
377
|
-
|
|
392
|
+
componentByColor.set(color, c);
|
|
393
|
+
}
|
|
378
394
|
}
|
|
379
395
|
}
|
|
380
396
|
}
|
|
@@ -435,12 +451,8 @@
|
|
|
435
451
|
<canvas
|
|
436
452
|
bind:this={ref}
|
|
437
453
|
style:z-index={zIndex}
|
|
438
|
-
class={
|
|
439
|
-
|
|
440
|
-
'absolute top-0 left-0 w-full h-full',
|
|
441
|
-
pointerEvents === false && 'pointer-events-none',
|
|
442
|
-
className
|
|
443
|
-
)}
|
|
454
|
+
class={['lc-layout-canvas', className]}
|
|
455
|
+
class:disablePointerEvents={pointerEvents === false}
|
|
444
456
|
onclick={(e) => {
|
|
445
457
|
const component = getPointerComponent(e);
|
|
446
458
|
component?.events?.click?.(e);
|
|
@@ -489,17 +501,32 @@
|
|
|
489
501
|
</canvas>
|
|
490
502
|
|
|
491
503
|
<!-- Hit canvas used for hidden context -->
|
|
492
|
-
<canvas
|
|
493
|
-
bind:this={hitCanvasElement}
|
|
494
|
-
class={cls(
|
|
495
|
-
layerClass('hit-canvas'),
|
|
496
|
-
'layerchart-hitcanvas',
|
|
497
|
-
'absolute top-0 left-0 w-full h-full',
|
|
498
|
-
'pointer-events-none', // events all handled by main canvas
|
|
499
|
-
// '[image-rendering:pixelated]', // https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering
|
|
500
|
-
'border border-danger',
|
|
501
|
-
!debug && 'opacity-0'
|
|
502
|
-
)}
|
|
503
|
-
></canvas>
|
|
504
|
+
<canvas bind:this={hitCanvasElement} class="lc-hit-canvas" class:debug></canvas>
|
|
504
505
|
|
|
505
506
|
{@render children?.({ ref, canvasContext: context })}
|
|
507
|
+
|
|
508
|
+
<style>
|
|
509
|
+
@layer base {
|
|
510
|
+
:where(.lc-layout-canvas) {
|
|
511
|
+
position: absolute;
|
|
512
|
+
inset: 0;
|
|
513
|
+
|
|
514
|
+
&.disablePointerEvents {
|
|
515
|
+
pointer-events: none;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
:where(.lc-hit-canvas) {
|
|
520
|
+
position: absolute;
|
|
521
|
+
inset: 0;
|
|
522
|
+
pointer-events: none; /* events handled by main canvas */
|
|
523
|
+
image-rendering: pixelated; /* https://developer.mozilla.org/en-US/docs/Web/CSS/image-rendering */
|
|
524
|
+
|
|
525
|
+
opacity: 0;
|
|
526
|
+
&.debug {
|
|
527
|
+
border: 1px solid var(--color-danger, red);
|
|
528
|
+
opacity: 1;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
</style>
|
|
@@ -55,6 +55,12 @@ export type CanvasPropsWithoutHTML = {
|
|
|
55
55
|
* @default false
|
|
56
56
|
*/
|
|
57
57
|
ignoreTransform?: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Disable the hit canvas (useful when animations are playing)
|
|
60
|
+
*
|
|
61
|
+
* @default false
|
|
62
|
+
*/
|
|
63
|
+
disableHitCanvas?: boolean;
|
|
58
64
|
/**
|
|
59
65
|
* Show the hit canvas for debugging purposes.
|
|
60
66
|
*
|
|
@@ -46,11 +46,9 @@
|
|
|
46
46
|
</script>
|
|
47
47
|
|
|
48
48
|
<script lang="ts">
|
|
49
|
-
import { cls } from '@layerstack/tailwind';
|
|
50
49
|
import { getTransformContext } from '../TransformContext.svelte';
|
|
51
50
|
|
|
52
51
|
import { getChartContext, setRenderContext } from '../Chart.svelte';
|
|
53
|
-
import { layerClass } from '../../utils/attributes.js';
|
|
54
52
|
|
|
55
53
|
let {
|
|
56
54
|
ref: refProp = $bindable(),
|
|
@@ -90,16 +88,11 @@
|
|
|
90
88
|
|
|
91
89
|
<div
|
|
92
90
|
bind:this={ref}
|
|
93
|
-
class={
|
|
94
|
-
|
|
95
|
-
'absolute top-0 left-0',
|
|
96
|
-
pointerEvents === false && 'pointer-events-none',
|
|
97
|
-
className
|
|
98
|
-
)}
|
|
91
|
+
class={['lc-layout-html', className]}
|
|
92
|
+
class:disablePointerEvents={pointerEvents === false}
|
|
99
93
|
style:transform
|
|
100
94
|
style:transform-origin="top left"
|
|
101
95
|
style:z-index={zIndex}
|
|
102
|
-
style:pointer-events={pointerEvents === false ? 'none' : null}
|
|
103
96
|
style:top="{ctx.padding.top}px"
|
|
104
97
|
style:bottom="{ctx.padding.bottom}px"
|
|
105
98
|
style:left="{ctx.padding.left}px"
|
|
@@ -112,3 +105,16 @@
|
|
|
112
105
|
>
|
|
113
106
|
{@render children?.({ ref })}
|
|
114
107
|
</div>
|
|
108
|
+
|
|
109
|
+
<style>
|
|
110
|
+
@layer base {
|
|
111
|
+
:where(.lc-layout-html) {
|
|
112
|
+
position: absolute;
|
|
113
|
+
inset: 0;
|
|
114
|
+
|
|
115
|
+
&.disablePointerEvents {
|
|
116
|
+
pointer-events: none;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
</style>
|
|
@@ -3,17 +3,19 @@
|
|
|
3
3
|
|
|
4
4
|
export type CanvasLayerProps = {
|
|
5
5
|
type: 'canvas';
|
|
6
|
-
} & Omit<ComponentProps<typeof Canvas>, 'type'>;
|
|
6
|
+
} & Omit<ComponentProps<typeof Canvas>, 'type' | 'onpointermove'>;
|
|
7
7
|
|
|
8
8
|
export type HtmlLayerProps = {
|
|
9
9
|
type: 'html';
|
|
10
|
-
} & Omit<ComponentProps<typeof Html>, 'type'>;
|
|
10
|
+
} & Omit<ComponentProps<typeof Html>, 'type' | 'onpointermove'>;
|
|
11
11
|
|
|
12
12
|
export type SvgLayerProps = {
|
|
13
13
|
type: 'svg';
|
|
14
|
-
} & Omit<ComponentProps<typeof Svg>, 'type'>;
|
|
14
|
+
} & Omit<ComponentProps<typeof Svg>, 'type' | 'onpointermove'>;
|
|
15
15
|
|
|
16
|
-
export type LayerProps = CanvasLayerProps | HtmlLayerProps | SvgLayerProps
|
|
16
|
+
export type LayerProps = (CanvasLayerProps | HtmlLayerProps | SvgLayerProps) & {
|
|
17
|
+
onpointermove?: (e: PointerEvent) => void;
|
|
18
|
+
};
|
|
17
19
|
</script>
|
|
18
20
|
|
|
19
21
|
<script lang="ts">
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import type { ComponentProps } from 'svelte';
|
|
2
2
|
export type CanvasLayerProps = {
|
|
3
3
|
type: 'canvas';
|
|
4
|
-
} & Omit<ComponentProps<typeof Canvas>, 'type'>;
|
|
4
|
+
} & Omit<ComponentProps<typeof Canvas>, 'type' | 'onpointermove'>;
|
|
5
5
|
export type HtmlLayerProps = {
|
|
6
6
|
type: 'html';
|
|
7
|
-
} & Omit<ComponentProps<typeof Html>, 'type'>;
|
|
7
|
+
} & Omit<ComponentProps<typeof Html>, 'type' | 'onpointermove'>;
|
|
8
8
|
export type SvgLayerProps = {
|
|
9
9
|
type: 'svg';
|
|
10
|
-
} & Omit<ComponentProps<typeof Svg>, 'type'>;
|
|
11
|
-
export type LayerProps = CanvasLayerProps | HtmlLayerProps | SvgLayerProps
|
|
10
|
+
} & Omit<ComponentProps<typeof Svg>, 'type' | 'onpointermove'>;
|
|
11
|
+
export type LayerProps = (CanvasLayerProps | HtmlLayerProps | SvgLayerProps) & {
|
|
12
|
+
onpointermove?: (e: PointerEvent) => void;
|
|
13
|
+
};
|
|
12
14
|
import Canvas from './Canvas.svelte';
|
|
13
15
|
import Html from './Html.svelte';
|
|
14
16
|
import Svg from './Svg.svelte';
|
|
@@ -63,11 +63,9 @@
|
|
|
63
63
|
</script>
|
|
64
64
|
|
|
65
65
|
<script lang="ts">
|
|
66
|
-
import { cls } from '@layerstack/tailwind';
|
|
67
66
|
import { getTransformContext } from '../TransformContext.svelte';
|
|
68
67
|
|
|
69
68
|
import { getChartContext, setRenderContext } from '../Chart.svelte';
|
|
70
|
-
import { layerClass } from '../../utils/attributes.js';
|
|
71
69
|
|
|
72
70
|
let {
|
|
73
71
|
ref: refProp = $bindable(),
|
|
@@ -114,19 +112,15 @@
|
|
|
114
112
|
width={ctx.containerWidth}
|
|
115
113
|
height={ctx.containerHeight}
|
|
116
114
|
style:z-index={zIndex}
|
|
117
|
-
class={
|
|
118
|
-
|
|
119
|
-
'absolute top-0 left-0 overflow-visible',
|
|
120
|
-
pointerEvents === false && 'pointer-events-none',
|
|
121
|
-
className
|
|
122
|
-
)}
|
|
115
|
+
class={['lc-layout-svg', className]}
|
|
116
|
+
class:disablePointerEvents={pointerEvents === false}
|
|
123
117
|
role="figure"
|
|
124
118
|
{...restProps}
|
|
125
119
|
>
|
|
126
120
|
{#if typeof title === 'function'}
|
|
127
121
|
{@render title()}
|
|
128
122
|
{:else if title}
|
|
129
|
-
<title class=
|
|
123
|
+
<title class="lc-layout-svg-title">{title}</title>
|
|
130
124
|
{/if}
|
|
131
125
|
|
|
132
126
|
<defs>
|
|
@@ -135,11 +129,11 @@
|
|
|
135
129
|
|
|
136
130
|
<g
|
|
137
131
|
bind:this={innerRef}
|
|
138
|
-
class=
|
|
132
|
+
class="lc-layout-svg-g"
|
|
139
133
|
transform="translate({ctx.padding.left}, {ctx.padding.top})"
|
|
140
134
|
>
|
|
141
135
|
{#if transform}
|
|
142
|
-
<g {transform} class=
|
|
136
|
+
<g {transform} class="lc-layout-svg-g-transform">
|
|
143
137
|
{@render children?.({ ref })}
|
|
144
138
|
</g>
|
|
145
139
|
{:else}
|
|
@@ -147,3 +141,17 @@
|
|
|
147
141
|
{/if}
|
|
148
142
|
</g>
|
|
149
143
|
</svg>
|
|
144
|
+
|
|
145
|
+
<style>
|
|
146
|
+
@layer base {
|
|
147
|
+
:where(.lc-layout-svg) {
|
|
148
|
+
position: absolute;
|
|
149
|
+
inset: 0;
|
|
150
|
+
overflow: visible; /* match html and allow viewing outside of bounds (useful for axis that leak and general debugging)*/
|
|
151
|
+
|
|
152
|
+
&.disablePointerEvents {
|
|
153
|
+
pointer-events: none;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
</style>
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { Without } from '../../utils/types.js';
|
|
4
|
+
import type { HTMLCanvasAttributes } from 'svelte/elements';
|
|
5
|
+
|
|
6
|
+
export type WebGLPropsWithoutHTML = {
|
|
3
7
|
/**
|
|
4
8
|
* A reference to the `<canvas>` element.
|
|
5
9
|
*
|
|
@@ -44,6 +48,9 @@
|
|
|
44
48
|
>;
|
|
45
49
|
};
|
|
46
50
|
|
|
51
|
+
export type WebGLProps = WebGLPropsWithoutHTML &
|
|
52
|
+
Without<HTMLCanvasAttributes, WebGLPropsWithoutHTML>;
|
|
53
|
+
|
|
47
54
|
export type WebGLContextValue = {
|
|
48
55
|
gl: WebGLRenderingContext | null;
|
|
49
56
|
};
|
|
@@ -61,10 +68,9 @@
|
|
|
61
68
|
</script>
|
|
62
69
|
|
|
63
70
|
<script lang="ts">
|
|
64
|
-
import { onMount
|
|
71
|
+
import { onMount } from 'svelte';
|
|
65
72
|
import { getChartContext } from '../Chart.svelte';
|
|
66
73
|
import { Context } from 'runed';
|
|
67
|
-
import { extractLayerProps } from '../../utils/attributes.js';
|
|
68
74
|
|
|
69
75
|
let {
|
|
70
76
|
context = $bindable(),
|
|
@@ -73,6 +79,7 @@
|
|
|
73
79
|
fallback = '',
|
|
74
80
|
pointerEvents = true,
|
|
75
81
|
zIndex = 0,
|
|
82
|
+
class: className,
|
|
76
83
|
children,
|
|
77
84
|
...restProps
|
|
78
85
|
}: WebGLProps = $props();
|
|
@@ -116,14 +123,14 @@
|
|
|
116
123
|
|
|
117
124
|
<canvas
|
|
118
125
|
bind:this={ref}
|
|
126
|
+
class={['lc-layout-webgl', className]}
|
|
127
|
+
class:disablePointerEvents={pointerEvents === false}
|
|
119
128
|
style:z-index={zIndex}
|
|
120
|
-
style:pointer-events={pointerEvents === false ? 'none' : null}
|
|
121
129
|
style:top={ctx.padding.top + 'px'}
|
|
122
130
|
style:right={ctx.padding.right + 'px'}
|
|
123
131
|
style:bottom={ctx.padding.bottom + 'px'}
|
|
124
132
|
style:left={ctx.padding.left + 'px'}
|
|
125
|
-
|
|
126
|
-
{...extractLayerProps(restProps, 'layout-webgl')}
|
|
133
|
+
{...restProps}
|
|
127
134
|
>
|
|
128
135
|
{#if typeof fallback === 'function'}
|
|
129
136
|
{@render fallback()}
|
|
@@ -133,3 +140,16 @@
|
|
|
133
140
|
</canvas>
|
|
134
141
|
|
|
135
142
|
{@render children?.({ ref, webGLContext: context })}
|
|
143
|
+
|
|
144
|
+
<style>
|
|
145
|
+
@layer base {
|
|
146
|
+
:where(.lc-layout-webgl) {
|
|
147
|
+
position: absolute;
|
|
148
|
+
inset: 0;
|
|
149
|
+
|
|
150
|
+
&.disablePointerEvents {
|
|
151
|
+
pointer-events: none;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
</style>
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { Without } from '../../utils/types.js';
|
|
3
|
+
import type { HTMLCanvasAttributes } from 'svelte/elements';
|
|
4
|
+
export type WebGLPropsWithoutHTML = {
|
|
2
5
|
/**
|
|
3
6
|
* A reference to the `<canvas>` element.
|
|
4
7
|
*
|
|
@@ -39,12 +42,12 @@ export type WebGLProps = {
|
|
|
39
42
|
}
|
|
40
43
|
]>;
|
|
41
44
|
};
|
|
45
|
+
export type WebGLProps = WebGLPropsWithoutHTML & Without<HTMLCanvasAttributes, WebGLPropsWithoutHTML>;
|
|
42
46
|
export type WebGLContextValue = {
|
|
43
47
|
gl: WebGLRenderingContext | null;
|
|
44
48
|
};
|
|
45
49
|
export declare function setWebGLContext(context: WebGLContextValue): WebGLContextValue;
|
|
46
50
|
export declare function getWebGLContext(): WebGLContextValue;
|
|
47
|
-
import { type Snippet } from 'svelte';
|
|
48
51
|
declare const WebGl: import("svelte").Component<WebGLProps, {}, "ref" | "context">;
|
|
49
52
|
type WebGl = ReturnType<typeof WebGl>;
|
|
50
53
|
export default WebGl;
|
|
@@ -162,7 +162,6 @@
|
|
|
162
162
|
import { getTooltipContext } from './TooltipContext.svelte';
|
|
163
163
|
import { createMotion, type MotionProp } from '../../utils/motion.svelte.js';
|
|
164
164
|
import { untrack, type Snippet } from 'svelte';
|
|
165
|
-
import { layerClass } from '../../utils/attributes.js';
|
|
166
165
|
|
|
167
166
|
let {
|
|
168
167
|
anchor = 'top-left',
|
|
@@ -193,8 +192,8 @@
|
|
|
193
192
|
const ctx = getChartContext();
|
|
194
193
|
const tooltipCtx = getTooltipContext();
|
|
195
194
|
|
|
196
|
-
let tooltipWidth = $state(
|
|
197
|
-
let tooltipHeight = $state(
|
|
195
|
+
let tooltipWidth = $state<number | null>(null);
|
|
196
|
+
let tooltipHeight = $state<number | null>(null);
|
|
198
197
|
|
|
199
198
|
function alignValue(value: number, align: Align, additionalOffset: number, tooltipSize: number) {
|
|
200
199
|
const alignOffset = align === 'center' ? tooltipSize / 2 : align === 'end' ? tooltipSize : 0;
|
|
@@ -202,12 +201,11 @@
|
|
|
202
201
|
}
|
|
203
202
|
|
|
204
203
|
const positions = $derived.by(() => {
|
|
205
|
-
if
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
const tooltipY = untrack(() => tooltipCtx.y);
|
|
209
|
-
return { x: tooltipX, y: tooltipY };
|
|
204
|
+
// if no data or tooltip size is not known yet, return null
|
|
205
|
+
if (!tooltipCtx.data || tooltipWidth === null || tooltipHeight === null) {
|
|
206
|
+
return { x: null, y: null };
|
|
210
207
|
}
|
|
208
|
+
|
|
211
209
|
const xBandOffset = isScaleBand(ctx.xScale)
|
|
212
210
|
? ctx.xScale.step() / 2 - (ctx.xScale.padding() * ctx.xScale.step()) / 2
|
|
213
211
|
: 0;
|
|
@@ -346,8 +344,8 @@
|
|
|
346
344
|
};
|
|
347
345
|
});
|
|
348
346
|
|
|
349
|
-
const motionX = createMotion(
|
|
350
|
-
const motionY = createMotion(
|
|
347
|
+
const motionX = createMotion(null, () => positions.x, motion);
|
|
348
|
+
const motionY = createMotion(null, () => positions.y, motion);
|
|
351
349
|
|
|
352
350
|
$effect(() => {
|
|
353
351
|
if (!tooltipCtx.data) {
|
|
@@ -359,13 +357,8 @@
|
|
|
359
357
|
{#if tooltipCtx.data}
|
|
360
358
|
<div
|
|
361
359
|
{...props.root}
|
|
362
|
-
class={cls(
|
|
363
|
-
|
|
364
|
-
'absolute z-50 select-none',
|
|
365
|
-
!pointerEvents && 'pointer-events-none',
|
|
366
|
-
classes.root,
|
|
367
|
-
props.root?.class
|
|
368
|
-
)}
|
|
360
|
+
class={cls('lc-tooltip-root', classes.root, props.root?.class)}
|
|
361
|
+
class:disablePointerEvents={pointerEvents === false}
|
|
369
362
|
style:top="{motionY.current}px"
|
|
370
363
|
style:left="{motionX.current}px"
|
|
371
364
|
transition:fade={{ duration: 100 }}
|
|
@@ -381,30 +374,74 @@
|
|
|
381
374
|
>
|
|
382
375
|
<div
|
|
383
376
|
{...props.container}
|
|
384
|
-
class={cls(
|
|
385
|
-
|
|
386
|
-
variant !== 'none' && ['text-sm py-1 px-2 h-full rounded-sm elevation-1'],
|
|
387
|
-
{
|
|
388
|
-
default: [
|
|
389
|
-
'bg-surface-100/90 dark:bg-surface-300/90 backdrop-filter backdrop-blur-[2px] text-surface-content',
|
|
390
|
-
'[&_.label]:text-surface-content/75',
|
|
391
|
-
],
|
|
392
|
-
invert: [
|
|
393
|
-
'bg-surface-content/90 backdrop-filter backdrop-blur-[2px] text-surface-100 border border-surface-content',
|
|
394
|
-
'[&_.label]:text-surface-100/50',
|
|
395
|
-
],
|
|
396
|
-
none: '',
|
|
397
|
-
}[variant],
|
|
398
|
-
classes.container,
|
|
399
|
-
props.container?.class,
|
|
400
|
-
className
|
|
401
|
-
)}
|
|
377
|
+
class={cls('lc-tooltip-container', classes.container, props.container?.class, className)}
|
|
378
|
+
data-variant={variant}
|
|
402
379
|
>
|
|
403
380
|
{#if children}
|
|
404
|
-
<div {...props.content} class={cls(
|
|
381
|
+
<div {...props.content} class={cls('lc-tooltip-content', classes.content)}>
|
|
405
382
|
{@render children({ data: tooltipCtx.data, payload: tooltipCtx.payload })}
|
|
406
383
|
</div>
|
|
407
384
|
{/if}
|
|
408
385
|
</div>
|
|
409
386
|
</div>
|
|
410
387
|
{/if}
|
|
388
|
+
|
|
389
|
+
<style>
|
|
390
|
+
@layer component {
|
|
391
|
+
:where(.lc-tooltip-root) {
|
|
392
|
+
position: absolute;
|
|
393
|
+
z-index: 50;
|
|
394
|
+
user-select: none;
|
|
395
|
+
|
|
396
|
+
&.disablePointerEvents {
|
|
397
|
+
pointer-events: none;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
:where(.lc-tooltip-container) {
|
|
402
|
+
&:not([data-variant='none']) {
|
|
403
|
+
font-size: 0.875rem;
|
|
404
|
+
line-height: 1.25rem;
|
|
405
|
+
padding: 4px 8px;
|
|
406
|
+
height: 100%;
|
|
407
|
+
border-radius: 0.25rem; /* rounded-sm */
|
|
408
|
+
box-shadow: /* elevation-1 */
|
|
409
|
+
0px 2px 1px -1px hsl(0 0% 0% / 20%),
|
|
410
|
+
0px 1px 1px 0px hsl(0 0% 0% / 14%),
|
|
411
|
+
0px 1px 3px 0px hsl(0 0% 0% / 12%);
|
|
412
|
+
/* STYLE-TODO: vendor prefix (-webkit?) */
|
|
413
|
+
backdrop-filter: blur(2px);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
&[data-variant='default'] {
|
|
417
|
+
color: var(--color-surface-content, currentColor);
|
|
418
|
+
background-color: color-mix(
|
|
419
|
+
in oklab,
|
|
420
|
+
light-dark(var(--color-surface-100, white), var(--color-surface-300, black)) 90%,
|
|
421
|
+
transparent
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
:global(& .label) {
|
|
425
|
+
color: color-mix(in oklab, var(--color-surface-content, currentColor) 75%, transparent);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
&[data-variant='invert'] {
|
|
430
|
+
color: var(--color-surface-100, light-dark(white, black));
|
|
431
|
+
background-color: color-mix(
|
|
432
|
+
in oklab,
|
|
433
|
+
var(--color-surface-content, currentColor) 90%,
|
|
434
|
+
transparent
|
|
435
|
+
);
|
|
436
|
+
|
|
437
|
+
:global(& .label) {
|
|
438
|
+
color: color-mix(
|
|
439
|
+
in oklab,
|
|
440
|
+
var(--color-surface-100, light-dark(white, black)) 50%,
|
|
441
|
+
transparent
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
</style>
|
|
@@ -134,10 +134,17 @@ export type TooltipProps<T = any> = TooltipPropsWithoutHTML<T> & Without<HTMLAtt
|
|
|
134
134
|
import { type ChartContextValue } from '../Chart.svelte';
|
|
135
135
|
import { type MotionProp } from '../../utils/motion.svelte.js';
|
|
136
136
|
import { type Snippet } from 'svelte';
|
|
137
|
+
declare function $$render<T = any>(): {
|
|
138
|
+
props: TooltipProps<T>;
|
|
139
|
+
exports: {};
|
|
140
|
+
bindings: "rootRef";
|
|
141
|
+
slots: {};
|
|
142
|
+
events: {};
|
|
143
|
+
};
|
|
137
144
|
declare class __sveltets_Render<T = any> {
|
|
138
|
-
props():
|
|
139
|
-
events():
|
|
140
|
-
slots():
|
|
145
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
146
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
147
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
141
148
|
bindings(): "rootRef";
|
|
142
149
|
exports(): {};
|
|
143
150
|
}
|