layerchart 0.0.1 → 0.0.2

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.
Files changed (70) hide show
  1. package/components/Area.svelte +38 -0
  2. package/components/Area.svelte.d.ts +28 -0
  3. package/components/AreaStack.svelte +40 -0
  4. package/components/AreaStack.svelte.d.ts +20 -0
  5. package/components/AxisX.svelte +52 -0
  6. package/components/AxisX.svelte.d.ts +23 -0
  7. package/components/AxisY.svelte +69 -0
  8. package/components/AxisY.svelte.d.ts +23 -0
  9. package/components/Bar.svelte +93 -0
  10. package/components/Bar.svelte.d.ts +32 -0
  11. package/components/Baseline.svelte +21 -0
  12. package/components/Baseline.svelte.d.ts +17 -0
  13. package/components/Chart.svelte +50 -0
  14. package/components/Chart.svelte.d.ts +24 -0
  15. package/components/Circle.svelte +15 -0
  16. package/components/Circle.svelte.d.ts +22 -0
  17. package/components/ClevelandDotPlot.svelte +44 -0
  18. package/components/ClevelandDotPlot.svelte.d.ts +21 -0
  19. package/components/HighlightBar.svelte +27 -0
  20. package/components/HighlightBar.svelte.d.ts +18 -0
  21. package/components/HighlightLine.svelte +52 -0
  22. package/components/HighlightLine.svelte.d.ts +17 -0
  23. package/components/Label.svelte +96 -0
  24. package/components/Label.svelte.d.ts +22 -0
  25. package/components/Line.svelte +18 -0
  26. package/components/Line.svelte.d.ts +23 -0
  27. package/components/Path.svelte +36 -0
  28. package/components/Path.svelte.d.ts +25 -0
  29. package/components/Rect.svelte +25 -0
  30. package/components/Rect.svelte.d.ts +25 -0
  31. package/components/Scatter.svelte +25 -0
  32. package/components/Scatter.svelte.d.ts +33 -0
  33. package/components/Text.svelte +129 -0
  34. package/components/Text.svelte.d.ts +28 -0
  35. package/components/Threshold.svelte +83 -0
  36. package/components/Threshold.svelte.d.ts +35 -0
  37. package/components/Tooltip.svelte +120 -0
  38. package/components/Tooltip.svelte.d.ts +33 -0
  39. package/docs/Blockquote.svelte +7 -0
  40. package/docs/Blockquote.svelte.d.ts +23 -0
  41. package/docs/Code.svelte +6 -0
  42. package/docs/Code.svelte.d.ts +23 -0
  43. package/docs/Layout.svelte +20 -0
  44. package/docs/Layout.svelte.d.ts +29 -0
  45. package/docs/Link.svelte +7 -0
  46. package/docs/Link.svelte.d.ts +27 -0
  47. package/docs/Preview.svelte +19 -0
  48. package/docs/Preview.svelte.d.ts +19 -0
  49. package/package.json +73 -26
  50. package/stores/motionStore.d.ts +8 -0
  51. package/stores/motionStore.js +16 -0
  52. package/utils/event.d.ts +4 -0
  53. package/utils/event.js +42 -0
  54. package/utils/genData.d.ts +19 -0
  55. package/utils/genData.js +35 -0
  56. package/utils/pivot.d.ts +14 -0
  57. package/utils/pivot.js +36 -0
  58. package/utils/scales.d.ts +10 -0
  59. package/utils/scales.js +21 -0
  60. package/utils/string.d.ts +4 -0
  61. package/utils/string.js +27 -0
  62. package/utils/ticks.d.ts +3 -0
  63. package/utils/ticks.js +157 -0
  64. package/.prettierrc +0 -6
  65. package/src/app.html +0 -12
  66. package/src/global.d.ts +0 -1
  67. package/src/routes/index.svelte +0 -2
  68. package/static/favicon.png +0 -0
  69. package/svelte.config.js +0 -15
  70. package/tsconfig.json +0 -31
@@ -0,0 +1,18 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ data: any;
5
+ };
6
+ events: {
7
+ click: MouseEvent;
8
+ } & {
9
+ [evt: string]: CustomEvent<any>;
10
+ };
11
+ slots: {};
12
+ };
13
+ export declare type HighlightBarProps = typeof __propDef.props;
14
+ export declare type HighlightBarEvents = typeof __propDef.events;
15
+ export declare type HighlightBarSlots = typeof __propDef.slots;
16
+ export default class HighlightBar extends SvelteComponentTyped<HighlightBarProps, HighlightBarEvents, HighlightBarSlots> {
17
+ }
18
+ export {};
@@ -0,0 +1,52 @@
1
+ <script >import { getContext } from 'svelte';
2
+ import { get } from 'svelte/store';
3
+ import Circle from './Circle.svelte';
4
+ import Line from './Line.svelte';
5
+ export let data;
6
+ export let color = undefined;
7
+ const { xGet, yScale, yRange, yGet, zScale, padding } = getContext('LayerCake');
8
+ // TODO: Fix circle points being backwards for stack (see AreaStack)
9
+ $: x = $xGet(data);
10
+ function getColor(index) {
11
+ return color ?? get(zScale)(index) ?? 'var(--color-blue-500)';
12
+ }
13
+ $: points = Array.isArray(data)
14
+ ? // Stack series
15
+ data.map((yValue, i) => ({
16
+ x,
17
+ y: $yScale(yValue),
18
+ color: getColor(i)
19
+ }))
20
+ : [
21
+ {
22
+ x,
23
+ y: $yGet(data) - $padding.top,
24
+ color: getColor(0)
25
+ }
26
+ ];
27
+ </script>
28
+
29
+ <Line
30
+ spring
31
+ x1={x}
32
+ y1={0}
33
+ x2={x}
34
+ y2={$yRange[0]}
35
+ stroke="rgba(0,0,0,.5)"
36
+ stroke-width={2}
37
+ style="pointerEvents: none"
38
+ stroke-dasharray="2,2"
39
+ />
40
+
41
+ {#each points as point}
42
+ <Circle
43
+ spring
44
+ cx={point.x}
45
+ cy={point.y}
46
+ r={7}
47
+ fill="rgba(255,255,255,.9)"
48
+ stroke={point.color}
49
+ stroke-width={2}
50
+ />
51
+ <Circle spring cx={point.x} cy={point.y} r={3} fill={point.color} />
52
+ {/each}
@@ -0,0 +1,17 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ data: any;
5
+ color?: any;
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ };
12
+ export declare type HighlightLineProps = typeof __propDef.props;
13
+ export declare type HighlightLineEvents = typeof __propDef.events;
14
+ export declare type HighlightLineSlots = typeof __propDef.slots;
15
+ export default class HighlightLine extends SvelteComponentTyped<HighlightLineProps, HighlightLineEvents, HighlightLineSlots> {
16
+ }
17
+ export {};
@@ -0,0 +1,96 @@
1
+ <script >/*
2
+ * TODO
3
+ * - [ ] Support step curves (center like scaleBand())
4
+ * - [ ] Support multiple values (threshold, stacks, etc)
5
+ */
6
+ import { getContext } from 'svelte';
7
+ import { scaleBand } from 'd3-scale';
8
+ import { max, min } from 'd3-array';
9
+ import Text from './Text.svelte';
10
+ import { formatNumberAsStyle } from 'svelte-ux/utils/number';
11
+ import { isScaleBand } from '../utils/scales';
12
+ import { greatestAbs, unique } from 'svelte-ux/utils/array';
13
+ const { data, flatData, xGet, yRange, xScale, yScale, x, y, custom } = getContext('LayerCake');
14
+ export let orientation = 'auto';
15
+ export let significantDigits = 3;
16
+ export let formatStyle = null;
17
+ export let overlap = false;
18
+ $: yBaseline = $custom?.yBaseline ?? 0;
19
+ export let groupBy = undefined;
20
+ const x1Scale = scaleBand();
21
+ $: if (isScaleBand($xScale) && groupBy) {
22
+ const groupKeys = unique($flatData.map((d) => d[groupBy]));
23
+ x1Scale.domain(groupKeys).range([0, $xScale.bandwidth()]).paddingInner(0.2);
24
+ }
25
+ $: getDimensions = (item) => {
26
+ // console.log({ item, y: $y(item) });
27
+ let x = $xGet(item);
28
+ let width = 0;
29
+ if (isScaleBand($xScale)) {
30
+ width = groupBy ? x1Scale.bandwidth() : $xScale.bandwidth();
31
+ x += (groupBy ? x1Scale(item[groupBy]) : 0) + width / 2;
32
+ }
33
+ const yValue = $y(item);
34
+ let yTop = 0;
35
+ let yBottom = 0;
36
+ if (Array.isArray(yValue)) {
37
+ // Array contains both top and bottom values;
38
+ yTop = max(yValue);
39
+ yBottom = min(yValue);
40
+ }
41
+ else if (yValue == null) {
42
+ // null/undefined value
43
+ yTop = 0;
44
+ yBottom = 0;
45
+ }
46
+ else if (yValue > 0) {
47
+ // Positive value
48
+ yTop = yValue;
49
+ yBottom = $yRange[1]; // or `0`?
50
+ }
51
+ else {
52
+ // Negative value
53
+ yTop = $yRange[1]; // or `0`?
54
+ yBottom = yValue;
55
+ }
56
+ if (yBottom < 0) {
57
+ // Show label below
58
+ return {
59
+ x,
60
+ y: $yScale(yBottom),
61
+ dy: '0.5em',
62
+ width
63
+ };
64
+ }
65
+ else {
66
+ // Show label above
67
+ return {
68
+ x,
69
+ y: $yScale(yTop),
70
+ dy: '-0.6em',
71
+ width
72
+ };
73
+ }
74
+ };
75
+ $: getValue = (item) => {
76
+ const value = $y(item);
77
+ const labelValue = Array.isArray(value) ? greatestAbs(value) : value;
78
+ return labelValue != null
79
+ ? formatNumberAsStyle(labelValue + yBaseline, formatStyle, 0, significantDigits) ?? ''
80
+ : '';
81
+ };
82
+ </script>
83
+
84
+ <g class="label-group">
85
+ {#each $data as item, index}
86
+ <Text
87
+ class="group-rect"
88
+ textAnchor="middle"
89
+ verticalAnchor="middle"
90
+ value={getValue(item)}
91
+ style="font-size: 0.7em"
92
+ {...getDimensions(item)}
93
+ {...$$restProps}
94
+ />
95
+ {/each}
96
+ </g>
@@ -0,0 +1,22 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import { FormatNumberStyle } from 'svelte-ux/utils/number';
3
+ declare const __propDef: {
4
+ props: {
5
+ [x: string]: any;
6
+ orientation?: 'outside' | 'inside' | 'auto';
7
+ significantDigits?: number;
8
+ formatStyle?: FormatNumberStyle;
9
+ overlap?: boolean;
10
+ groupBy?: string;
11
+ };
12
+ events: {
13
+ [evt: string]: CustomEvent<any>;
14
+ };
15
+ slots: {};
16
+ };
17
+ export declare type LabelProps = typeof __propDef.props;
18
+ export declare type LabelEvents = typeof __propDef.events;
19
+ export declare type LabelSlots = typeof __propDef.slots;
20
+ export default class Label extends SvelteComponentTyped<LabelProps, LabelEvents, LabelSlots> {
21
+ }
22
+ export {};
@@ -0,0 +1,18 @@
1
+ <script >import { getMotionStore } from '../stores/motionStore';
2
+ export let x1;
3
+ export let y1;
4
+ export let x2;
5
+ export let y2;
6
+ export let spring = undefined;
7
+ export let tweened = undefined;
8
+ let tweened_x1 = getMotionStore(x1, { spring, tweened });
9
+ let tweened_y1 = getMotionStore(y1, { spring, tweened });
10
+ let tweened_x2 = getMotionStore(x2, { spring, tweened });
11
+ let tweened_y2 = getMotionStore(y2, { spring, tweened });
12
+ $: tweened_x1.set(x1);
13
+ $: tweened_y1.set(y1);
14
+ $: tweened_x2.set(x2);
15
+ $: tweened_y2.set(y2);
16
+ </script>
17
+
18
+ <line x1={$tweened_x1} y1={$tweened_y1} x2={$tweened_x2} y2={$tweened_y2} {...$$restProps} />
@@ -0,0 +1,23 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { spring as springStore, tweened as tweenedStore } from 'svelte/motion';
3
+ declare const __propDef: {
4
+ props: {
5
+ [x: string]: any;
6
+ x1: number;
7
+ y1: number;
8
+ x2: number;
9
+ y2: number;
10
+ spring?: boolean | Parameters<typeof springStore>[1];
11
+ tweened?: boolean | Parameters<typeof tweenedStore>[1];
12
+ };
13
+ events: {
14
+ [evt: string]: CustomEvent<any>;
15
+ };
16
+ slots: {};
17
+ };
18
+ export declare type LineProps = typeof __propDef.props;
19
+ export declare type LineEvents = typeof __propDef.events;
20
+ export declare type LineSlots = typeof __propDef.slots;
21
+ export default class Line extends SvelteComponentTyped<LineProps, LineEvents, LineSlots> {
22
+ }
23
+ export {};
@@ -0,0 +1,36 @@
1
+ <script >import { getContext } from 'svelte';
2
+ import { line as d3Line } from 'd3-shape';
3
+ const { data: contextData, xGet, yGet, zGet } = getContext('LayerCake');
4
+ // Properties to override what is used from context
5
+ export let data = undefined; // TODO: Update Type
6
+ export let x = undefined; // TODO: Update Type
7
+ export let y = undefined; // TODO: Update Type
8
+ export let pathData = undefined;
9
+ export let curve = undefined;
10
+ export let defined = undefined;
11
+ export let color = 'var(--color-blue-500)';
12
+ export let width = undefined;
13
+ $: path = d3Line()
14
+ .x(x ?? $xGet)
15
+ .y(y ?? $yGet);
16
+ $: if (curve)
17
+ path.curve(curve);
18
+ $: if (defined)
19
+ path.defined(defined);
20
+ </script>
21
+
22
+ <path
23
+ class="path-line"
24
+ d={pathData ?? path(data ?? $contextData)}
25
+ stroke={color}
26
+ stroke-width={width}
27
+ {...$$restProps}
28
+ />
29
+
30
+ <style >
31
+ .path-line {
32
+ fill: none;
33
+ stroke-linejoin: round;
34
+ stroke-linecap: round;
35
+ }
36
+ </style>
@@ -0,0 +1,25 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { CurveFactory, CurveFactoryLineOnly } from 'd3-shape';
3
+ declare const __propDef: {
4
+ props: {
5
+ [x: string]: any;
6
+ data?: any;
7
+ x?: any;
8
+ y?: any;
9
+ pathData?: string;
10
+ curve?: CurveFactory | CurveFactoryLineOnly;
11
+ defined?: (d: [number, number], index: number, data: [number, number][]) => boolean;
12
+ color?: string;
13
+ width?: any;
14
+ };
15
+ events: {
16
+ [evt: string]: CustomEvent<any>;
17
+ };
18
+ slots: {};
19
+ };
20
+ export declare type PathProps = typeof __propDef.props;
21
+ export declare type PathEvents = typeof __propDef.events;
22
+ export declare type PathSlots = typeof __propDef.slots;
23
+ export default class Path extends SvelteComponentTyped<PathProps, PathEvents, PathSlots> {
24
+ }
25
+ export {};
@@ -0,0 +1,25 @@
1
+ <script >import { getMotionStore } from '../stores/motionStore';
2
+ export let x;
3
+ export let y;
4
+ export let width;
5
+ export let height;
6
+ export let spring = undefined;
7
+ export let tweened = undefined;
8
+ let tweened_x = getMotionStore(x, { spring, tweened });
9
+ let tweened_y = getMotionStore(y, { spring, tweened });
10
+ let tweened_width = getMotionStore(width, { spring, tweened });
11
+ let tweened_height = getMotionStore(height, { spring, tweened });
12
+ $: tweened_x.set(x);
13
+ $: tweened_y.set(y);
14
+ $: tweened_width.set(width);
15
+ $: tweened_height.set(height);
16
+ </script>
17
+
18
+ <rect
19
+ x={$tweened_x}
20
+ y={$tweened_y}
21
+ width={$tweened_width}
22
+ height={$tweened_height}
23
+ {...$$restProps}
24
+ on:click
25
+ />
@@ -0,0 +1,25 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ import type { spring as springStore, tweened as tweenedStore } from 'svelte/motion';
3
+ declare const __propDef: {
4
+ props: {
5
+ [x: string]: any;
6
+ x: number;
7
+ y: number;
8
+ width: number;
9
+ height: number;
10
+ spring?: boolean | Parameters<typeof springStore>[1];
11
+ tweened?: boolean | Parameters<typeof tweenedStore>[1];
12
+ };
13
+ events: {
14
+ click: MouseEvent;
15
+ } & {
16
+ [evt: string]: CustomEvent<any>;
17
+ };
18
+ slots: {};
19
+ };
20
+ export declare type RectProps = typeof __propDef.props;
21
+ export declare type RectEvents = typeof __propDef.events;
22
+ export declare type RectSlots = typeof __propDef.slots;
23
+ export default class Rect extends SvelteComponentTyped<RectProps, RectEvents, RectSlots> {
24
+ }
25
+ export {};
@@ -0,0 +1,25 @@
1
+ <script>
2
+ import { getContext } from 'svelte';
3
+
4
+ const { data, xGet, yGet, xScale, yScale } = getContext('LayerCake');
5
+
6
+ export let r = 5;
7
+ export let fill = '#000';
8
+ export let stroke = '#0cf';
9
+ export let strokeWidth = 0;
10
+ export let dx = 0;
11
+ export let dy = 0;
12
+ </script>
13
+
14
+ <g class="scatter-group">
15
+ {#each $data as d}
16
+ <circle
17
+ cx={$xGet(d) + (typeof dx === 'function' ? dx($xScale) : dx)}
18
+ cy={$yGet(d) + (typeof dy === 'function' ? dy($yScale) : dy)}
19
+ {r}
20
+ {fill}
21
+ {stroke}
22
+ stroke-width={strokeWidth}
23
+ />
24
+ {/each}
25
+ </g>
@@ -0,0 +1,33 @@
1
+ /** @typedef {typeof __propDef.props} ScatterProps */
2
+ /** @typedef {typeof __propDef.events} ScatterEvents */
3
+ /** @typedef {typeof __propDef.slots} ScatterSlots */
4
+ export default class Scatter extends SvelteComponentTyped<{
5
+ dx?: number;
6
+ dy?: number;
7
+ stroke?: string;
8
+ strokeWidth?: number;
9
+ r?: number;
10
+ fill?: string;
11
+ }, {
12
+ [evt: string]: CustomEvent<any>;
13
+ }, {}> {
14
+ }
15
+ export type ScatterProps = typeof __propDef.props;
16
+ export type ScatterEvents = typeof __propDef.events;
17
+ export type ScatterSlots = typeof __propDef.slots;
18
+ import { SvelteComponentTyped } from "svelte";
19
+ declare const __propDef: {
20
+ props: {
21
+ dx?: number;
22
+ dy?: number;
23
+ stroke?: string;
24
+ strokeWidth?: number;
25
+ r?: number;
26
+ fill?: string;
27
+ };
28
+ events: {
29
+ [evt: string]: CustomEvent<any>;
30
+ };
31
+ slots: {};
32
+ };
33
+ export {};
@@ -0,0 +1,129 @@
1
+ <script >import { getStringWidth } from '../utils/string';
2
+ /*
3
+ TODO:
4
+ - [ ] Handle styled text (use <slot /> to measure?)
5
+
6
+ Reference:
7
+ - https://bl.ocks.org/mbostock/7555321
8
+ - https://github.com/airbnb/visx/blob/master/packages/visx-text/src/Text.tsx
9
+ - https://airbnb.io/visx/text
10
+ - https://github.com/airbnb/visx/blob/master/packages/visx-demo/src/pages/text.tsx
11
+ */
12
+ /** text value */
13
+ export let value = 0;
14
+ /** Maximum width to occupy (approximate as words are not split). */
15
+ export let width = undefined;
16
+ /** x position of the text. */
17
+ export let x = 0;
18
+ /** y position of the text. */
19
+ export let y = 0;
20
+ /** dx offset of the text. */
21
+ export let dx = 0;
22
+ /** dy offset of the text. */
23
+ export let dy = 0;
24
+ /** Desired "line height" of the text, implemented as y offsets. */
25
+ export let lineHeight = '1em';
26
+ /** Cap height of the text. */
27
+ export let capHeight = '0.71em'; // Magic number from d3
28
+ /** Whether to scale the fontSize to accommodate the specified width. */
29
+ export let scaleToFit = false;
30
+ /** Horizontal text anchor. */
31
+ export let textAnchor = 'start';
32
+ /** Vertical text anchor. */
33
+ export let verticalAnchor = 'end'; // default SVG behavior
34
+ /** Rotational angle of the text. */
35
+ export let rotate = undefined;
36
+ let wordsByLines = [];
37
+ let wordsWithWidth = [];
38
+ let spaceWidth = 0;
39
+ let style = undefined; // TODO: read from DOM?
40
+ $: words = value ? value.toString().split(/(?:(?!\u00A0+)\s+)/) : [];
41
+ $: wordsWithWidth = words.map((word) => ({
42
+ word,
43
+ width: getStringWidth(word, style) || 0
44
+ }));
45
+ $: spaceWidth = getStringWidth('\u00A0', style) || 0;
46
+ $: wordsByLines = wordsWithWidth.reduce((result, item) => {
47
+ const currentLine = result[result.length - 1];
48
+ if (currentLine &&
49
+ (width == null || scaleToFit || (currentLine.width || 0) + item.width + spaceWidth < width)) {
50
+ // Word can be added to an existing line
51
+ currentLine.words.push(item.word);
52
+ currentLine.width = currentLine.width || 0;
53
+ currentLine.width += item.width + spaceWidth;
54
+ }
55
+ else {
56
+ // Add first word to line or word is too long to scaleToFit on existing line
57
+ const newLine = { words: [item.word], width: item.width };
58
+ result.push(newLine);
59
+ }
60
+ return result;
61
+ }, []);
62
+ $: lines = wordsByLines.length;
63
+ /**
64
+ * Convert css value to pixel value (ex. 0.71em => 11.36)
65
+ */
66
+ function getPixelValue(cssValue) {
67
+ // TODO: Properly measure pixel values using DOM (handle inherited font size, zoom, etc)
68
+ // console.log(cssValue);
69
+ const [match, value, units] = cssValue.match(/([\d.]+)(\D+)/);
70
+ // console.log({ value, units });
71
+ const number = Number(value);
72
+ switch (units) {
73
+ case 'px':
74
+ return number;
75
+ case 'em':
76
+ case 'rem':
77
+ return number * 16;
78
+ default:
79
+ return 0;
80
+ }
81
+ }
82
+ let startDy = 0;
83
+ $: if (verticalAnchor === 'start') {
84
+ startDy = getPixelValue(capHeight);
85
+ }
86
+ else if (verticalAnchor === 'middle') {
87
+ startDy = ((lines - 1) / 2) * -getPixelValue(lineHeight) + getPixelValue(capHeight) / 2;
88
+ }
89
+ else {
90
+ startDy = (lines - 1) * -getPixelValue(lineHeight);
91
+ }
92
+ let scaleTransform = '';
93
+ $: if (scaleToFit &&
94
+ lines > 0 &&
95
+ typeof x == 'number' &&
96
+ typeof y == 'number' &&
97
+ typeof width == 'number') {
98
+ const lineWidth = wordsByLines[0].width || 1;
99
+ const sx = width / lineWidth;
100
+ const sy = sx;
101
+ const originX = x - sx * x;
102
+ const originY = y - sy * y;
103
+ scaleTransform = `matrix(${sx}, 0, 0, ${sy}, ${originX}, ${originY})`;
104
+ }
105
+ else {
106
+ scaleTransform = '';
107
+ }
108
+ $: rotateTransform = rotate ? `rotate(${rotate}, ${x}, ${y})` : '';
109
+ $: transform = `${scaleTransform} ${rotateTransform}`;
110
+ function isValidXOrY(xOrY) {
111
+ return (
112
+ // number that is not NaN or Infinity
113
+ (typeof xOrY === 'number' && Number.isFinite(xOrY)) ||
114
+ // for percentage
115
+ typeof xOrY === 'string');
116
+ }
117
+ </script>
118
+
119
+ <svg x={dx} y={dy} style="overflow: visible">
120
+ {#if isValidXOrY(x) && isValidXOrY(y)}
121
+ <text {x} {y} {transform} text-anchor={textAnchor} {...$$restProps}>
122
+ {#each wordsByLines as line, index}
123
+ <tspan {x} dy={index === 0 ? startDy : lineHeight}>
124
+ {line.words.join(' ')}
125
+ </tspan>
126
+ {/each}
127
+ </text>
128
+ {/if}
129
+ </svg>
@@ -0,0 +1,28 @@
1
+ import { SvelteComponentTyped } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ [x: string]: any;
5
+ value?: string | number;
6
+ width?: number;
7
+ x?: string | number;
8
+ y?: string | number;
9
+ dx?: string | number;
10
+ dy?: string | number;
11
+ lineHeight?: string;
12
+ capHeight?: string;
13
+ scaleToFit?: boolean;
14
+ textAnchor?: 'start' | 'middle' | 'end' | 'inherit';
15
+ verticalAnchor?: 'start' | 'middle' | 'end' | 'inherit';
16
+ rotate?: number;
17
+ };
18
+ events: {
19
+ [evt: string]: CustomEvent<any>;
20
+ };
21
+ slots: {};
22
+ };
23
+ export declare type TextProps = typeof __propDef.props;
24
+ export declare type TextEvents = typeof __propDef.events;
25
+ export declare type TextSlots = typeof __propDef.slots;
26
+ export default class Text extends SvelteComponentTyped<TextProps, TextEvents, TextSlots> {
27
+ }
28
+ export {};
@@ -0,0 +1,83 @@
1
+ <script >/*
2
+ See also:
3
+ - https://observablehq.com/@d3/difference-chart
4
+ - https://github.com/airbnb/visx/issues/245
5
+ */
6
+ import { getContext } from 'svelte';
7
+ import { area as d3Area, line as d3Line } from 'd3-shape';
8
+ const { data: contextData, xGet, yGet, yRange } = getContext('LayerCake');
9
+ // Properties to override what is used from context
10
+ export let data = undefined; // TODO: Update Type
11
+ export let x = undefined; // TODO: Update Type
12
+ export let y0 = undefined; // TODO: Update Type
13
+ export let y1 = undefined; // TODO: Update Type
14
+ export let curve = undefined;
15
+ export let defined = undefined;
16
+ export let id = Math.random().toString(16).slice(-4);
17
+ $: areaPath = d3Area()
18
+ .x(x ?? $xGet)
19
+ .y0(y0 ?? ((d) => $yGet(d)[0]))
20
+ .y1(y1 ?? ((d) => $yGet(d)[1]));
21
+ $: if (curve)
22
+ areaPath.curve(curve);
23
+ $: if (defined)
24
+ areaPath.defined(defined);
25
+ $: clipPathBelow = d3Area()
26
+ .x(x ?? $xGet)
27
+ .y0(y0 ?? ((d) => $yGet(d)[0]))
28
+ .y1(y1 ?? ((d) => $yRange[0]));
29
+ $: if (curve)
30
+ clipPathBelow.curve(curve);
31
+ $: if (defined)
32
+ clipPathBelow.defined(defined);
33
+ $: clipPathAbove = d3Area()
34
+ .x(x ?? $xGet)
35
+ .y0(y0 ?? ((d) => $yRange[0]))
36
+ .y1(y1 ?? ((d) => $yGet(d)[1]));
37
+ $: if (curve)
38
+ clipPathAbove.curve(curve);
39
+ $: if (defined)
40
+ clipPathAbove.defined(defined);
41
+ $: linePathAbove = d3Line()
42
+ .x(x ?? $xGet)
43
+ .y(y0 ?? ((d) => $yGet(d)[0]));
44
+ $: if (curve)
45
+ linePathAbove.curve(curve);
46
+ $: if (defined)
47
+ linePathAbove.defined(defined);
48
+ $: linePathBelow = d3Line()
49
+ .x(x ?? $xGet)
50
+ .y(y1 ?? ((d) => $yGet(d)[1]));
51
+ $: if (curve)
52
+ linePathBelow.curve(curve);
53
+ $: if (defined)
54
+ linePathBelow.defined(defined);
55
+ </script>
56
+
57
+ <g class="clip-paths">
58
+ <defs>
59
+ <clipPath id="threshold-clip-below-{id}">
60
+ <path d={clipPathBelow(data ?? $contextData)} />
61
+ </clipPath>
62
+ <clipPath id="threshold-clip-above-{id}">
63
+ <path d={clipPathAbove(data ?? $contextData)} />
64
+ </clipPath>
65
+ </defs>
66
+ </g>
67
+
68
+ <slot
69
+ name="pathAbove"
70
+ areaPathData={areaPath(data ?? $contextData)}
71
+ clipPath="url(#threshold-clip-below-{id})"
72
+ linePathData={linePathAbove(data ?? $contextData)}
73
+ />
74
+
75
+ <slot
76
+ name="pathBelow"
77
+ areaPathData={areaPath(data ?? $contextData)}
78
+ clipPath="url(#threshold-clip-above-{id})"
79
+ linePathData={linePathBelow(data ?? $contextData)}
80
+ />
81
+
82
+ <!-- Fix `<Threshold> received an unexpected slot "default".` warning -->
83
+ <slot />