layerchart 2.0.0-next.38 → 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/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/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/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/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/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/Pattern.svelte +5 -5
- package/dist/components/Pie.svelte +1 -2
- package/dist/components/Points.svelte +1 -1
- 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/Voronoi.svelte +12 -13
- package/dist/components/charts/ArcChart.svelte +40 -69
- package/dist/components/charts/AreaChart.svelte +19 -42
- package/dist/components/charts/BarChart.svelte +7 -18
- 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 +11 -5
- package/dist/components/charts/PieChart.svelte +41 -69
- package/dist/components/charts/ScatterChart.svelte +8 -19
- 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/TooltipContext.svelte +73 -36
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +7 -0
- 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/math.d.ts +17 -0
- package/dist/utils/math.js +17 -0
- package/dist/utils/types.d.ts +15 -2
- package/package.json +5 -1
|
@@ -56,7 +56,6 @@
|
|
|
56
56
|
<script lang="ts">
|
|
57
57
|
import { format as formatUtil, type FormatType, type FormatConfig } from '@layerstack/utils';
|
|
58
58
|
import { cls } from '@layerstack/tailwind';
|
|
59
|
-
import { layerClass } from '../../utils/attributes.js';
|
|
60
59
|
|
|
61
60
|
let {
|
|
62
61
|
ref: refProp = $bindable(),
|
|
@@ -89,25 +88,14 @@
|
|
|
89
88
|
</script>
|
|
90
89
|
|
|
91
90
|
<div
|
|
92
|
-
class={cls(
|
|
93
|
-
layerClass('tooltip-header'),
|
|
94
|
-
'font-semibold whitespace-nowrap border-b mb-1 pb-1 flex items-center gap-2',
|
|
95
|
-
classes.root,
|
|
96
|
-
props.root?.class,
|
|
97
|
-
className
|
|
98
|
-
)}
|
|
91
|
+
class={cls('lc-tooltip-header', classes.root, props.root?.class, className)}
|
|
99
92
|
{...restProps}
|
|
100
93
|
bind:this={ref}
|
|
101
94
|
>
|
|
102
95
|
{#if color}
|
|
103
96
|
<div
|
|
104
97
|
bind:this={colorRef}
|
|
105
|
-
class={cls(
|
|
106
|
-
layerClass('tooltip-header-color'),
|
|
107
|
-
'color',
|
|
108
|
-
'inline-block size-2 rounded-full bg-[var(--color)]',
|
|
109
|
-
classes.color
|
|
110
|
-
)}
|
|
98
|
+
class={cls('lc-tooltip-header-color', classes.color)}
|
|
111
99
|
style:--color={color}
|
|
112
100
|
></div>
|
|
113
101
|
{/if}
|
|
@@ -118,3 +106,28 @@
|
|
|
118
106
|
{format ? formatUtil(value, asAny(format)) : value}
|
|
119
107
|
{/if}
|
|
120
108
|
</div>
|
|
109
|
+
|
|
110
|
+
<style>
|
|
111
|
+
@layer component {
|
|
112
|
+
:where(.lc-tooltip-header) {
|
|
113
|
+
font-weight: 600;
|
|
114
|
+
white-space: nowrap;
|
|
115
|
+
border-bottom: 1px solid
|
|
116
|
+
color-mix(in oklab, var(--color-surface-content, currentColor) 20%, transparent);
|
|
117
|
+
margin-bottom: 4px;
|
|
118
|
+
padding-bottom: 4px;
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: center;
|
|
121
|
+
gap: 8px;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
:where(.lc-tooltip-header-color) {
|
|
125
|
+
display: inline-block;
|
|
126
|
+
width: 8px;
|
|
127
|
+
height: 8px;
|
|
128
|
+
border-radius: 9999px; /* rounded-full */
|
|
129
|
+
background-color: var(--color);
|
|
130
|
+
flex-shrink: 0;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
</style>
|
|
@@ -78,7 +78,6 @@
|
|
|
78
78
|
import { format as formatUtil, type FormatType, type FormatConfig } from '@layerstack/utils';
|
|
79
79
|
import { cls } from '@layerstack/tailwind';
|
|
80
80
|
import type { Snippet } from 'svelte';
|
|
81
|
-
import { layerClass } from '../../utils/attributes.js';
|
|
82
81
|
|
|
83
82
|
let {
|
|
84
83
|
ref: refProp = $bindable(),
|
|
@@ -129,37 +128,19 @@
|
|
|
129
128
|
|
|
130
129
|
<div
|
|
131
130
|
{...props.root}
|
|
132
|
-
class={cls(
|
|
133
|
-
layerClass('tooltip-item-root'),
|
|
134
|
-
'contents',
|
|
135
|
-
classes.root,
|
|
136
|
-
className,
|
|
137
|
-
props.root?.class
|
|
138
|
-
)}
|
|
131
|
+
class={cls('lc-tooltip-item-root', classes.root, className, props.root?.class)}
|
|
139
132
|
{...restProps}
|
|
140
133
|
bind:this={ref}
|
|
141
134
|
>
|
|
142
135
|
<div
|
|
143
136
|
{...props.label}
|
|
144
|
-
class={cls(
|
|
145
|
-
layerClass('tooltip-item-label'),
|
|
146
|
-
'label',
|
|
147
|
-
'flex items-center gap-2 whitespace-nowrap',
|
|
148
|
-
classes.label,
|
|
149
|
-
props.label?.class
|
|
150
|
-
)}
|
|
137
|
+
class={cls('lc-tooltip-item-label', 'label', classes.label, props.label?.class)}
|
|
151
138
|
bind:this={labelRef}
|
|
152
139
|
>
|
|
153
140
|
{#if color}
|
|
154
141
|
<div
|
|
155
142
|
{...props.color}
|
|
156
|
-
class={cls(
|
|
157
|
-
layerClass('tooltip-item-color'),
|
|
158
|
-
'color',
|
|
159
|
-
'inline-block size-2 rounded-full bg-[var(--color)]',
|
|
160
|
-
classes.color,
|
|
161
|
-
props.color?.class
|
|
162
|
-
)}
|
|
143
|
+
class={cls('lc-tooltip-item-color', 'color', classes.color, props.color?.class)}
|
|
163
144
|
style:--color={color}
|
|
164
145
|
bind:this={colorRef}
|
|
165
146
|
></div>
|
|
@@ -174,17 +155,8 @@
|
|
|
174
155
|
<div
|
|
175
156
|
bind:this={valueRef}
|
|
176
157
|
{...props.value}
|
|
177
|
-
class={cls(
|
|
178
|
-
|
|
179
|
-
'value',
|
|
180
|
-
'tabular-nums',
|
|
181
|
-
{
|
|
182
|
-
'text-right': valueAlign === 'right',
|
|
183
|
-
'text-center': valueAlign === 'center',
|
|
184
|
-
},
|
|
185
|
-
classes.value,
|
|
186
|
-
props.value?.class
|
|
187
|
-
)}
|
|
158
|
+
class={cls('lc-tooltip-item-value', 'value', classes.value, props.value?.class)}
|
|
159
|
+
data-align={valueAlign}
|
|
188
160
|
>
|
|
189
161
|
{#if children}
|
|
190
162
|
{@render children()}
|
|
@@ -194,3 +166,39 @@
|
|
|
194
166
|
{/if}
|
|
195
167
|
</div>
|
|
196
168
|
</div>
|
|
169
|
+
|
|
170
|
+
<style>
|
|
171
|
+
@layer component {
|
|
172
|
+
:where(.lc-tooltip-item-root) {
|
|
173
|
+
display: contents;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
:where(.lc-tooltip-item-color) {
|
|
177
|
+
display: inline-block;
|
|
178
|
+
width: 8px;
|
|
179
|
+
height: 8px;
|
|
180
|
+
border-radius: 9999px; /* full */
|
|
181
|
+
background-color: var(--color);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
:where(.lc-tooltip-item-label) {
|
|
185
|
+
display: flex;
|
|
186
|
+
align-items: center;
|
|
187
|
+
gap: 8px;
|
|
188
|
+
white-space: nowrap;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
:where(.lc-tooltip-item-value) {
|
|
192
|
+
/* tabular-nums */
|
|
193
|
+
font-variant-numeric: tabular-nums;
|
|
194
|
+
|
|
195
|
+
&[data-align='right'] {
|
|
196
|
+
text-align: right;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
&[data-align='center'] {
|
|
200
|
+
text-align: center;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
</style>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { cls } from '@layerstack/tailwind';
|
|
3
|
-
import { layerClass } from '../../utils/attributes.js';
|
|
4
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
5
4
|
|
|
6
5
|
let {
|
|
@@ -19,14 +18,17 @@
|
|
|
19
18
|
});
|
|
20
19
|
</script>
|
|
21
20
|
|
|
22
|
-
<div
|
|
23
|
-
bind:this={ref}
|
|
24
|
-
class={cls(
|
|
25
|
-
layerClass('tooltip-list'),
|
|
26
|
-
'grid grid-cols-[1fr_auto] gap-x-2 gap-y-1 items-start',
|
|
27
|
-
className
|
|
28
|
-
)}
|
|
29
|
-
{...restProps}
|
|
30
|
-
>
|
|
21
|
+
<div bind:this={ref} class={cls('lc-tooltip-list', className)} {...restProps}>
|
|
31
22
|
{@render children?.()}
|
|
32
23
|
</div>
|
|
24
|
+
|
|
25
|
+
<style>
|
|
26
|
+
@layer component {
|
|
27
|
+
:where(.lc-tooltip-list) {
|
|
28
|
+
display: grid;
|
|
29
|
+
grid-template-columns: 1fr auto;
|
|
30
|
+
gap: 4px 8px;
|
|
31
|
+
align-items: start;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
</style>
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { cls } from '@layerstack/tailwind';
|
|
3
|
-
import { layerClass } from '../../utils/attributes.js';
|
|
4
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
5
4
|
|
|
6
5
|
let {
|
|
@@ -18,14 +17,23 @@
|
|
|
18
17
|
});
|
|
19
18
|
</script>
|
|
20
19
|
|
|
21
|
-
<div
|
|
22
|
-
bind:this={ref}
|
|
23
|
-
class={cls(
|
|
24
|
-
layerClass('tooltip-separator'),
|
|
25
|
-
'rounded-sm bg-surface-content/20 my-1 col-span-full h-px',
|
|
26
|
-
className
|
|
27
|
-
)}
|
|
28
|
-
{...restProps}
|
|
29
|
-
>
|
|
20
|
+
<div bind:this={ref} class={cls('lc-tooltip-separator', className)} {...restProps}>
|
|
30
21
|
{@render children?.()}
|
|
31
22
|
</div>
|
|
23
|
+
|
|
24
|
+
<style>
|
|
25
|
+
@layer component {
|
|
26
|
+
:where(.lc-tooltip-separator) {
|
|
27
|
+
height: 1px;
|
|
28
|
+
border-radius: 4px;
|
|
29
|
+
background-color: color-mix(
|
|
30
|
+
in oklab,
|
|
31
|
+
var(--color-surface-content, currentColor) 20%,
|
|
32
|
+
transparent
|
|
33
|
+
);
|
|
34
|
+
margin-top: 4px;
|
|
35
|
+
margin-bottom: 4px;
|
|
36
|
+
grid-column: 1 / -1; /* col-span-full */
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { Component } from 'svelte';
|
|
2
|
+
import type { SeriesData } from '../components/charts/types.js';
|
|
3
|
+
import { SelectionState } from '@layerstack/svelte-state';
|
|
4
|
+
declare class HighlightKey<TData, SeriesComponent extends Component> {
|
|
5
|
+
current: string | null;
|
|
6
|
+
set: (seriesKey: typeof this.current) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare class SeriesState<TData, TComponent extends Component> {
|
|
9
|
+
#private;
|
|
10
|
+
selectedKeys: SelectionState<string, false>;
|
|
11
|
+
highlightKey: HighlightKey<TData, TComponent>;
|
|
12
|
+
constructor(getSeries: () => SeriesData<TData, TComponent>[]);
|
|
13
|
+
get series(): SeriesData<TData, TComponent>[];
|
|
14
|
+
get isDefaultSeries(): boolean;
|
|
15
|
+
get visibleSeries(): SeriesData<TData, TComponent>[];
|
|
16
|
+
/**
|
|
17
|
+
* Check if series is visible
|
|
18
|
+
*/
|
|
19
|
+
isVisible(seriesKey: SeriesData<TData, TComponent>['key']): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Check if series is highlighted
|
|
22
|
+
* Changing default to `true` is useful to determine if series should be faded
|
|
23
|
+
*/
|
|
24
|
+
isHighlighted(seriesKey: SeriesData<TData, TComponent>['key'], defaultValue?: boolean): boolean;
|
|
25
|
+
get allSeriesData(): Array<TData & {
|
|
26
|
+
seriesKey: string;
|
|
27
|
+
}>;
|
|
28
|
+
get allSeriesColors(): Array<NonNullable<SeriesData<TData, TComponent>["color"]>>;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { SelectionState } from '@layerstack/svelte-state';
|
|
2
|
+
class HighlightKey {
|
|
3
|
+
current = $state(null);
|
|
4
|
+
set = (seriesKey) => {
|
|
5
|
+
this.current = seriesKey;
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
export class SeriesState {
|
|
9
|
+
#series = $state.raw([]);
|
|
10
|
+
selectedKeys = new SelectionState();
|
|
11
|
+
highlightKey = new HighlightKey();
|
|
12
|
+
constructor(getSeries) {
|
|
13
|
+
this.#series = getSeries();
|
|
14
|
+
$effect.pre(() => {
|
|
15
|
+
// keep series state in sync with the prop
|
|
16
|
+
this.#series = getSeries();
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
get series() {
|
|
20
|
+
return this.#series;
|
|
21
|
+
}
|
|
22
|
+
get isDefaultSeries() {
|
|
23
|
+
return this.#series.length === 1 && this.#series[0].key === 'default';
|
|
24
|
+
}
|
|
25
|
+
get visibleSeries() {
|
|
26
|
+
return this.#series.filter((s) => this.isVisible(s.key));
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Check if series is visible
|
|
30
|
+
*/
|
|
31
|
+
isVisible(seriesKey) {
|
|
32
|
+
return this.selectedKeys.isEmpty() || this.selectedKeys.isSelected(seriesKey);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check if series is highlighted
|
|
36
|
+
* Changing default to `true` is useful to determine if series should be faded
|
|
37
|
+
*/
|
|
38
|
+
isHighlighted(seriesKey, defaultValue = false) {
|
|
39
|
+
if (this.highlightKey.current === null) {
|
|
40
|
+
return defaultValue;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
return this.highlightKey.current === seriesKey;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
get allSeriesData() {
|
|
47
|
+
return this.#series
|
|
48
|
+
.flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d })))
|
|
49
|
+
.filter((d) => d);
|
|
50
|
+
}
|
|
51
|
+
get allSeriesColors() {
|
|
52
|
+
return this.#series.map((s) => s.color).filter((c) => c != null);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
When NOT using shadcn-svelte Chart component.
|
|
3
|
+
Not typically needed even when using built-in Chart, as defaults typically are sufficient
|
|
4
|
+
*/
|
|
5
|
+
.lc-root-container {
|
|
6
|
+
--color-primary: var(--primary);
|
|
7
|
+
--color-surface-100: var(--card-background);
|
|
8
|
+
--color-surface-200: var(--card-muted);
|
|
9
|
+
/* No direct mapping, should add explicit color (light and dark mode) */
|
|
10
|
+
--color-surface-content: var(--card-foreground);
|
|
11
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.lc-root-container {
|
|
2
|
+
--color-primary: var(--color-primary-500);
|
|
3
|
+
|
|
4
|
+
--color-surface-100: var(--color-surface-50);
|
|
5
|
+
--color-surface-200: var(--color-surface-100);
|
|
6
|
+
--color-surface-300: var(--color-surface-200);
|
|
7
|
+
--color-surface-content: var(--base-font-color);
|
|
8
|
+
|
|
9
|
+
html.dark & {
|
|
10
|
+
--color-surface-100: var(--color-surface-700);
|
|
11
|
+
--color-surface-200: var(--color-surface-800);
|
|
12
|
+
--color-surface-300: var(--color-surface-900);
|
|
13
|
+
--color-surface-content: var(--base-font-color-dark);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
* Creates a string containing a class name that can be used by
|
|
3
|
-
* developers to target a specific layer/element within a LayerChart.
|
|
4
|
-
*
|
|
5
|
-
* This is a function so that the class names remain consistent and the
|
|
6
|
-
* prefix/structure can be changed in the future if needed
|
|
7
|
-
*
|
|
8
|
-
* @param layerName - the name of the layer to be appended to the generated class name
|
|
9
|
-
* @returns a string to be used as a class on an element
|
|
10
|
-
*/
|
|
11
|
-
export declare function layerClass(layerName: string): string;
|
|
1
|
+
import type { ClassValue } from 'svelte/elements';
|
|
12
2
|
type ExtractObjectType<T> = T extends object ? (T extends Function ? never : T) : never;
|
|
13
3
|
type WithClass<T> = T & {
|
|
14
4
|
class?: string;
|
|
@@ -21,9 +11,9 @@ type DefaultProps = WithClass<{
|
|
|
21
11
|
* a class name to its class property to identify the layer for CSS targeting.
|
|
22
12
|
*
|
|
23
13
|
* @param props The props to be extracted, can be an object, function or any other type
|
|
24
|
-
* @param
|
|
14
|
+
* @param className The class name to be applied to the layer for targeting styling (e.g. 'lc-layer')
|
|
25
15
|
* @param extraClasses Additional classes to be applied to the layer if they don't exist in the props already
|
|
26
16
|
* @returns a typed spreadable object with props for the layer
|
|
27
17
|
*/
|
|
28
|
-
export declare function extractLayerProps<T>(props: T,
|
|
18
|
+
export declare function extractLayerProps<T>(props: T, className: string, ...extraClasses: ClassValue[]): WithClass<ExtractObjectType<T> extends never ? DefaultProps : ExtractObjectType<T>>;
|
|
29
19
|
export {};
|
package/dist/utils/attributes.js
CHANGED
|
@@ -1,17 +1,4 @@
|
|
|
1
1
|
import { cls } from '@layerstack/tailwind';
|
|
2
|
-
/**
|
|
3
|
-
* Creates a string containing a class name that can be used by
|
|
4
|
-
* developers to target a specific layer/element within a LayerChart.
|
|
5
|
-
*
|
|
6
|
-
* This is a function so that the class names remain consistent and the
|
|
7
|
-
* prefix/structure can be changed in the future if needed
|
|
8
|
-
*
|
|
9
|
-
* @param layerName - the name of the layer to be appended to the generated class name
|
|
10
|
-
* @returns a string to be used as a class on an element
|
|
11
|
-
*/
|
|
12
|
-
export function layerClass(layerName) {
|
|
13
|
-
return `lc-${layerName}`;
|
|
14
|
-
}
|
|
15
2
|
// type guard to narrow props to an object with optional class
|
|
16
3
|
// for extractLayerProps
|
|
17
4
|
function isObjectWithClass(val) {
|
|
@@ -22,19 +9,18 @@ function isObjectWithClass(val) {
|
|
|
22
9
|
* a class name to its class property to identify the layer for CSS targeting.
|
|
23
10
|
*
|
|
24
11
|
* @param props The props to be extracted, can be an object, function or any other type
|
|
25
|
-
* @param
|
|
12
|
+
* @param className The class name to be applied to the layer for targeting styling (e.g. 'lc-layer')
|
|
26
13
|
* @param extraClasses Additional classes to be applied to the layer if they don't exist in the props already
|
|
27
14
|
* @returns a typed spreadable object with props for the layer
|
|
28
15
|
*/
|
|
29
|
-
export function extractLayerProps(props,
|
|
30
|
-
const className = layerClass(layerName);
|
|
16
|
+
export function extractLayerProps(props, className, ...extraClasses) {
|
|
31
17
|
if (isObjectWithClass(props)) {
|
|
32
18
|
return {
|
|
33
19
|
...props,
|
|
34
|
-
class: cls(className, props.class
|
|
20
|
+
class: cls(className, ...extraClasses, props.class),
|
|
35
21
|
};
|
|
36
22
|
}
|
|
37
23
|
return {
|
|
38
|
-
class: cls(className, extraClasses),
|
|
24
|
+
class: cls(className, ...extraClasses),
|
|
39
25
|
};
|
|
40
26
|
}
|
package/dist/utils/common.d.ts
CHANGED
|
@@ -16,3 +16,12 @@ export declare function defaultChartPadding<TData, SeriesComponent extends Compo
|
|
|
16
16
|
* Handles complex objects such as `Date` by invoking `.valueOf()`
|
|
17
17
|
*/
|
|
18
18
|
export declare function findRelatedData(data: any[], original: any, accessor: Function): any;
|
|
19
|
+
/**
|
|
20
|
+
* Return the object if the value is an object, otherwise return null.
|
|
21
|
+
* Functions (including Snippet types) are treated as non-objects and return null.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getObjectOrNull<T>(value: T): T extends object ? T extends Function ? null : T : T extends null ? null : T extends undefined ? undefined : null;
|
|
24
|
+
/**
|
|
25
|
+
* Call with args if function, otherwise return the value.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resolveMaybeFn<T>(value: T | ((...args: any[]) => T), ...args: any[]): any;
|
package/dist/utils/common.js
CHANGED
|
@@ -40,7 +40,7 @@ export function defaultChartPadding(axis = true, legend = false) {
|
|
|
40
40
|
return {
|
|
41
41
|
top: axis === true || axis === 'y' ? 4 : 0,
|
|
42
42
|
left: axis === true || axis === 'y' ? 20 : 0,
|
|
43
|
-
bottom: (axis === true || axis === 'x' ? 20 : 0) + (legend
|
|
43
|
+
bottom: (axis === true || axis === 'x' ? 20 : 0) + (legend ? 32 : 0),
|
|
44
44
|
right: axis === true || axis === 'x' ? 4 : 0,
|
|
45
45
|
};
|
|
46
46
|
}
|
|
@@ -54,3 +54,20 @@ export function findRelatedData(data, original, accessor) {
|
|
|
54
54
|
return accessor(d)?.valueOf() === accessor(original)?.valueOf();
|
|
55
55
|
});
|
|
56
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Return the object if the value is an object, otherwise return null.
|
|
59
|
+
* Functions (including Snippet types) are treated as non-objects and return null.
|
|
60
|
+
*/
|
|
61
|
+
export function getObjectOrNull(value) {
|
|
62
|
+
if (typeof value === 'object')
|
|
63
|
+
return value;
|
|
64
|
+
if (value === undefined)
|
|
65
|
+
return undefined;
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Call with args if function, otherwise return the value.
|
|
70
|
+
*/
|
|
71
|
+
export function resolveMaybeFn(value, ...args) {
|
|
72
|
+
return typeof value === 'function' ? value(...args) : value;
|
|
73
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { accessor } from './common.js';
|
|
2
|
+
import { accessor, resolveMaybeFn, getObjectOrNull } from './common.js';
|
|
3
3
|
export const testData = {
|
|
4
4
|
one: 1,
|
|
5
5
|
two: 2,
|
|
@@ -36,3 +36,28 @@ describe('accessor', () => {
|
|
|
36
36
|
expect(actual).toEqual(testData);
|
|
37
37
|
});
|
|
38
38
|
});
|
|
39
|
+
describe('getObjectOrNull', () => {
|
|
40
|
+
it('returns null for non-object values', () => {
|
|
41
|
+
expect(getObjectOrNull(5)).toBeNull();
|
|
42
|
+
expect(getObjectOrNull('string')).toBeNull();
|
|
43
|
+
expect(getObjectOrNull(null)).toBeNull();
|
|
44
|
+
expect(getObjectOrNull(undefined)).toBeUndefined();
|
|
45
|
+
});
|
|
46
|
+
it('returns null for functions', () => {
|
|
47
|
+
const fn = () => { };
|
|
48
|
+
expect(getObjectOrNull(fn)).toBeNull();
|
|
49
|
+
});
|
|
50
|
+
it('returns the object if value is an object', () => {
|
|
51
|
+
const obj = { a: 1 };
|
|
52
|
+
expect(getObjectOrNull(obj)).toBe(obj);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
describe('resolveMaybeFn', () => {
|
|
56
|
+
it('returns value if not a function', () => {
|
|
57
|
+
expect(resolveMaybeFn(5)).toBe(5);
|
|
58
|
+
});
|
|
59
|
+
it('calls function with args', () => {
|
|
60
|
+
const fn = (a, b) => a + b;
|
|
61
|
+
expect(resolveMaybeFn(fn, 2, 3)).toBe(5);
|
|
62
|
+
});
|
|
63
|
+
});
|
package/dist/utils/math.d.ts
CHANGED
|
@@ -23,6 +23,23 @@ export declare function cartesianToPolar(x: number, y: number): {
|
|
|
23
23
|
radius: number;
|
|
24
24
|
radians: number;
|
|
25
25
|
};
|
|
26
|
+
/**
|
|
27
|
+
* Calculate the angle and length between two points
|
|
28
|
+
* @param point1 - First point
|
|
29
|
+
* @param point2 - Second point
|
|
30
|
+
* @returns Angle in degrees and length
|
|
31
|
+
*/
|
|
32
|
+
export declare function pointsToAngleAndLength(point1: {
|
|
33
|
+
x: number;
|
|
34
|
+
y: number;
|
|
35
|
+
}, point2: {
|
|
36
|
+
x: number;
|
|
37
|
+
y: number;
|
|
38
|
+
}): {
|
|
39
|
+
radians: number;
|
|
40
|
+
angle: number;
|
|
41
|
+
length: number;
|
|
42
|
+
};
|
|
26
43
|
/** Convert celsius temperature to fahrenheit */
|
|
27
44
|
export declare function celsiusToFahrenheit(temperature: number): number;
|
|
28
45
|
/** Convert fahrenheit temperature to celsius */
|
package/dist/utils/math.js
CHANGED
|
@@ -37,6 +37,23 @@ export function cartesianToPolar(x, y) {
|
|
|
37
37
|
radians,
|
|
38
38
|
};
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Calculate the angle and length between two points
|
|
42
|
+
* @param point1 - First point
|
|
43
|
+
* @param point2 - Second point
|
|
44
|
+
* @returns Angle in degrees and length
|
|
45
|
+
*/
|
|
46
|
+
export function pointsToAngleAndLength(point1, point2) {
|
|
47
|
+
const dx = point2.x - point1.x;
|
|
48
|
+
const dy = point2.y - point1.y;
|
|
49
|
+
const radians = Math.atan2(dy, dx);
|
|
50
|
+
const length = Math.sqrt(dx * dx + dy * dy);
|
|
51
|
+
return {
|
|
52
|
+
radians,
|
|
53
|
+
angle: radiansToDegrees(radians),
|
|
54
|
+
length,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
40
57
|
/** Convert celsius temperature to fahrenheit */
|
|
41
58
|
export function celsiusToFahrenheit(temperature) {
|
|
42
59
|
return temperature * (9 / 5) + 32;
|
package/dist/utils/types.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { MouseEventHandler, PointerEventHandler } from 'svelte/elements';
|
|
2
|
+
import type { TransitionConfig } from 'svelte/transition';
|
|
1
3
|
import type { HierarchyNode } from 'd3-hierarchy';
|
|
2
|
-
import type { AnyScale } from './scales.svelte.js';
|
|
3
4
|
import type { SankeyGraph } from 'd3-sankey';
|
|
4
|
-
import type {
|
|
5
|
+
import type { AnyScale } from './scales.svelte.js';
|
|
5
6
|
/**
|
|
6
7
|
* Useful to workaround Svelte 3/4 markup type issues
|
|
7
8
|
* TODO: Remove usage after migrating to Svelte 5
|
|
@@ -79,6 +80,18 @@ export type CommonStyleProps = {
|
|
|
79
80
|
*/
|
|
80
81
|
opacity?: number;
|
|
81
82
|
};
|
|
83
|
+
/**
|
|
84
|
+
* Events for primatives which support `SVGRectElement` and `HTMLDivElement` elements based on render context
|
|
85
|
+
*/
|
|
86
|
+
export type CommonEvents = {
|
|
87
|
+
onclick?: MouseEventHandler<Element> | null;
|
|
88
|
+
ondblclick?: MouseEventHandler<Element> | null;
|
|
89
|
+
onpointerenter?: PointerEventHandler<Element> | null;
|
|
90
|
+
onpointermove?: PointerEventHandler<Element> | null;
|
|
91
|
+
onpointerleave?: PointerEventHandler<Element> | null;
|
|
92
|
+
onpointerover?: PointerEventHandler<Element> | null;
|
|
93
|
+
onpointerout?: PointerEventHandler<Element> | null;
|
|
94
|
+
};
|
|
82
95
|
export type OnlyObjects<T> = T extends object ? T : never;
|
|
83
96
|
export type Getter<T> = () => T;
|
|
84
97
|
export type GetterValues<T> = {
|
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.
|
|
7
|
+
"version": "2.0.0-next.39",
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@changesets/cli": "^2.29.6",
|
|
10
10
|
"@iconify-json/lucide": "^1.2.62",
|
|
@@ -109,6 +109,10 @@
|
|
|
109
109
|
"types": "./dist/utils/*.d.ts",
|
|
110
110
|
"svelte": "./dist/utils/*.js",
|
|
111
111
|
"default": "./dist/utils/*.js"
|
|
112
|
+
},
|
|
113
|
+
"./*.css": {
|
|
114
|
+
"style": "./dist/styles/*.css",
|
|
115
|
+
"default": "./dist/styles/*.css"
|
|
112
116
|
}
|
|
113
117
|
},
|
|
114
118
|
"files": [
|