layerchart 2.0.0-next.37 → 2.0.0-next.39
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 +13 -2
- package/dist/components/AnnotationRange.svelte +16 -2
- package/dist/components/Arc.svelte +3 -3
- package/dist/components/Area.svelte +10 -2
- package/dist/components/Axis.svelte +43 -26
- package/dist/components/Axis.svelte.d.ts +10 -3
- package/dist/components/Bar.svelte +6 -5
- package/dist/components/Bar.svelte.d.ts +2 -2
- package/dist/components/Bars.svelte +3 -3
- package/dist/components/Blur.svelte +2 -3
- package/dist/components/BrushContext.svelte +44 -44
- package/dist/components/Calendar.svelte +21 -4
- package/dist/components/Chart.svelte +1 -2
- package/dist/components/Chart.svelte.d.ts +10 -3
- 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 +1 -1
- package/dist/components/Ellipse.svelte +44 -3
- package/dist/components/ForceSimulation.svelte.d.ts +10 -3
- 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 +18 -3
- package/dist/components/GeoPoint.svelte +3 -3
- package/dist/components/GeoSpline.svelte +1 -1
- package/dist/components/GeoTile.svelte +1 -1
- package/dist/components/Graticule.svelte +5 -5
- package/dist/components/Grid.svelte +57 -60
- package/dist/components/Group.svelte +11 -6
- package/dist/components/Group.svelte.d.ts +10 -3
- package/dist/components/Highlight.svelte +46 -22
- package/dist/components/Highlight.svelte.d.ts +4 -0
- package/dist/components/Hull.svelte +11 -4
- package/dist/components/Labels.svelte +21 -11
- package/dist/components/Labels.svelte.d.ts +10 -3
- package/dist/components/Legend.svelte +133 -67
- package/dist/components/Legend.svelte.d.ts +7 -3
- 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 +14 -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 +1 -3
- package/dist/components/Polygon.svelte +27 -3
- package/dist/components/RadialGradient.svelte +3 -3
- 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 +30 -23
- package/dist/components/Spline.svelte +29 -10
- package/dist/components/Text.svelte +59 -13
- package/dist/components/TileImage.svelte +19 -4
- package/dist/components/TransformContext.svelte +9 -3
- package/dist/components/TransformControls.svelte +72 -17
- package/dist/components/Tree.svelte.d.ts +10 -3
- package/dist/components/Treemap.svelte.d.ts +10 -3
- package/dist/components/Voronoi.svelte +12 -13
- package/dist/components/charts/ArcChart.svelte +40 -69
- package/dist/components/charts/ArcChart.svelte.d.ts +10 -3
- package/dist/components/charts/AreaChart.svelte +19 -42
- package/dist/components/charts/AreaChart.svelte.d.ts +10 -3
- package/dist/components/charts/BarChart.svelte +7 -18
- package/dist/components/charts/BarChart.svelte.d.ts +10 -3
- package/dist/components/charts/DefaultTooltip.svelte +2 -2
- package/dist/components/charts/DefaultTooltip.svelte.d.ts +1 -1
- package/dist/components/charts/LineChart.svelte +61 -66
- package/dist/components/charts/LineChart.svelte.d.ts +21 -8
- package/dist/components/charts/PieChart.svelte +41 -69
- package/dist/components/charts/PieChart.svelte.d.ts +10 -3
- package/dist/components/charts/ScatterChart.svelte +8 -19
- 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 -39
- package/dist/components/layout/Canvas.svelte +29 -20
- package/dist/components/layout/Html.svelte +15 -9
- 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 +60 -29
- package/dist/components/tooltip/Tooltip.svelte.d.ts +10 -3
- package/dist/components/tooltip/TooltipContext.svelte +73 -36
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +17 -3
- package/dist/components/tooltip/TooltipHeader.svelte +27 -14
- package/dist/components/tooltip/TooltipItem.svelte +41 -33
- package/dist/components/tooltip/TooltipList.svelte +12 -10
- package/dist/components/tooltip/TooltipSeparator.svelte +18 -10
- 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/attributes.d.ts +3 -13
- package/dist/utils/attributes.js +4 -18
- 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/graph/dagre.d.ts +4 -4
- package/dist/utils/graph/dagre.js +5 -7
- package/dist/utils/math.d.ts +17 -0
- package/dist/utils/math.js +17 -0
- package/dist/utils/scales.svelte.js +3 -3
- package/dist/utils/stack.js +1 -1
- package/dist/utils/types.d.ts +15 -2
- package/package.json +25 -22
|
@@ -101,6 +101,11 @@
|
|
|
101
101
|
*/
|
|
102
102
|
motion?: MotionProp;
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* The opacity of the element. (0 to 1)
|
|
106
|
+
*/
|
|
107
|
+
opacity?: number;
|
|
108
|
+
|
|
104
109
|
onAreaClick?: (e: MouseEvent, detail: { data: any }) => void;
|
|
105
110
|
onBarClick?: (e: MouseEvent, detail: { data: any }) => void;
|
|
106
111
|
|
|
@@ -114,7 +119,6 @@
|
|
|
114
119
|
import { max, min } from 'd3-array';
|
|
115
120
|
import { pointRadial, type Series, type SeriesPoint } from 'd3-shape';
|
|
116
121
|
import { notNull } from '@layerstack/utils';
|
|
117
|
-
import { cls } from '@layerstack/tailwind';
|
|
118
122
|
|
|
119
123
|
import { isScaleBand, isScaleTime } from '../utils/scales.svelte.js';
|
|
120
124
|
import { asAny } from '../utils/types.js';
|
|
@@ -136,6 +140,7 @@
|
|
|
136
140
|
lines: linesProp = false,
|
|
137
141
|
area = false,
|
|
138
142
|
bar = false,
|
|
143
|
+
opacity,
|
|
139
144
|
motion = 'spring',
|
|
140
145
|
onAreaClick,
|
|
141
146
|
onBarClick,
|
|
@@ -435,11 +440,6 @@
|
|
|
435
440
|
return tmpPoints;
|
|
436
441
|
}
|
|
437
442
|
);
|
|
438
|
-
|
|
439
|
-
const areaProps = $derived(extractLayerProps(area, 'highlight-area'));
|
|
440
|
-
const barProps = $derived(extractLayerProps(bar, 'highlight-bar'));
|
|
441
|
-
const linesProps = $derived(extractLayerProps(linesProp, 'highlight-line'));
|
|
442
|
-
const pointsProps = $derived(extractLayerProps(points, 'highlight-point'));
|
|
443
443
|
</script>
|
|
444
444
|
|
|
445
445
|
{#if highlightData}
|
|
@@ -454,15 +454,16 @@
|
|
|
454
454
|
endAngle={_area.x + _area.width}
|
|
455
455
|
innerRadius={_area.y}
|
|
456
456
|
outerRadius={_area.y + _area.height}
|
|
457
|
-
|
|
457
|
+
{opacity}
|
|
458
|
+
class="lc-highlight-area"
|
|
458
459
|
onclick={onAreaClick && ((e) => onAreaClick(e, { data: highlightData }))}
|
|
459
460
|
/>
|
|
460
461
|
{:else}
|
|
461
462
|
<Rect
|
|
462
463
|
motion={motion === 'spring' ? 'spring' : undefined}
|
|
464
|
+
{opacity}
|
|
463
465
|
{..._area}
|
|
464
|
-
{...
|
|
465
|
-
class={cls(!areaProps.fill && 'fill-surface-content/5', areaProps.class)}
|
|
466
|
+
{...extractLayerProps(area, 'lc-highlight-area')}
|
|
466
467
|
onclick={onAreaClick && ((e) => onAreaClick(e, { data: highlightData }))}
|
|
467
468
|
/>
|
|
468
469
|
{/if}
|
|
@@ -475,8 +476,8 @@
|
|
|
475
476
|
<Bar
|
|
476
477
|
motion={motion === 'spring' ? 'spring' : undefined}
|
|
477
478
|
data={highlightData}
|
|
478
|
-
{
|
|
479
|
-
|
|
479
|
+
{opacity}
|
|
480
|
+
{...extractLayerProps(bar, 'lc-highlight-bar')}
|
|
480
481
|
onclick={onBarClick && ((e) => onBarClick(e, { data: highlightData }))}
|
|
481
482
|
/>
|
|
482
483
|
{/if}
|
|
@@ -493,11 +494,8 @@
|
|
|
493
494
|
y1={line.y1}
|
|
494
495
|
x2={line.x2}
|
|
495
496
|
y2={line.y2}
|
|
496
|
-
{
|
|
497
|
-
|
|
498
|
-
'stroke-surface-content/20 stroke-2 [stroke-dasharray:2,2] pointer-events-none',
|
|
499
|
-
linesProps.class
|
|
500
|
-
)}
|
|
497
|
+
{opacity}
|
|
498
|
+
{...extractLayerProps(linesProp, 'lc-highlight-line')}
|
|
501
499
|
/>
|
|
502
500
|
{/each}
|
|
503
501
|
{/if}
|
|
@@ -515,12 +513,8 @@
|
|
|
515
513
|
fill={point.fill}
|
|
516
514
|
r={4}
|
|
517
515
|
strokeWidth={6}
|
|
518
|
-
{
|
|
519
|
-
|
|
520
|
-
'stroke-white [paint-order:stroke] drop-shadow-sm',
|
|
521
|
-
!point.fill && (typeof points === 'boolean' || !points.fill) && 'fill-primary',
|
|
522
|
-
pointsProps.class
|
|
523
|
-
)}
|
|
516
|
+
{opacity}
|
|
517
|
+
{...extractLayerProps(points, 'lc-highlight-point')}
|
|
524
518
|
onpointerdown={onPointClick &&
|
|
525
519
|
((e) => {
|
|
526
520
|
// Do not propagate `pointerdown` event to `BrushContext` if `onclick` is provided
|
|
@@ -546,3 +540,33 @@
|
|
|
546
540
|
{/if}
|
|
547
541
|
{/if}
|
|
548
542
|
{/if}
|
|
543
|
+
|
|
544
|
+
<style>
|
|
545
|
+
@layer components {
|
|
546
|
+
:global(:where(.lc-highlight-area)) {
|
|
547
|
+
--fill-color: color-mix(in oklab, var(--color-surface-content, currentColor) 5%, transparent);
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
:global(:where(.lc-highlight-bar)) {
|
|
551
|
+
--fill-color: var(--color-primary, currentColor);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
:global(:where(.lc-highlight-line)) {
|
|
555
|
+
--stroke-color: color-mix(
|
|
556
|
+
in oklab,
|
|
557
|
+
var(--color-surface-content, currentColor) 20%,
|
|
558
|
+
transparent
|
|
559
|
+
);
|
|
560
|
+
stroke-width: 2;
|
|
561
|
+
stroke-dasharray: 2 2;
|
|
562
|
+
pointer-events: none;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
:global(:where(.lc-highlight-point)) {
|
|
566
|
+
--stroke-color: white;
|
|
567
|
+
--fill-color: var(--color-primary, currentColor);
|
|
568
|
+
paint-order: stroke;
|
|
569
|
+
filter: drop-shadow(var(--drop-shadow-sm, 0 1px 2px rgb(0 0 0 / 0.15)));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
</style>
|
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
import Spline from './Spline.svelte';
|
|
66
66
|
import { getChartContext } from './Chart.svelte';
|
|
67
67
|
import { getGeoContext } from './GeoContext.svelte';
|
|
68
|
-
import { layerClass } from '../utils/attributes.js';
|
|
69
68
|
|
|
70
69
|
let {
|
|
71
70
|
data,
|
|
@@ -104,13 +103,13 @@
|
|
|
104
103
|
);
|
|
105
104
|
</script>
|
|
106
105
|
|
|
107
|
-
<Group {...restProps} class={cls(
|
|
106
|
+
<Group {...restProps} class={cls('lc-hull-g', classes.root, className)} bind:ref>
|
|
108
107
|
{#if geoCtx.projection}
|
|
109
108
|
{@const polygon = geoVoronoi().hull(points)}
|
|
110
109
|
<GeoPath
|
|
111
110
|
geojson={polygon}
|
|
112
111
|
{curve}
|
|
113
|
-
class={
|
|
112
|
+
class={['lc-hull-path', classes.path]}
|
|
114
113
|
onclick={(e) => onclick?.(e, { points, polygon })}
|
|
115
114
|
onpointermove={(e) => onpointermove?.(e, { points, polygon })}
|
|
116
115
|
{onpointerleave}
|
|
@@ -123,10 +122,18 @@
|
|
|
123
122
|
x={(d) => d[0]}
|
|
124
123
|
y={(d) => d[1]}
|
|
125
124
|
{curve}
|
|
126
|
-
class={
|
|
125
|
+
class={['lc-hull-class', classes.path]}
|
|
127
126
|
onclick={(e) => onclick?.(e, { points, polygon })}
|
|
128
127
|
onpointermove={(e) => onpointermove?.(e, { points, polygon })}
|
|
129
128
|
{onpointerleave}
|
|
130
129
|
/>
|
|
131
130
|
{/if}
|
|
132
131
|
</Group>
|
|
132
|
+
|
|
133
|
+
<style>
|
|
134
|
+
@layer components {
|
|
135
|
+
:global(:where(.lc-hull-path, .lc-hull-geo-path)) {
|
|
136
|
+
fill: transparent;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
</style>
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
import { isScaleBand } from '../utils/scales.svelte.js';
|
|
75
75
|
import { getChartContext } from './Chart.svelte';
|
|
76
76
|
import Group from './Group.svelte';
|
|
77
|
-
import { extractLayerProps
|
|
77
|
+
import { extractLayerProps } from '../utils/attributes.js';
|
|
78
78
|
|
|
79
79
|
const ctx = getChartContext();
|
|
80
80
|
|
|
@@ -174,28 +174,38 @@
|
|
|
174
174
|
}
|
|
175
175
|
</script>
|
|
176
176
|
|
|
177
|
-
<Group class=
|
|
177
|
+
<Group class="lc-labels-g">
|
|
178
178
|
<Points {data} {x} {y}>
|
|
179
179
|
{#snippet children({ points })}
|
|
180
180
|
{#each points as point, i (key(point.data, i))}
|
|
181
|
-
{@const textProps = extractLayerProps(getTextProps(point), 'labels-text')}
|
|
181
|
+
{@const textProps = extractLayerProps(getTextProps(point), 'lc-labels-text')}
|
|
182
182
|
{#if childrenProp}
|
|
183
183
|
{@render childrenProp({ data: point, textProps })}
|
|
184
184
|
{:else}
|
|
185
185
|
<Text
|
|
186
|
+
data-placement={placement}
|
|
186
187
|
{...textProps}
|
|
187
188
|
{...restProps}
|
|
188
|
-
|
|
189
|
-
'text-xs',
|
|
190
|
-
placement === 'inside'
|
|
191
|
-
? 'fill-surface-300 stroke-surface-content'
|
|
192
|
-
: 'fill-surface-content stroke-surface-100',
|
|
193
|
-
textProps.class,
|
|
194
|
-
className
|
|
195
|
-
)}
|
|
189
|
+
{...extractLayerProps(getTextProps(point), 'lc-labels-text', className ?? '')}
|
|
196
190
|
/>
|
|
197
191
|
{/if}
|
|
198
192
|
{/each}
|
|
199
193
|
{/snippet}
|
|
200
194
|
</Points>
|
|
201
195
|
</Group>
|
|
196
|
+
|
|
197
|
+
<style>
|
|
198
|
+
@layer components {
|
|
199
|
+
:global(:where(.lc-labels-text)) {
|
|
200
|
+
font-size: 12px;
|
|
201
|
+
|
|
202
|
+
--fill-color: var(--color-surface-content, currentColor);
|
|
203
|
+
--stroke-color: var(--color-surface-100, light-dark(white, black));
|
|
204
|
+
|
|
205
|
+
&[data-placement='inside'] {
|
|
206
|
+
--fill-color: var(--color-surface-100, light-dark(white, black));
|
|
207
|
+
--stroke-color: var(--color-surface-content, currentColor);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
</style>
|
|
@@ -56,10 +56,17 @@ export type LabelsPropsWithoutHTML<T = any> = {
|
|
|
56
56
|
}]>;
|
|
57
57
|
};
|
|
58
58
|
export type LabelsProps<T = any> = LabelsPropsWithoutHTML<T> & Without<TextProps, LabelsPropsWithoutHTML<T>>;
|
|
59
|
+
declare function $$render<TData = any>(): {
|
|
60
|
+
props: LabelsProps<TData>;
|
|
61
|
+
exports: {};
|
|
62
|
+
bindings: "";
|
|
63
|
+
slots: {};
|
|
64
|
+
events: {};
|
|
65
|
+
};
|
|
59
66
|
declare class __sveltets_Render<TData = any> {
|
|
60
|
-
props():
|
|
61
|
-
events():
|
|
62
|
-
slots():
|
|
67
|
+
props(): ReturnType<typeof $$render<TData>>['props'];
|
|
68
|
+
events(): ReturnType<typeof $$render<TData>>['events'];
|
|
69
|
+
slots(): ReturnType<typeof $$render<TData>>['slots'];
|
|
63
70
|
bindings(): "";
|
|
64
71
|
exports(): {};
|
|
65
72
|
}
|
|
@@ -65,10 +65,6 @@
|
|
|
65
65
|
*/
|
|
66
66
|
orientation?: 'horizontal' | 'vertical';
|
|
67
67
|
|
|
68
|
-
onclick?: (e: MouseEvent, detail: LegendItem) => any;
|
|
69
|
-
onpointerenter?: (e: MouseEvent, detail: LegendItem) => any;
|
|
70
|
-
onpointerleave?: (e: MouseEvent, detail: LegendItem) => any;
|
|
71
|
-
|
|
72
68
|
/**
|
|
73
69
|
* Determine display ramp (individual color swatches or continuous ramp)
|
|
74
70
|
*
|
|
@@ -76,6 +72,11 @@
|
|
|
76
72
|
*/
|
|
77
73
|
variant?: 'ramp' | 'swatches';
|
|
78
74
|
|
|
75
|
+
/**
|
|
76
|
+
* An array of selected items. If provided, the legend fades unselected items.
|
|
77
|
+
*/
|
|
78
|
+
selected?: string[];
|
|
79
|
+
|
|
79
80
|
/**
|
|
80
81
|
* Classes to apply to the elements.
|
|
81
82
|
*
|
|
@@ -91,6 +92,10 @@
|
|
|
91
92
|
item?: string | ((item: LegendItem) => string);
|
|
92
93
|
};
|
|
93
94
|
|
|
95
|
+
onclick?: (e: MouseEvent, detail: LegendItem) => any;
|
|
96
|
+
onpointerenter?: (e: MouseEvent, detail: LegendItem) => any;
|
|
97
|
+
onpointerleave?: (e: MouseEvent, detail: LegendItem) => any;
|
|
98
|
+
|
|
94
99
|
/**
|
|
95
100
|
* A bindable reference to the wrapping `<div>` element.
|
|
96
101
|
*
|
|
@@ -116,7 +121,8 @@
|
|
|
116
121
|
import { cls } from '@layerstack/tailwind';
|
|
117
122
|
import type { AnyScale } from '../utils/scales.svelte.js';
|
|
118
123
|
import { getChartContext } from './Chart.svelte';
|
|
119
|
-
import { extractLayerProps
|
|
124
|
+
import { extractLayerProps } from '../utils/attributes.js';
|
|
125
|
+
import { resolveMaybeFn } from '../utils/common.js';
|
|
120
126
|
|
|
121
127
|
let {
|
|
122
128
|
scale: scaleProp,
|
|
@@ -134,6 +140,7 @@
|
|
|
134
140
|
onpointerenter,
|
|
135
141
|
onpointerleave,
|
|
136
142
|
variant = 'ramp',
|
|
143
|
+
selected = [],
|
|
137
144
|
classes = {},
|
|
138
145
|
ref: refProp = $bindable(),
|
|
139
146
|
class: className,
|
|
@@ -296,29 +303,9 @@
|
|
|
296
303
|
bind:this={ref}
|
|
297
304
|
{...restProps}
|
|
298
305
|
data-placement={placement}
|
|
299
|
-
class={cls(
|
|
300
|
-
layerClass('legend-container'),
|
|
301
|
-
'inline-block',
|
|
302
|
-
'z-1', // stack above tooltip context layers (band rects, voronoi, ...)
|
|
303
|
-
placement && [
|
|
304
|
-
'absolute',
|
|
305
|
-
{
|
|
306
|
-
'top-left': 'top-0 left-0',
|
|
307
|
-
top: 'top-0 left-1/2 -translate-x-1/2',
|
|
308
|
-
'top-right': 'top-0 right-0',
|
|
309
|
-
left: 'top-1/2 left-0 -translate-y-1/2',
|
|
310
|
-
center: 'top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2',
|
|
311
|
-
right: 'top-1/2 right-0 -translate-y-1/2',
|
|
312
|
-
'bottom-left': 'bottom-0 left-0',
|
|
313
|
-
bottom: 'bottom-0 left-1/2 -translate-x-1/2',
|
|
314
|
-
'bottom-right': 'bottom-0 right-0',
|
|
315
|
-
}[placement],
|
|
316
|
-
],
|
|
317
|
-
className,
|
|
318
|
-
classes.root
|
|
319
|
-
)}
|
|
306
|
+
class={cls('lc-legend-container', className, classes.root)}
|
|
320
307
|
>
|
|
321
|
-
<div class={cls(
|
|
308
|
+
<div class={cls('lc-legend-title', classes.title)}>
|
|
322
309
|
{title}
|
|
323
310
|
</div>
|
|
324
311
|
{#if children}
|
|
@@ -331,35 +318,31 @@
|
|
|
331
318
|
{width}
|
|
332
319
|
height={height + tickLengthProp + tickFontSize}
|
|
333
320
|
viewBox="0 0 {width} {height + tickLengthProp + tickFontSize}"
|
|
334
|
-
class={cls(
|
|
321
|
+
class={cls('lc-legend-ramp-svg')}
|
|
335
322
|
>
|
|
336
|
-
<g class=
|
|
323
|
+
<g class="lc-legend-ramp-g">
|
|
337
324
|
{#if scaleConfig.interpolator}
|
|
338
325
|
<ColorRamp
|
|
339
326
|
{width}
|
|
340
327
|
{height}
|
|
341
328
|
interpolator={scaleConfig.interpolator}
|
|
342
|
-
class=
|
|
329
|
+
class="lc-legend-color-ramp"
|
|
343
330
|
/>
|
|
344
331
|
{:else if scaleConfig.swatches}
|
|
345
332
|
{#each scaleConfig.swatches as swatch, i}
|
|
346
|
-
<rect {...extractLayerProps(swatch, 'legend-swatch')} />
|
|
333
|
+
<rect {...extractLayerProps(swatch, 'lc-legend-ramp-swatch')} />
|
|
347
334
|
{/each}
|
|
348
335
|
{/if}
|
|
349
336
|
</g>
|
|
350
337
|
|
|
351
|
-
<g class=
|
|
338
|
+
<g class="lc-legend-tick-group">
|
|
352
339
|
{#each tickValuesProp ?? scaleConfig.xScale?.ticks?.(ticks) ?? [] as tick, i}
|
|
353
340
|
<text
|
|
354
341
|
text-anchor="middle"
|
|
355
342
|
x={scaleConfig.xScale?.(tick) + scaleConfig.tickLabelOffset}
|
|
356
343
|
y={height + tickLengthProp + tickFontSize}
|
|
357
344
|
style:font-size={tickFontSize}
|
|
358
|
-
class={cls(
|
|
359
|
-
layerClass('legend-tick-text'),
|
|
360
|
-
'text-[10px] fill-surface-content',
|
|
361
|
-
classes.label
|
|
362
|
-
)}
|
|
345
|
+
class={cls('lc-legend-tick-text', classes.label)}
|
|
363
346
|
>
|
|
364
347
|
<!-- @ts-expect-error - improve types -->
|
|
365
348
|
{tickFormatProp ? format(tick, asAny(tickFormatProp)) : tick}
|
|
@@ -371,50 +354,26 @@
|
|
|
371
354
|
y1={0}
|
|
372
355
|
x2={scaleConfig.xScale?.(tick)}
|
|
373
356
|
y2={height + tickLengthProp}
|
|
374
|
-
class={cls(
|
|
357
|
+
class={cls('lc-legend-tick-line', classes.tick)}
|
|
375
358
|
/>
|
|
376
359
|
{/if}
|
|
377
360
|
{/each}
|
|
378
361
|
</g>
|
|
379
362
|
</svg>
|
|
380
363
|
{:else if variant === 'swatches'}
|
|
381
|
-
<div
|
|
382
|
-
class={cls(
|
|
383
|
-
layerClass('legend-swatch-group'),
|
|
384
|
-
'flex gap-x-4 gap-y-1',
|
|
385
|
-
orientation === 'vertical' && 'flex-col',
|
|
386
|
-
classes.items
|
|
387
|
-
)}
|
|
388
|
-
>
|
|
364
|
+
<div class={cls('lc-legend-swatch-group', classes.items)} data-orientation={orientation}>
|
|
389
365
|
{#each scaleConfig.tickValues ?? scaleConfig.xScale?.ticks?.(ticks) ?? [] as tick}
|
|
390
366
|
{@const color = scale?.(tick) ?? ''}
|
|
391
367
|
{@const item = { value: tick, color }}
|
|
392
368
|
<button
|
|
393
|
-
class={cls(
|
|
394
|
-
|
|
395
|
-
'flex items-center gap-1 truncate',
|
|
396
|
-
!onclick && 'cursor-auto',
|
|
397
|
-
typeof classes.item === 'function' ? classes.item(item) : classes.item
|
|
398
|
-
)}
|
|
369
|
+
class={cls('lc-legend-swatch-button', resolveMaybeFn(classes?.item, item))}
|
|
370
|
+
style:opacity={selected.length === 0 || selected.includes(tick) ? 1 : 0.3}
|
|
399
371
|
onclick={(e) => onclick?.(e, item)}
|
|
400
372
|
onpointerenter={(e) => onpointerenter?.(e, item)}
|
|
401
373
|
onpointerleave={(e) => onpointerleave?.(e, item)}
|
|
402
374
|
>
|
|
403
|
-
<div
|
|
404
|
-
|
|
405
|
-
layerClass('legend-swatch'),
|
|
406
|
-
'h-4 w-4 shrink-0 rounded-full',
|
|
407
|
-
classes.swatch
|
|
408
|
-
)}
|
|
409
|
-
style:background-color={color}
|
|
410
|
-
></div>
|
|
411
|
-
<div
|
|
412
|
-
class={cls(
|
|
413
|
-
layerClass('legend-swatch-label'),
|
|
414
|
-
'text-xs text-surface-content truncate whitespace-nowrap',
|
|
415
|
-
classes.label
|
|
416
|
-
)}
|
|
417
|
-
>
|
|
375
|
+
<div class={cls('lc-legend-swatch', classes.swatch)} style:background-color={color}></div>
|
|
376
|
+
<div class={cls('lc-legend-swatch-label', classes.label)}>
|
|
418
377
|
<!-- @ts-expect-error - improve types -->
|
|
419
378
|
{tickFormatProp ? format(tick, asAny(tickFormatProp)) : tick}
|
|
420
379
|
</div>
|
|
@@ -423,3 +382,110 @@
|
|
|
423
382
|
</div>
|
|
424
383
|
{/if}
|
|
425
384
|
</div>
|
|
385
|
+
|
|
386
|
+
<style>
|
|
387
|
+
@layer components {
|
|
388
|
+
:where(.lc-legend-container) {
|
|
389
|
+
display: inline-block;
|
|
390
|
+
z-index: 1; /*stack above tooltip context layers (band rects, voronoi, ...) */
|
|
391
|
+
|
|
392
|
+
&[data-placement] {
|
|
393
|
+
position: absolute;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
&[data-placement='top-left'] {
|
|
397
|
+
top: 0;
|
|
398
|
+
left: 0;
|
|
399
|
+
}
|
|
400
|
+
&[data-placement='top'] {
|
|
401
|
+
top: 0;
|
|
402
|
+
left: 50%;
|
|
403
|
+
transform: translateX(-50%);
|
|
404
|
+
}
|
|
405
|
+
&[data-placement='top-right'] {
|
|
406
|
+
top: 0;
|
|
407
|
+
right: 0;
|
|
408
|
+
}
|
|
409
|
+
&[data-placement='left'] {
|
|
410
|
+
top: 50%;
|
|
411
|
+
left: 0;
|
|
412
|
+
transform: translateY(-50%);
|
|
413
|
+
}
|
|
414
|
+
&[data-placement='center'] {
|
|
415
|
+
top: 50%;
|
|
416
|
+
left: 50%;
|
|
417
|
+
transform: translate(-50%, -50%);
|
|
418
|
+
}
|
|
419
|
+
&[data-placement='right'] {
|
|
420
|
+
top: 50%;
|
|
421
|
+
right: 0;
|
|
422
|
+
transform: translateY(-50%);
|
|
423
|
+
}
|
|
424
|
+
&[data-placement='bottom-left'] {
|
|
425
|
+
bottom: 0;
|
|
426
|
+
left: 0;
|
|
427
|
+
}
|
|
428
|
+
&[data-placement='bottom'] {
|
|
429
|
+
bottom: 0;
|
|
430
|
+
left: 50%;
|
|
431
|
+
transform: translateX(-50%);
|
|
432
|
+
}
|
|
433
|
+
&[data-placement='bottom-right'] {
|
|
434
|
+
bottom: 0;
|
|
435
|
+
right: 0;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
:where(.lc-legend-title) {
|
|
440
|
+
font-size: 10px;
|
|
441
|
+
font-weight: 600;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
:where(.lc-legend-ramp-svg) {
|
|
445
|
+
overflow: visible;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
:where(.lc-legend-tick-text) {
|
|
449
|
+
font-size: 10px;
|
|
450
|
+
fill: var(--color-surface-content, currentColor);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
:where(.lc-legend-tick-line) {
|
|
454
|
+
stroke: var(--color-surface-content, currentColor);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
:where(.lc-legend-swatch-group) {
|
|
458
|
+
display: flex;
|
|
459
|
+
gap: 0.25rem 1rem;
|
|
460
|
+
|
|
461
|
+
&[data-orientation='vertical'] {
|
|
462
|
+
flex-direction: column;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
:where(.lc-legend-swatch-button) {
|
|
467
|
+
display: flex;
|
|
468
|
+
align-items: center;
|
|
469
|
+
gap: 0.25rem;
|
|
470
|
+
white-space: nowrap;
|
|
471
|
+
overflow: hidden;
|
|
472
|
+
text-overflow: ellipsis;
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
:where(.lc-legend-swatch) {
|
|
476
|
+
width: 16px;
|
|
477
|
+
height: 16px;
|
|
478
|
+
flex-shrink: 0;
|
|
479
|
+
border-radius: 9999px; /* full */
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
:where(.lc-legend-swatch-label) {
|
|
483
|
+
font-size: 0.75rem; /* text-xs */
|
|
484
|
+
line-height: calc(1 / 0.75);
|
|
485
|
+
color: var(--color-surface-content, currentColor);
|
|
486
|
+
overflow: hidden;
|
|
487
|
+
text-overflow: ellipsis;
|
|
488
|
+
white-space: nowrap;
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
</style>
|
|
@@ -54,15 +54,16 @@ export type LegendPropsWithoutHTML = {
|
|
|
54
54
|
* @default 'horizontal'
|
|
55
55
|
*/
|
|
56
56
|
orientation?: 'horizontal' | 'vertical';
|
|
57
|
-
onclick?: (e: MouseEvent, detail: LegendItem) => any;
|
|
58
|
-
onpointerenter?: (e: MouseEvent, detail: LegendItem) => any;
|
|
59
|
-
onpointerleave?: (e: MouseEvent, detail: LegendItem) => any;
|
|
60
57
|
/**
|
|
61
58
|
* Determine display ramp (individual color swatches or continuous ramp)
|
|
62
59
|
*
|
|
63
60
|
* @default 'ramp'
|
|
64
61
|
*/
|
|
65
62
|
variant?: 'ramp' | 'swatches';
|
|
63
|
+
/**
|
|
64
|
+
* An array of selected items. If provided, the legend fades unselected items.
|
|
65
|
+
*/
|
|
66
|
+
selected?: string[];
|
|
66
67
|
/**
|
|
67
68
|
* Classes to apply to the elements.
|
|
68
69
|
*
|
|
@@ -77,6 +78,9 @@ export type LegendPropsWithoutHTML = {
|
|
|
77
78
|
swatch?: string;
|
|
78
79
|
item?: string | ((item: LegendItem) => string);
|
|
79
80
|
};
|
|
81
|
+
onclick?: (e: MouseEvent, detail: LegendItem) => any;
|
|
82
|
+
onpointerenter?: (e: MouseEvent, detail: LegendItem) => any;
|
|
83
|
+
onpointerleave?: (e: MouseEvent, detail: LegendItem) => any;
|
|
80
84
|
/**
|
|
81
85
|
* A bindable reference to the wrapping `<div>` element.
|
|
82
86
|
*
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { renderPathData, type ComputedStylesOptions } from '../utils/canvas.js';
|
|
5
5
|
import MarkerWrapper, { type MarkerOptions } from './MarkerWrapper.svelte';
|
|
6
6
|
import type { CommonStyleProps, Without } from '../utils/types.js';
|
|
7
|
+
import { pointsToAngleAndLength } from '../utils/math.js';
|
|
7
8
|
|
|
8
9
|
export type LinePropsWithoutHTML = {
|
|
9
10
|
/**
|
|
@@ -98,7 +99,6 @@
|
|
|
98
99
|
|
|
99
100
|
import { createKey } from '../utils/key.svelte.js';
|
|
100
101
|
import { createId } from '../utils/createId.js';
|
|
101
|
-
import { layerClass } from '../utils/attributes.js';
|
|
102
102
|
|
|
103
103
|
const uid = $props.id();
|
|
104
104
|
|
|
@@ -148,7 +148,7 @@
|
|
|
148
148
|
? merge({ styles: { strokeWidth } }, styleOverrides)
|
|
149
149
|
: {
|
|
150
150
|
styles: { fill, stroke, strokeWidth, opacity },
|
|
151
|
-
classes: className,
|
|
151
|
+
classes: cls('lc-line', className),
|
|
152
152
|
}
|
|
153
153
|
);
|
|
154
154
|
}
|
|
@@ -195,10 +195,47 @@
|
|
|
195
195
|
marker-start={markerStartId ? `url(#${markerStartId})` : undefined}
|
|
196
196
|
marker-mid={markerMidId ? `url(#${markerMidId})` : undefined}
|
|
197
197
|
marker-end={markerEndId ? `url(#${markerEndId})` : undefined}
|
|
198
|
-
class={cls(
|
|
198
|
+
class={cls('lc-line', className)}
|
|
199
199
|
{...restProps}
|
|
200
200
|
/>
|
|
201
201
|
<MarkerWrapper id={markerStartId} marker={markerStart ?? marker} />
|
|
202
202
|
<MarkerWrapper id={markerMidId} marker={markerMid ?? marker} />
|
|
203
203
|
<MarkerWrapper id={markerEndId} marker={markerEnd ?? marker} />
|
|
204
|
+
{:else if renderCtx === 'html'}
|
|
205
|
+
{@const { angle, length } = pointsToAngleAndLength(
|
|
206
|
+
{ x: motionX1.current, y: motionY1.current },
|
|
207
|
+
{ x: motionX2.current, y: motionY2.current }
|
|
208
|
+
)}
|
|
209
|
+
<!-- STYLE-TODO: Should html use stroke for fill? -->
|
|
210
|
+
<div
|
|
211
|
+
style:position="absolute"
|
|
212
|
+
style:left="{motionX1.current}px"
|
|
213
|
+
style:top="{motionY1.current}px"
|
|
214
|
+
style:width="{length}px"
|
|
215
|
+
style:height="{strokeWidth ?? 1}px"
|
|
216
|
+
style:transform="translateY(-50%) rotate({angle}deg)"
|
|
217
|
+
style:transform-origin="0 50%"
|
|
218
|
+
style:opacity
|
|
219
|
+
style:background-color={stroke}
|
|
220
|
+
class={cls('lc-line', className)}
|
|
221
|
+
style={restProps.style}
|
|
222
|
+
></div>
|
|
204
223
|
{/if}
|
|
224
|
+
|
|
225
|
+
<style>
|
|
226
|
+
@layer base {
|
|
227
|
+
:global(:where(.lc-line)) {
|
|
228
|
+
--stroke-color: var(--color-surface-content, currentColor);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* Svg | Canvas layers */
|
|
232
|
+
:global(:where(.lc-layout-svg .lc-line, svg.lc-line):not([stroke])) {
|
|
233
|
+
stroke: var(--stroke-color);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/* Html layers */
|
|
237
|
+
:global(:where(.lc-layout-html .lc-line):not([background-color])) {
|
|
238
|
+
background-color: var(--stroke-color);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
</style>
|