svelteplot 0.0.1-alpha.1 → 0.0.1-alpha.3

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/dist/Plot.svelte +171 -0
  2. package/dist/Plot.svelte.d.ts +15 -0
  3. package/dist/classes/Channel.svelte.js +72 -0
  4. package/dist/classes/Mark.svelte.js +17 -0
  5. package/dist/classes/Plot.svelte.js +99 -0
  6. package/dist/contants.d.ts +3 -0
  7. package/dist/contants.js +40 -0
  8. package/dist/helpers/GroupMultiple.svelte +8 -0
  9. package/dist/helpers/GroupMultiple.svelte.d.ts +19 -0
  10. package/dist/helpers/autoTimeFormat.d.ts +2 -0
  11. package/dist/helpers/autoTimeFormat.js +10 -0
  12. package/dist/helpers/colors.d.ts +13 -0
  13. package/dist/helpers/colors.js +200 -0
  14. package/dist/helpers/createScale.d.ts +4 -0
  15. package/dist/helpers/createScale.js +47 -0
  16. package/dist/helpers/getBaseStyles.d.ts +2 -0
  17. package/dist/helpers/getBaseStyles.js +18 -0
  18. package/dist/helpers/getLogTicks.d.ts +1 -0
  19. package/dist/helpers/getLogTicks.js +57 -0
  20. package/dist/helpers/isDataRecord.d.ts +2 -0
  21. package/dist/helpers/isDataRecord.js +13 -0
  22. package/dist/helpers/mergeDeep.d.ts +5 -0
  23. package/dist/helpers/mergeDeep.js +26 -0
  24. package/dist/helpers/removeIdenticalLines.d.ts +1 -0
  25. package/dist/helpers/removeIdenticalLines.js +16 -0
  26. package/dist/helpers/resolveChannel.d.ts +2 -0
  27. package/dist/helpers/resolveChannel.js +28 -0
  28. package/dist/helpers/symbols.d.ts +5 -0
  29. package/dist/helpers/symbols.js +51 -0
  30. package/dist/helpers/typeChecks.d.ts +7 -0
  31. package/dist/helpers/typeChecks.js +21 -0
  32. package/dist/helpers/wrapArray.d.ts +2 -0
  33. package/dist/helpers/wrapArray.js +4 -0
  34. package/dist/index.d.ts +12 -0
  35. package/dist/index.js +13 -0
  36. package/dist/marks/AxisX.svelte +101 -0
  37. package/dist/marks/AxisX.svelte.d.ts +17 -0
  38. package/dist/marks/AxisY.svelte +69 -0
  39. package/dist/marks/AxisY.svelte.d.ts +15 -0
  40. package/dist/marks/BaseMark.svelte +22 -0
  41. package/dist/marks/BaseMark.svelte.d.ts +19 -0
  42. package/dist/marks/ColorLegend.svelte +52 -0
  43. package/dist/marks/ColorLegend.svelte.d.ts +14 -0
  44. package/dist/marks/Dot.svelte +83 -0
  45. package/dist/marks/Dot.svelte.d.ts +15 -0
  46. package/dist/marks/DotX.svelte +5 -0
  47. package/dist/marks/DotX.svelte.d.ts +17 -0
  48. package/dist/marks/DotY.svelte +5 -0
  49. package/dist/marks/DotY.svelte.d.ts +17 -0
  50. package/dist/marks/Frame.svelte +37 -0
  51. package/dist/marks/Frame.svelte.d.ts +15 -0
  52. package/dist/marks/GridX.svelte +42 -0
  53. package/dist/marks/GridX.svelte.d.ts +19 -0
  54. package/dist/marks/GridY.svelte +31 -0
  55. package/dist/marks/GridY.svelte.d.ts +15 -0
  56. package/dist/marks/Line.svelte +49 -0
  57. package/dist/marks/Line.svelte.d.ts +15 -0
  58. package/dist/marks/LineX.svelte +10 -0
  59. package/dist/marks/LineX.svelte.d.ts +17 -0
  60. package/dist/marks/LineY.svelte +10 -0
  61. package/dist/marks/LineY.svelte.d.ts +17 -0
  62. package/dist/marks/RuleX.svelte +30 -0
  63. package/dist/marks/RuleX.svelte.d.ts +15 -0
  64. package/dist/marks/RuleY.svelte +31 -0
  65. package/dist/marks/RuleY.svelte.d.ts +15 -0
  66. package/dist/marks/SymbolLegend.svelte +50 -0
  67. package/dist/marks/SymbolLegend.svelte.d.ts +14 -0
  68. package/dist/types.d.ts +188 -0
  69. package/dist/types.js +1 -0
  70. package/package.json +4 -2
@@ -0,0 +1,4 @@
1
+ declare const Scales: Record<string, (domain: number[], range: [number, number]) => (val: any) => any>;
2
+ export declare function createScale(type: keyof typeof Scales, domain: any, range: any, options?: {}): (val: any) => any;
3
+ export declare function createColorScale(type: any, domain: string[] | [number, number] | [Date, Date] | [boolean | boolean], scheme: any): ((d: any) => any) | (unknown[] & string[] & import("d3-scale").ScaleOrdinal<string, unknown, never>);
4
+ export {};
@@ -0,0 +1,47 @@
1
+ import { scaleBand, scaleLinear, scaleTime, scaleSqrt, scaleLog, scaleOrdinal } from 'd3-scale';
2
+ import { getLogTicks } from './getLogTicks';
3
+ import { categoricalSchemes, isCategoricalScheme, isOrdinalScheme, ordinalScheme } from './colors';
4
+ import { isColorOrNull } from './typeChecks';
5
+ const Scales = {
6
+ band: scaleBand,
7
+ linear: scaleLinear,
8
+ time: scaleTime,
9
+ sqrt: scaleSqrt,
10
+ log: scaleLog,
11
+ ordinal: scaleOrdinal
12
+ };
13
+ export function createScale(type, domain, range, options = {}) {
14
+ const scale = Scales[type](domain, range);
15
+ // allow setting arbiraty scale options
16
+ for (const [key, val] of Object.entries(options)) {
17
+ if (typeof scale[key] === 'function')
18
+ scale[key](val);
19
+ else
20
+ console.warn('unknown scale setter ' + key);
21
+ }
22
+ if (type === 'log') {
23
+ // overwrite scaleLog's internal ticks() method
24
+ scale.ticks = (count) => getLogTicks(domain, count);
25
+ // console.log({domain})
26
+ // console.log(getLogTicks(domain, 5))
27
+ }
28
+ return scale;
29
+ }
30
+ const identity = (d) => d;
31
+ export function createColorScale(type, domain, scheme) {
32
+ if (type === 'band') {
33
+ if (domain.every(isColorOrNull)) {
34
+ console.log('domain is colors', domain);
35
+ return identity;
36
+ }
37
+ const colorRange = !scheme
38
+ ? categoricalSchemes.get('tableau10')
39
+ : Array.isArray(scheme)
40
+ ? scheme
41
+ : isCategoricalScheme(scheme)
42
+ ? categoricalSchemes.get(scheme)
43
+ : ordinalScheme(scheme)(domain.length);
44
+ return scaleOrdinal().domain(domain).range(colorRange);
45
+ }
46
+ return (d) => d;
47
+ }
@@ -0,0 +1,2 @@
1
+ import type { ChannelAccessor, MarkStyleProps, DataRow } from '../types';
2
+ export default function (datum: DataRow, props: Partial<Record<MarkStyleProps, ChannelAccessor>>): string;
@@ -0,0 +1,18 @@
1
+ import { MARK_PROP_CHANNEL } from '../contants';
2
+ import resolveChannel from './resolveChannel';
3
+ const styleProps = {
4
+ fill: 'fill',
5
+ stroke: 'stroke',
6
+ strokeWidth: 'stroke-width',
7
+ strokeDasharray: 'stroke-dasharray',
8
+ fillOpacity: 'fill-opacity',
9
+ strokeOpacity: 'stroke-opacity',
10
+ fontSize: 'font-size',
11
+ opacity: 'opacity'
12
+ };
13
+ export default function (datum, props) {
14
+ return Object.entries(styleProps)
15
+ .filter(([key, cssKey]) => cssKey && props[key] != null)
16
+ .map(([key, cssKey]) => `${cssKey}: ${resolveChannel(MARK_PROP_CHANNEL[key], datum, props[key])}`)
17
+ .join(';');
18
+ }
@@ -0,0 +1 @@
1
+ export declare function getLogTicks(domain: [number, number], count?: number): number[];
@@ -0,0 +1,57 @@
1
+ import { ticks as ticksArray } from 'd3-array';
2
+ export function getLogTicks(domain, count = 6) {
3
+ const inverted = domain[0] < 0 && domain[1] < 0;
4
+ if (inverted)
5
+ domain = [domain[0] * -1, domain[1] * -1];
6
+ const reversed = domain[1] < domain[0];
7
+ if (reversed)
8
+ domain = domain.slice(0).reverse();
9
+ if (domain[0] < 0 || domain[1] < 0)
10
+ return [];
11
+ if (domain[0] === 0)
12
+ return ticksArray(domain[0], domain[1], count - 2);
13
+ let mult = Math.pow(10, Math.floor(Math.log10(Math.abs(domain[1] - domain[0]))) - 1);
14
+ count += 2;
15
+ let candidates = getTickCandidates(domain, mult);
16
+ if (candidates[0].num > count) {
17
+ // too many ticks
18
+ while (candidates[0].num > count) {
19
+ mult *= 10;
20
+ candidates = getTickCandidates(domain, mult);
21
+ }
22
+ }
23
+ else if (candidates[candidates.length - 1].num < count) {
24
+ // not enough ticks, let's fallback to linear ticks
25
+ const ticksList = ticksArray(domain[0], domain[1], count - 2);
26
+ if (reversed)
27
+ ticksList.reverse();
28
+ return ticksList;
29
+ }
30
+ count -= 2;
31
+ const ticksList = candidates
32
+ .map((d) => ({
33
+ ...d,
34
+ ticks: d.ticks.filter((t) => t >= domain[0] && t <= domain[1])
35
+ }))
36
+ .map((d) => ({ ...d, diff: Math.abs(d.ticks.length - count) }))
37
+ .sort((a, b) => a.diff - b.diff)[0].ticks;
38
+ if (reversed)
39
+ ticksList.reverse();
40
+ if (inverted)
41
+ return ticksList.map((t) => t * -1);
42
+ return ticksList;
43
+ }
44
+ const logSeries = [[10], [5, 4, 5], [3, 10 / 3], [2, 2.5, 2], [1.5, 2, 5 / 3, 2]];
45
+ function getTickCandidates(domain, mult = 1) {
46
+ return logSeries.map((factors) => {
47
+ let i = Math.pow(10, Math.floor(Math.log10(domain[0])));
48
+ let f = 0;
49
+ const r = [i];
50
+ while (i < domain[1] && r.length < 50) {
51
+ i *= factors[f] * mult;
52
+ r.push(i);
53
+ f = (f + 1) % factors.length;
54
+ }
55
+ return { ticks: r, num: r.length };
56
+ });
57
+ }
@@ -0,0 +1,2 @@
1
+ import type { DataRecord } from '../types';
2
+ export default function (value: any): value is DataRecord;
@@ -0,0 +1,13 @@
1
+ export default function (value) {
2
+ if (typeof value !== 'object' || value === null)
3
+ return false;
4
+ if (Object.prototype.toString.call(value) !== '[object Object]')
5
+ return false;
6
+ const proto = Object.getPrototypeOf(value);
7
+ if (proto === null)
8
+ return true;
9
+ const Ctor = Object.prototype.hasOwnProperty.call(proto, 'constructor') && proto.constructor;
10
+ return (typeof Ctor === 'function' &&
11
+ Ctor instanceof Ctor &&
12
+ Function.prototype.call(Ctor) === Function.prototype.call(value));
13
+ }
@@ -0,0 +1,5 @@
1
+ type ObjectType = {
2
+ [key: string]: any;
3
+ };
4
+ export default function mergeDeep(target: ObjectType, ...sources: ObjectType[]): ObjectType;
5
+ export {};
@@ -0,0 +1,26 @@
1
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2
+ function isObject(item) {
3
+ return item && typeof item === 'object' && !Array.isArray(item);
4
+ }
5
+ export default function mergeDeep(target, ...sources) {
6
+ if (!sources.length)
7
+ return target;
8
+ const source = sources.shift();
9
+ if (isObject(target) && isObject(source)) {
10
+ for (const key in source) {
11
+ if (isObject(source[key])) {
12
+ if (!target[key]) {
13
+ Object.assign(target, { [key]: {} });
14
+ }
15
+ else {
16
+ target[key] = Object.assign({}, target[key]);
17
+ }
18
+ mergeDeep(target[key], source[key]);
19
+ }
20
+ else if (source[key] !== null) {
21
+ Object.assign(target, { [key]: source[key] });
22
+ }
23
+ }
24
+ }
25
+ return mergeDeep(target, ...sources);
26
+ }
@@ -0,0 +1 @@
1
+ export default function removeIdenticalLines(input: string[][]): string[][];
@@ -0,0 +1,16 @@
1
+ export default function removeIdenticalLines(input) {
2
+ const uniqueLines = [];
3
+ if (!input.length)
4
+ return input;
5
+ for (let c = 0; c < input.length; c++) {
6
+ uniqueLines.push([]);
7
+ }
8
+ for (let l = 0; l < input[0].length; l++) {
9
+ const isIdentical = input.every((value) => input[0][l] === value[l]);
10
+ for (let c = 0; c < input.length; c++) {
11
+ if (!isIdentical)
12
+ uniqueLines[c].push(input[c][l]);
13
+ }
14
+ }
15
+ return uniqueLines;
16
+ }
@@ -0,0 +1,2 @@
1
+ import type { ChannelName, ChannelAccessor, DataRow, RawValue } from '../types';
2
+ export default function (channel: ChannelName, datum: DataRow, accessor?: ChannelAccessor): RawValue;
@@ -0,0 +1,28 @@
1
+ import isDataRecord from './isDataRecord';
2
+ export default function (channel, datum, accessor = null) {
3
+ if ((channel === 'x' || channel === 'y') && Array.isArray(datum) && accessor === null) {
4
+ // special case for [[x0,y0], [x1,y1], ...] format
5
+ return datum[channel === 'x' ? 0 : 1];
6
+ }
7
+ else if (isDataRecord(datum)) {
8
+ // use accessor function
9
+ if (typeof accessor === 'function')
10
+ return accessor(datum.___orig___ ? datum.___orig___ : datum);
11
+ // use accessor string
12
+ if (typeof accessor === 'string' && datum[accessor] !== undefined)
13
+ return datum[accessor];
14
+ // fallback to channel name as accessor
15
+ if (accessor === null && datum[channel] !== undefined)
16
+ return datum[channel];
17
+ // interpret accessor as constant
18
+ return accessor;
19
+ }
20
+ else {
21
+ // return single value or accessor
22
+ return typeof accessor === 'function'
23
+ ? accessor(datum)
24
+ : accessor !== null
25
+ ? accessor
26
+ : datum;
27
+ }
28
+ }
@@ -0,0 +1,5 @@
1
+ import { type SymbolType } from 'd3-shape';
2
+ export declare const sqrt3: number;
3
+ export declare const sqrt4_3: number;
4
+ export declare function isSymbol(value: string | SymbolType): boolean;
5
+ export declare function maybeSymbol(symbol: SymbolType | string): SymbolType;
@@ -0,0 +1,51 @@
1
+ import { symbolAsterisk, symbolDiamond2, symbolPlus, symbolSquare2, symbolTriangle2, symbolX as symbolTimes, symbolCircle, symbolCross, symbolDiamond, symbolSquare, symbolStar, symbolTriangle, symbolWye } from 'd3-shape';
2
+ export const sqrt3 = Math.sqrt(3);
3
+ export const sqrt4_3 = 2 / sqrt3;
4
+ const symbolHexagon = {
5
+ draw(context, size) {
6
+ const rx = Math.sqrt(size / Math.PI), ry = rx * sqrt4_3, hy = ry / 2;
7
+ context.moveTo(0, ry);
8
+ context.lineTo(rx, hy);
9
+ context.lineTo(rx, -hy);
10
+ context.lineTo(0, -ry);
11
+ context.lineTo(-rx, -hy);
12
+ context.lineTo(-rx, hy);
13
+ context.closePath();
14
+ }
15
+ };
16
+ const symbols = new Map([
17
+ ['asterisk', symbolAsterisk],
18
+ ['circle', symbolCircle],
19
+ ['cross', symbolCross],
20
+ ['diamond', symbolDiamond],
21
+ ['diamond2', symbolDiamond2],
22
+ ['hexagon', symbolHexagon],
23
+ ['plus', symbolPlus],
24
+ ['square', symbolSquare],
25
+ ['square2', symbolSquare2],
26
+ ['star', symbolStar],
27
+ ['times', symbolTimes],
28
+ ['triangle', symbolTriangle],
29
+ ['triangle2', symbolTriangle2],
30
+ ['wye', symbolWye]
31
+ ]);
32
+ function isSymbolObject(value) {
33
+ if (typeof value === 'string')
34
+ return false;
35
+ return value && typeof value.draw === 'function';
36
+ }
37
+ export function isSymbol(value) {
38
+ if (isSymbolObject(value))
39
+ return true;
40
+ if (typeof value !== 'string')
41
+ return false;
42
+ return symbols.has(value.toLowerCase());
43
+ }
44
+ export function maybeSymbol(symbol) {
45
+ if (symbol == null || isSymbolObject(symbol))
46
+ return symbol;
47
+ const value = symbols.get(`${symbol}`.toLowerCase());
48
+ if (value)
49
+ return value;
50
+ throw new Error(`invalid symbol: ${symbol}`);
51
+ }
@@ -0,0 +1,7 @@
1
+ import type { RawValue } from '../types';
2
+ export declare function isBooleanOrNull(v: RawValue): boolean;
3
+ export declare function isDateOrNull(v: RawValue): boolean;
4
+ export declare function isNumberOrNull(v: RawValue): boolean;
5
+ export declare function isStringOrNull(v: RawValue): boolean;
6
+ export declare function isColorOrNull(v: RawValue): boolean;
7
+ export declare function isOpacityOrNull(v: RawValue): boolean;
@@ -0,0 +1,21 @@
1
+ import chroma from 'chroma-js';
2
+ import { isDate, isFinite } from 'underscore';
3
+ export function isBooleanOrNull(v) {
4
+ return v == null || typeof v === 'boolean';
5
+ }
6
+ export function isDateOrNull(v) {
7
+ return v == null || isDate(v);
8
+ }
9
+ export function isNumberOrNull(v) {
10
+ return v == null || isFinite(v);
11
+ }
12
+ export function isStringOrNull(v) {
13
+ return v == null || typeof v === 'string';
14
+ }
15
+ export function isColorOrNull(v) {
16
+ // todo: maybe not use chroma.js here to save kb
17
+ return v == null || (typeof v === 'string' && chroma.valid(v));
18
+ }
19
+ export function isOpacityOrNull(v) {
20
+ return v == null || (typeof v === 'number' && isFinite(v) && v >= 0 && v <= 1);
21
+ }
@@ -0,0 +1,2 @@
1
+ import type { DataRow } from '../types';
2
+ export default function (data: DataRow[]): (Date | [number, number] | import("../types").DataRecord)[];
@@ -0,0 +1,4 @@
1
+ import { isObject } from 'underscore';
2
+ export default function (data) {
3
+ return data.map((d) => (isObject(d) ? d : { value: d }));
4
+ }
@@ -0,0 +1,12 @@
1
+ export { default as Dot } from './marks/Dot.svelte';
2
+ export { default as DotX } from './marks/DotX.svelte';
3
+ export { default as DotY } from './marks/DotY.svelte';
4
+ export { default as Plot } from './Plot.svelte';
5
+ export { default as Frame } from './marks/Frame.svelte';
6
+ export { default as GridX } from './marks/GridX.svelte';
7
+ export { default as GridY } from './marks/GridY.svelte';
8
+ export { default as Line } from './marks/Line.svelte';
9
+ export { default as LineX } from './marks/LineX.svelte';
10
+ export { default as LineY } from './marks/LineY.svelte';
11
+ export { default as RuleX } from './marks/RuleX.svelte';
12
+ export { default as RuleY } from './marks/RuleY.svelte';
package/dist/index.js ADDED
@@ -0,0 +1,13 @@
1
+ // Reexport your entry components here
2
+ export { default as Dot } from './marks/Dot.svelte';
3
+ export { default as DotX } from './marks/DotX.svelte';
4
+ export { default as DotY } from './marks/DotY.svelte';
5
+ export { default as Plot } from './Plot.svelte';
6
+ export { default as Frame } from './marks/Frame.svelte';
7
+ export { default as GridX } from './marks/GridX.svelte';
8
+ export { default as GridY } from './marks/GridY.svelte';
9
+ export { default as Line } from './marks/Line.svelte';
10
+ export { default as LineX } from './marks/LineX.svelte';
11
+ export { default as LineY } from './marks/LineY.svelte';
12
+ export { default as RuleX } from './marks/RuleX.svelte';
13
+ export { default as RuleY } from './marks/RuleY.svelte';
@@ -0,0 +1,101 @@
1
+ <script>import { getContext } from "svelte";
2
+ import BaseMark from "./BaseMark.svelte";
3
+ import resolveChannel from "../helpers/resolveChannel";
4
+ import getBaseStyles from "../helpers/getBaseStyles";
5
+ import removeIdenticalLines from "../helpers/removeIdenticalLines";
6
+ import autoTimeFormat from "../helpers/autoTimeFormat";
7
+ import dayjs from "dayjs";
8
+ import { get } from "underscore";
9
+ const BaseMark_AxisX = BaseMark;
10
+ const plot = getContext("svelteplot");
11
+ let {
12
+ ticks = [],
13
+ anchor = "bottom",
14
+ tickSize = 6,
15
+ tickPadding = 3,
16
+ tickFormat = null,
17
+ automatic = false,
18
+ title = null,
19
+ tickFontSize = null,
20
+ fill = null,
21
+ ...styleProps
22
+ } = $props();
23
+ let autoTickCount = $derived(plot.plotWidth / get(plot, "options.x.tickSpacing", 80));
24
+ let autoTicks = $derived(
25
+ ticks.length > 0 ? ticks : get(plot, "options.x.ticks", plot.xScale.ticks(autoTickCount))
26
+ );
27
+ let useTickFormat = $derived(
28
+ typeof tickFormat === "function" ? tickFormat : plot.x.scaleType === "time" ? typeof tickFormat === "string" ? (d) => dayjs(d).format(tickFormat).split("\n") : autoTimeFormat(plot.x, plot.plotWidth) : (d) => String(d)
29
+ );
30
+ let tickTexts = $derived(
31
+ removeIdenticalLines(
32
+ autoTicks.map(useTickFormat).map((tick) => Array.isArray(tick) ? tick : [tick])
33
+ )
34
+ );
35
+ let optionsLabel = $derived(plot.options?.x?.label);
36
+ let useTitle = $derived(
37
+ title || (optionsLabel === null ? null : optionsLabel === void 0 ? plot.x.autoTitle : optionsLabel)
38
+ );
39
+ </script>
40
+
41
+ <BaseMark_AxisX type="axis-x" data={ticks} channels={['x']} {automatic}>
42
+ <g class="axis-x">
43
+ {#if useTitle}
44
+ <text
45
+ x={plot.plotWidth + plot.margins.left}
46
+ y={plot.height - 10}
47
+ class="axis-title"
48
+ dominant-baseline="hanging">{useTitle} →</text
49
+ >
50
+ {/if}
51
+ {#each autoTicks as tick, t}
52
+ {@const textLines = tickTexts[t]}
53
+ {@const prevTextLines = t && tickTexts[t - 1]}
54
+ <g
55
+ class="x-tick"
56
+ transform="translate({plot.xScale(tick)},{anchor === 'bottom'
57
+ ? plot.margins.top + plot.plotHeight
58
+ : plot.margins.top})"
59
+ >
60
+ <text
61
+ style={getBaseStyles(tick, { fill, fontSize: tickFontSize })}
62
+ y={(tickSize + tickPadding) * (anchor === 'bottom' ? 1 : -1)}
63
+ dominant-baseline={anchor === 'bottom' ? 'hanging' : 'auto'}
64
+ >
65
+ {#if typeof textLines === 'string' || textLines.length === 1}
66
+ {textLines}
67
+ {:else}
68
+ {#each textLines as line, i}
69
+ <tspan x="0" dy={i ? 12 : 0}
70
+ >{!prevTextLines || prevTextLines[i] !== line ? line : ''}</tspan
71
+ >
72
+ {/each}
73
+ {/if}
74
+ </text>
75
+ <line
76
+ style={getBaseStyles(tick, styleProps)}
77
+ y2={anchor === 'bottom' ? tickSize : -tickSize}
78
+ />
79
+ </g>
80
+ {/each}
81
+ </g>
82
+ </BaseMark_AxisX>
83
+
84
+ <style>
85
+ text {
86
+ text-anchor: middle;
87
+ font-size: 11px;
88
+
89
+ fill: #4a4a4a;
90
+ }
91
+
92
+ text.axis-title {
93
+ text-anchor: end;
94
+ }
95
+ .x-tick line {
96
+ stroke: currentColor;
97
+ }
98
+ .x-tick line.grid {
99
+ stroke: #d9d9d9;
100
+ }
101
+ </style>
@@ -0,0 +1,17 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { AxisMarkOptions } from '../types';
3
+ declare const __propDef: {
4
+ props: AxisMarkOptions & {
5
+ anchor?: "bottom" | "top" | undefined;
6
+ };
7
+ events: {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots: {};
11
+ };
12
+ export type AxisXProps = typeof __propDef.props;
13
+ export type AxisXEvents = typeof __propDef.events;
14
+ export type AxisXSlots = typeof __propDef.slots;
15
+ export default class AxisX extends SvelteComponent<AxisXProps, AxisXEvents, AxisXSlots> {
16
+ }
17
+ export {};
@@ -0,0 +1,69 @@
1
+ <script>import { getContext } from "svelte";
2
+ import BaseMark from "./BaseMark.svelte";
3
+ import getBaseStyles from "../helpers/getBaseStyles";
4
+ import { get } from "underscore";
5
+ const BaseMark_AxisX = BaseMark;
6
+ const plot = getContext("svelteplot");
7
+ let {
8
+ ticks = [],
9
+ anchor = "left",
10
+ automatic = false,
11
+ tickSize = 6,
12
+ tickPadding = 3,
13
+ title = null,
14
+ tickFormat = (d) => String(d),
15
+ tickFontSize = null,
16
+ fill = null,
17
+ ...styleProps
18
+ } = $props();
19
+ let autoTickCount = $derived(plot.plotHeight / get(plot, "options.y.tickSpacing", 80));
20
+ let autoTicks = $derived(
21
+ ticks.length > 0 ? ticks : get(plot, "options.y.ticks", plot.yScale.ticks(autoTickCount))
22
+ );
23
+ let optionsLabel = $derived(get(plot, "options.y.label"));
24
+ let useTitle = $derived(
25
+ title || (optionsLabel === null ? null : optionsLabel === void 0 ? plot.y.autoTitle : optionsLabel)
26
+ );
27
+ </script>
28
+
29
+ <BaseMark_AxisX type="axis-y" data={ticks} channels={['y']} {automatic}>
30
+ <g class="axis-y">
31
+ {#if useTitle}
32
+ <text x={0} y={5} class="axis-title" dominant-baseline="hanging">↑ {useTitle}</text>
33
+ {/if}
34
+ {#each autoTicks as tick}
35
+ <g
36
+ class="y-tick"
37
+ transform="translate({plot.margins.left +
38
+ (anchor === 'left' ? 0 : plot.plotWidth)},{plot.yScale(tick)})"
39
+ >
40
+ <text
41
+ class:is-left={anchor === 'left'}
42
+ style={getBaseStyles(tick, { fill, fontSize: tickFontSize })}
43
+ x={(tickSize + tickPadding) * (anchor === 'left' ? -1 : 1)}
44
+ dominant-baseline="middle">{tickFormat(tick)}</text
45
+ >
46
+ <line
47
+ style={getBaseStyles(tick, styleProps)}
48
+ x2={anchor === 'left' ? -tickSize : tickSize}
49
+ />
50
+ </g>
51
+ {/each}
52
+ </g>
53
+ </BaseMark_AxisX>
54
+
55
+ <style>
56
+ text {
57
+ font-size: 11px;
58
+ fill: #4a4a4a;
59
+ }
60
+ text.is-left {
61
+ text-anchor: end;
62
+ }
63
+ text.axis-title {
64
+ text-anchor: start;
65
+ }
66
+ .y-tick line {
67
+ stroke: currentColor;
68
+ }
69
+ </style>
@@ -0,0 +1,15 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { AxisYMarkProps } from '../types';
3
+ declare const __propDef: {
4
+ props: AxisYMarkProps;
5
+ events: {
6
+ [evt: string]: CustomEvent<any>;
7
+ };
8
+ slots: {};
9
+ };
10
+ export type AxisYProps = typeof __propDef.props;
11
+ export type AxisYEvents = typeof __propDef.events;
12
+ export type AxisYSlots = typeof __propDef.slots;
13
+ export default class AxisY extends SvelteComponent<AxisYProps, AxisYEvents, AxisYSlots> {
14
+ }
15
+ export {};
@@ -0,0 +1,22 @@
1
+ <script context="module"></script>
2
+
3
+ <script generics="T extends BaseMarkProps">import { Mark } from "../classes/Mark.svelte";
4
+ import { getContext } from "svelte";
5
+ const plot = getContext("svelteplot");
6
+ let { type, data = [], channels = [], children, automatic, ...rest } = $props();
7
+ const mark = new Mark(type, channels, automatic, { data, ...rest });
8
+ plot.addMark(mark);
9
+ $effect(() => {
10
+ mark.channels = new Set(channels);
11
+ });
12
+ $effect(() => {
13
+ mark.props = { data, ...rest };
14
+ });
15
+ $effect(() => {
16
+ return () => {
17
+ plot.removeMark(mark);
18
+ };
19
+ });
20
+ </script>
21
+
22
+ <slot />
@@ -0,0 +1,19 @@
1
+ import { SvelteComponent } from "svelte";
2
+ import type { BaseMarkProps } from '../types';
3
+ declare class __sveltets_Render<T extends BaseMarkProps> {
4
+ props(): T & {
5
+ children?: Function | undefined;
6
+ };
7
+ events(): {} & {
8
+ [evt: string]: CustomEvent<any>;
9
+ };
10
+ slots(): {
11
+ default: {};
12
+ };
13
+ }
14
+ export type BaseMarkProps<T extends BaseMarkProps> = ReturnType<__sveltets_Render<T>['props']>;
15
+ export type BaseMarkEvents<T extends BaseMarkProps> = ReturnType<__sveltets_Render<T>['events']>;
16
+ export type BaseMarkSlots<T extends BaseMarkProps> = ReturnType<__sveltets_Render<T>['slots']>;
17
+ export default class BaseMark<T extends BaseMarkProps> extends SvelteComponent<BaseMarkProps<T>, BaseMarkEvents<T>, BaseMarkSlots<T>> {
18
+ }
19
+ export {};