layerchart 0.73.0 → 0.74.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import Rect from './Rect.svelte';
|
|
6
6
|
import Spline from './Spline.svelte';
|
|
7
7
|
|
|
8
|
-
import { createDimensionGetter } from '../utils/rect.js';
|
|
8
|
+
import { createDimensionGetter, type Insets } from '../utils/rect.js';
|
|
9
9
|
import { isScaleBand } from '../utils/scales.js';
|
|
10
10
|
import { accessor, type Accessor } from '../utils/common.js';
|
|
11
11
|
import { greatestAbs } from '@layerstack/utils';
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
| 'bottom-left'
|
|
55
55
|
| 'bottom-right' = 'all';
|
|
56
56
|
|
|
57
|
-
export let
|
|
57
|
+
export let insets: Insets | undefined = undefined;
|
|
58
58
|
|
|
59
59
|
export let spring: ComponentProps<Rect>['spring'] = undefined;
|
|
60
60
|
export let tweened: ComponentProps<Rect>['tweened'] = undefined;
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
y,
|
|
67
67
|
x1,
|
|
68
68
|
y1,
|
|
69
|
-
|
|
69
|
+
insets,
|
|
70
70
|
});
|
|
71
71
|
$: dimensions = $getDimensions(bar) ?? { x: 0, y: 0, width: 0, height: 0 };
|
|
72
72
|
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import Bar from './Bar.svelte';
|
|
6
6
|
import Rect from './Rect.svelte';
|
|
7
7
|
import { chartDataArray, type Accessor } from '../utils/common.js';
|
|
8
|
+
import type { Insets } from '../index.js/utils/rect.js';
|
|
8
9
|
|
|
9
10
|
const { data: contextData, cGet, config } = chartContext();
|
|
10
11
|
|
|
@@ -39,7 +40,7 @@
|
|
|
39
40
|
export let fill: string | undefined = undefined;
|
|
40
41
|
|
|
41
42
|
/** Inset the rect for amount of padding. Useful with multiple bars (bullet, overlap, etc) */
|
|
42
|
-
export let
|
|
43
|
+
export let insets: Insets | undefined = undefined;
|
|
43
44
|
|
|
44
45
|
/** Define unique value for {#each} `(key)` expressions to improve transitions. `index` position used by default */
|
|
45
46
|
export let key: (d: any, index: number) => any = (d, i) => i;
|
|
@@ -66,7 +67,7 @@
|
|
|
66
67
|
{stroke}
|
|
67
68
|
{strokeWidth}
|
|
68
69
|
{radius}
|
|
69
|
-
{
|
|
70
|
+
{insets}
|
|
70
71
|
{spring}
|
|
71
72
|
{tweened}
|
|
72
73
|
on:click={() => onBarClick({ data: d })}
|
|
@@ -361,7 +361,7 @@
|
|
|
361
361
|
spring={motion}
|
|
362
362
|
x={typeof bar === 'object' ? bar.x : undefined}
|
|
363
363
|
y={typeof bar === 'object' ? bar.y : undefined}
|
|
364
|
-
|
|
364
|
+
insets={typeof bar === 'object' ? bar.insets : undefined}
|
|
365
365
|
stroke={typeof bar === 'object' ? bar.stroke : undefined}
|
|
366
366
|
strokeWidth={typeof bar === 'object' ? bar.strokeWidth : undefined}
|
|
367
367
|
radius={typeof bar === 'object' ? bar.radius : undefined}
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
type Accessor,
|
|
26
26
|
} from '../../utils/common.js';
|
|
27
27
|
import { asAny } from '../../utils/types.js';
|
|
28
|
+
import type { Insets } from '../../index.js/utils/rect.js';
|
|
28
29
|
|
|
29
30
|
type ChartProps = ComponentProps<Chart<TData>>;
|
|
30
31
|
|
|
@@ -33,6 +34,7 @@
|
|
|
33
34
|
grid?: typeof grid;
|
|
34
35
|
bandPadding?: typeof bandPadding;
|
|
35
36
|
groupPadding?: typeof groupPadding;
|
|
37
|
+
stackPadding?: typeof stackPadding;
|
|
36
38
|
labels?: typeof labels;
|
|
37
39
|
legend?: typeof legend;
|
|
38
40
|
orientation?: typeof orientation;
|
|
@@ -84,6 +86,8 @@
|
|
|
84
86
|
export let bandPadding = 0.4;
|
|
85
87
|
/** Padding between group/series items when using 'seriesLayout="group"', applied to scaleBand().padding() */
|
|
86
88
|
export let groupPadding = 0;
|
|
89
|
+
/** Padding between series items within bars when using 'seriesLayout="stack"' */
|
|
90
|
+
export let stackPadding = 0;
|
|
87
91
|
|
|
88
92
|
/** Event dispatched with current tooltip data */
|
|
89
93
|
export let onTooltipClick: (e: { data: any }) => void = () => {};
|
|
@@ -177,18 +181,41 @@
|
|
|
177
181
|
}
|
|
178
182
|
|
|
179
183
|
function getBarsProps(s: (typeof series)[number], i: number) {
|
|
180
|
-
const
|
|
184
|
+
const isFirst = i == 0;
|
|
185
|
+
const isLast = i == series.length - 1;
|
|
186
|
+
|
|
187
|
+
const isStackLayout = seriesLayout.startsWith('stack');
|
|
188
|
+
|
|
189
|
+
let stackInsets: Insets | undefined = undefined;
|
|
190
|
+
|
|
191
|
+
if (isStackLayout) {
|
|
192
|
+
const stackInset = stackPadding / 2;
|
|
193
|
+
if (isVertical) {
|
|
194
|
+
stackInsets = {
|
|
195
|
+
bottom: isFirst ? undefined : stackInset,
|
|
196
|
+
top: isLast ? undefined : stackInset,
|
|
197
|
+
};
|
|
198
|
+
} else {
|
|
199
|
+
stackInsets = {
|
|
200
|
+
left: isFirst ? undefined : stackInset,
|
|
201
|
+
right: isLast ? undefined : stackInset,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const valueAccessor = stackSeries
|
|
181
207
|
? (d: any) => d.stackData[i]
|
|
182
208
|
: (s.value ?? (s.data ? undefined : s.key));
|
|
183
209
|
const barsProps: ComponentProps<Bars> = {
|
|
184
210
|
data: s.data,
|
|
185
|
-
x: !isVertical ?
|
|
186
|
-
y: isVertical ?
|
|
211
|
+
x: !isVertical ? valueAccessor : undefined,
|
|
212
|
+
y: isVertical ? valueAccessor : undefined,
|
|
187
213
|
x1: isVertical && groupSeries ? (d) => s.value ?? s.key : undefined,
|
|
188
214
|
y1: !isVertical && groupSeries ? (d) => s.value ?? s.key : undefined,
|
|
189
|
-
rounded:
|
|
215
|
+
rounded: isStackLayout && i !== series.length - 1 ? 'none' : 'edge',
|
|
190
216
|
radius: 4,
|
|
191
217
|
strokeWidth: 1,
|
|
218
|
+
insets: stackInsets,
|
|
192
219
|
fill: s.color,
|
|
193
220
|
onBarClick: (e) => onBarClick({ data: e.data, series: s }),
|
|
194
221
|
...props.bars,
|
package/dist/utils/rect.d.ts
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
import type { ChartContext } from '../components/ChartContext.svelte';
|
|
2
2
|
import { type Accessor } from './common.js';
|
|
3
|
+
/** A set of inset distances, applied to a rectangle to shrink or expand the area represented by that rectangle. */
|
|
4
|
+
export type Insets = {
|
|
5
|
+
/** Applies an inset all sides of a rectangle: `left`, `right`, `bottom`, and `top` */
|
|
6
|
+
all?: number;
|
|
7
|
+
/** Applies an inset all horizontal sides of a rectangle: `left`, and `right`, overriding `all` */
|
|
8
|
+
x?: number;
|
|
9
|
+
/** Applies an inset all vertical sides of a rectangle: `top`, and `bottom`, overriding `all` */
|
|
10
|
+
y?: number;
|
|
11
|
+
/** Applies an inset the left side of a rectangle, overriding `x` */
|
|
12
|
+
left?: number;
|
|
13
|
+
/** Applies an inset the right side of a rectangle, overriding `x` */
|
|
14
|
+
right?: number;
|
|
15
|
+
/** Applies an inset the top side of a rectangle, overriding `y` */
|
|
16
|
+
top?: number;
|
|
17
|
+
/** Applies an inset the bottom side of a rectangle, overriding `y` */
|
|
18
|
+
bottom?: number;
|
|
19
|
+
};
|
|
3
20
|
type DimensionGetterOptions = {
|
|
4
21
|
/** Override `x` accessor from context */
|
|
5
22
|
x?: Accessor;
|
|
@@ -9,7 +26,7 @@ type DimensionGetterOptions = {
|
|
|
9
26
|
x1?: Accessor;
|
|
10
27
|
/** Override `y1` accessor from context */
|
|
11
28
|
y1?: Accessor;
|
|
12
|
-
|
|
29
|
+
insets?: Insets;
|
|
13
30
|
};
|
|
14
31
|
export declare function createDimensionGetter<TData>(context: ChartContext<TData>, options?: DimensionGetterOptions): import("svelte/store").Readable<(item: any) => {
|
|
15
32
|
x: any;
|
package/dist/utils/rect.js
CHANGED
|
@@ -4,8 +4,8 @@ import { isScaleBand } from './scales.js';
|
|
|
4
4
|
import { accessor } from './common.js';
|
|
5
5
|
export function createDimensionGetter(context, options) {
|
|
6
6
|
const { xScale, yScale, x: xAccessor, y: yAccessor, x1: x1Accessor, y1: y1Accessor, x1Scale, y1Scale, } = context;
|
|
7
|
-
const inset = options?.inset ?? 0;
|
|
8
7
|
return derived([xScale, x1Scale, yScale, y1Scale, xAccessor, yAccessor, x1Accessor, y1Accessor], ([$xScale, $x1Scale, $yScale, $y1Scale, $xAccessor, $yAccessor, $x1Accessor, $y1Accessor]) => {
|
|
8
|
+
const insets = resolveInsets(options?.insets);
|
|
9
9
|
// Use `xscale.domain()` instead of `$xDomain` to include `nice()` being applied
|
|
10
10
|
const [minXDomain, maxXDomain] = $xScale.domain();
|
|
11
11
|
const [minYDomain, maxYDomain] = $yScale.domain();
|
|
@@ -17,9 +17,11 @@ export function createDimensionGetter(context, options) {
|
|
|
17
17
|
return function getter(item) {
|
|
18
18
|
if (isScaleBand($yScale)) {
|
|
19
19
|
// Horizontal band
|
|
20
|
-
const y = firstValue($yScale(_y(item)) ?? 0) + ($y1Scale ? $y1Scale(_y1(item)) : 0) +
|
|
20
|
+
const y = firstValue($yScale(_y(item)) ?? 0) + ($y1Scale ? $y1Scale(_y1(item)) : 0) + insets.top;
|
|
21
21
|
const height = Math.max(0, $yScale.bandwidth
|
|
22
|
-
? ($y1Scale ? ($y1Scale.bandwidth?.() ?? 0) : $yScale.bandwidth()) -
|
|
22
|
+
? ($y1Scale ? ($y1Scale.bandwidth?.() ?? 0) : $yScale.bandwidth()) -
|
|
23
|
+
insets.bottom -
|
|
24
|
+
insets.top
|
|
23
25
|
: 0);
|
|
24
26
|
const xValue = _x(item);
|
|
25
27
|
let left = 0;
|
|
@@ -44,18 +46,17 @@ export function createDimensionGetter(context, options) {
|
|
|
44
46
|
left = xValue;
|
|
45
47
|
right = min([0, maxXDomain]);
|
|
46
48
|
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
width: $xScale(right) - $xScale(left),
|
|
51
|
-
height,
|
|
52
|
-
};
|
|
49
|
+
const x = $xScale(left) + insets.left;
|
|
50
|
+
const width = Math.max(0, $xScale(right) - $xScale(left) - insets.left - insets.right);
|
|
51
|
+
return { x, y, width, height };
|
|
53
52
|
}
|
|
54
53
|
else {
|
|
55
54
|
// Vertical band or linear
|
|
56
|
-
const x = firstValue($xScale(_x(item))) + ($x1Scale ? $x1Scale(_x1(item)) : 0) +
|
|
55
|
+
const x = firstValue($xScale(_x(item))) + ($x1Scale ? $x1Scale(_x1(item)) : 0) + insets.left;
|
|
57
56
|
const width = Math.max(0, $xScale.bandwidth
|
|
58
|
-
? ($x1Scale ? ($x1Scale.bandwidth?.() ?? 0) : $xScale.bandwidth()) -
|
|
57
|
+
? ($x1Scale ? ($x1Scale.bandwidth?.() ?? 0) : $xScale.bandwidth()) -
|
|
58
|
+
insets.left -
|
|
59
|
+
insets.right
|
|
59
60
|
: 0);
|
|
60
61
|
const yValue = _y(item);
|
|
61
62
|
let top = 0;
|
|
@@ -80,12 +81,9 @@ export function createDimensionGetter(context, options) {
|
|
|
80
81
|
top = min([0, maxYDomain]);
|
|
81
82
|
bottom = yValue;
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
width,
|
|
87
|
-
height: $yScale(bottom) - $yScale(top),
|
|
88
|
-
};
|
|
84
|
+
const y = $yScale(top) + insets.top;
|
|
85
|
+
const height = $yScale(bottom) - $yScale(top) - insets.bottom - insets.top;
|
|
86
|
+
return { x, y, width, height };
|
|
89
87
|
}
|
|
90
88
|
};
|
|
91
89
|
});
|
|
@@ -97,3 +95,13 @@ export function createDimensionGetter(context, options) {
|
|
|
97
95
|
export function firstValue(value) {
|
|
98
96
|
return Array.isArray(value) ? value[0] : value;
|
|
99
97
|
}
|
|
98
|
+
function resolveInsets(insets) {
|
|
99
|
+
const all = insets?.all ?? 0;
|
|
100
|
+
const x = insets?.x ?? all;
|
|
101
|
+
const y = insets?.y ?? all;
|
|
102
|
+
const left = insets?.left ?? x;
|
|
103
|
+
const right = insets?.right ?? x;
|
|
104
|
+
const top = insets?.top ?? y;
|
|
105
|
+
const bottom = insets?.bottom ?? y;
|
|
106
|
+
return { left, right, bottom, top };
|
|
107
|
+
}
|