svelteplot 0.0.1-alpha.7 → 0.0.1-alpha.9

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/Plot.svelte CHANGED
@@ -70,6 +70,7 @@ function onMouseMove(evt) {
70
70
  if (onmousemove)
71
71
  onmousemove({ ...evt, plot });
72
72
  }
73
+ $inspect(plot.x.domain);
73
74
  let hasLegend = $derived(color?.legend || symbol?.legend);
74
75
  </script>
75
76
 
@@ -149,6 +150,9 @@ let hasLegend = $derived(color?.legend || symbol?.legend);
149
150
  figure .plot-header {
150
151
  order: 1;
151
152
  }
153
+ h2, h3 {
154
+ margin: 0;
155
+ }
152
156
  svg {
153
157
  order: 2;
154
158
  overflow: visible;
@@ -67,6 +67,8 @@ export class Channel {
67
67
  ? 'linear'
68
68
  : this.valueType === 'text'
69
69
  ? 'band'
70
- : 'linear');
70
+ : this.valueType === 'color'
71
+ ? 'identity'
72
+ : 'linear');
71
73
  }
72
74
  // opacity: typeof === 'number' && between [0,1]
@@ -1,6 +1,7 @@
1
1
  import { createScale, createColorScale } from '../helpers/createScale.js';
2
2
  import mergeDeep from '../helpers/mergeDeep.js';
3
3
  import { Channel } from './Channel.svelte';
4
+ import { get } from 'underscore';
4
5
  export const DEFAULT_PLOT_OPTIONS = {
5
6
  title: '',
6
7
  subtitle: '',
@@ -76,7 +77,7 @@ export class Plot {
76
77
  symbolScale = $derived(createScale('ordinal', this.symbol.domain, this.options.symbol?.range || this.hasFilledDotMarks
77
78
  ? ['circle', 'cross', 'diamond', 'square', 'star', 'triangle', 'wye']
78
79
  : ['circle', 'plus', 'times', 'triangle2', 'asterisk', 'square2', 'diamond2']));
79
- colorScale = $derived(createColorScale(this.color.scaleType, this.color.domain, this.options.color.scheme));
80
+ colorScale = $derived(createColorScale(this.color.scaleType, this.color.domain, this.options.color?.range || null, this.options.color?.scheme));
80
81
  hasAxisXMark = $derived(!!this.marks.find((mark) => mark.type === 'axis-x' && !mark.automatic));
81
82
  hasAxisYMark = $derived(!!this.marks.find((mark) => mark.type === 'axis-y' && !mark.automatic));
82
83
  constructor(width, height, options) {
@@ -89,8 +90,7 @@ export class Plot {
89
90
  // console.log('addMark: ' + mark);
90
91
  this.marks = [...this.marks, mark];
91
92
  // add mark to respective channels
92
- if (mark.channels.has('color'))
93
- console.log(this.color.uniqueMarkProps);
93
+ // console.log(this.x.domain);
94
94
  }
95
95
  removeMark(removeMark) {
96
96
  this.marks = this.marks.filter((mark) => mark.id !== removeMark.id);
@@ -1,4 +1,5 @@
1
+ import type { ColorScheme, RawValue } from '../types.js';
1
2
  declare const Scales: Record<string, (domain: number[], range: [number, number]) => (val: any) => any>;
2
3
  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 declare function createColorScale(type: any, domain: string[] | [number, number] | [Date, Date] | [boolean | boolean], range: RawValue[] | null, scheme: ColorScheme | null): ((d: any) => any) | (unknown[] & string[] & import("d3-scale").ScaleOrdinal<string, unknown, never>) | import("d3-scale").ScaleSequential<string, never>;
4
5
  export {};
@@ -1,6 +1,7 @@
1
1
  import { scaleBand, scaleLinear, scaleTime, scaleSqrt, scaleLog, scaleOrdinal } from 'd3-scale';
2
+ import { scaleSequential, scaleDiverging } from 'd3-scale';
2
3
  import { getLogTicks } from './getLogTicks.js';
3
- import { categoricalSchemes, isCategoricalScheme, ordinalScheme } from './colors.js';
4
+ import { categoricalSchemes, isCategoricalScheme, isQuantitativeScheme, ordinalScheme, quantitativeScheme } from './colors.js';
4
5
  import { isColorOrNull } from './typeChecks.js';
5
6
  const Scales = {
6
7
  band: scaleBand,
@@ -8,7 +9,9 @@ const Scales = {
8
9
  time: scaleTime,
9
10
  sqrt: scaleSqrt,
10
11
  log: scaleLog,
11
- ordinal: scaleOrdinal
12
+ ordinal: scaleOrdinal,
13
+ sequential: scaleSequential,
14
+ diverging: scaleDiverging
12
15
  };
13
16
  export function createScale(type, domain, range, options = {}) {
14
17
  const scale = Scales[type](domain, range);
@@ -28,20 +31,27 @@ export function createScale(type, domain, range, options = {}) {
28
31
  return scale;
29
32
  }
30
33
  const identity = (d) => d;
31
- export function createColorScale(type, domain, scheme) {
34
+ export function createColorScale(type, domain, range, scheme) {
35
+ if (type === 'identity')
36
+ return identity;
32
37
  if (type === 'band') {
33
38
  if (domain.every(isColorOrNull)) {
34
- console.log('domain is colors', domain);
35
39
  return identity;
36
40
  }
37
- const colorRange = !scheme
38
- ? categoricalSchemes.get('tableau10')
39
- : Array.isArray(scheme)
40
- ? scheme
41
+ const colorRange = Array.isArray(range)
42
+ ? range
43
+ : !scheme
44
+ ? categoricalSchemes.get('tableau10')
41
45
  : isCategoricalScheme(scheme)
42
46
  ? categoricalSchemes.get(scheme)
43
47
  : ordinalScheme(scheme)(domain.length);
44
48
  return scaleOrdinal().domain(domain).range(colorRange);
45
49
  }
50
+ else if (type === 'linear') {
51
+ const colorInterpolator = isQuantitativeScheme(scheme)
52
+ ? quantitativeScheme(scheme)
53
+ : quantitativeScheme('blues');
54
+ return scaleSequential(domain, colorInterpolator);
55
+ }
46
56
  return (d) => d;
47
57
  }
@@ -1,6 +1,5 @@
1
1
  <script>import { getContext } from "svelte";
2
2
  import dayjs from "dayjs";
3
- import { get } from "underscore";
4
3
  import BaseMark from "./BaseMark.svelte";
5
4
  import getBaseStyles from "../helpers/getBaseStyles.js";
6
5
  import removeIdenticalLines from "../helpers/removeIdenticalLines.js";
@@ -19,9 +18,11 @@ let {
19
18
  fill = null,
20
19
  ...styleProps
21
20
  } = $props();
22
- let autoTickCount = $derived(plot.plotWidth / get(plot, "options.x.tickSpacing", 80));
21
+ let autoTickCount = $derived(Math.max(2, Math.round(plot.plotWidth / (plot.options?.x?.tickSpacing || 80))));
22
+ $inspect(autoTickCount);
23
+ $inspect(ticks.length);
23
24
  let autoTicks = $derived(
24
- ticks.length > 0 ? ticks : get(plot, "options.x.ticks", plot.xScale.ticks(autoTickCount))
25
+ ticks.length > 0 ? ticks : plot.options?.x?.ticks ?? plot.xScale.ticks(autoTickCount)
25
26
  );
26
27
  let useTickFormat = $derived(
27
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)
@@ -33,7 +34,7 @@ let tickTexts = $derived(
33
34
  );
34
35
  let optionsLabel = $derived(plot.options?.x?.label);
35
36
  let useTitle = $derived(
36
- title || (optionsLabel === null ? null : optionsLabel === void 0 ? plot.x.autoTitle : optionsLabel)
37
+ title || (optionsLabel === null ? null : optionsLabel !== void 0 ? optionsLabel : `${plot.x.autoTitle} \u2192`)
37
38
  );
38
39
  </script>
39
40
 
@@ -44,7 +45,7 @@ let useTitle = $derived(
44
45
  x={plot.plotWidth + plot.margins.left}
45
46
  y={plot.height - 10}
46
47
  class="axis-title"
47
- dominant-baseline="hanging">{useTitle} →</text
48
+ dominant-baseline="hanging">{useTitle}</text
48
49
  >
49
50
  {/if}
50
51
  {#each autoTicks as tick, t}
@@ -20,16 +20,17 @@ let autoTickCount = $derived(plot.plotHeight / get(plot, "options.y.tickSpacing"
20
20
  let autoTicks = $derived(
21
21
  ticks.length > 0 ? ticks : get(plot, "options.y.ticks", plot.yScale.ticks(autoTickCount))
22
22
  );
23
- let optionsLabel = $derived(get(plot, "options.y.label"));
23
+ let optionsLabel = $derived(plot.options.y?.label);
24
24
  let useTitle = $derived(
25
- title || (optionsLabel === null ? null : optionsLabel === void 0 ? plot.y.autoTitle : optionsLabel)
25
+ title || (optionsLabel === null ? null : optionsLabel !== void 0 ? optionsLabel : `\u2191 ${plot.y.autoTitle}`)
26
26
  );
27
+ $inspect(optionsLabel);
27
28
  </script>
28
29
 
29
30
  <BaseMark_AxisX type="axis-y" data={ticks} channels={['y']} {automatic}>
30
31
  <g class="axis-y">
31
32
  {#if useTitle}
32
- <text x={0} y={5} class="axis-title" dominant-baseline="hanging">↑ {useTitle}</text>
33
+ <text x={0} y={5} class="axis-title" dominant-baseline="hanging">{useTitle}</text>
33
34
  {/if}
34
35
  {#each autoTicks as tick}
35
36
  <g
@@ -4,6 +4,7 @@ import BaseMark from "./BaseMark.svelte";
4
4
  import getBaseStyles from "../helpers/getBaseStyles.js";
5
5
  import { line } from "d3-shape";
6
6
  import { groupBy } from "underscore";
7
+ import isDataRecord from "../helpers/isDataRecord.js";
7
8
  const BaseMark_Line = BaseMark;
8
9
  const plot = getContext("svelteplot");
9
10
  let {
@@ -14,10 +15,16 @@ let {
14
15
  fill,
15
16
  stroke,
16
17
  r = 5,
18
+ sort,
17
19
  ...styleProps
18
20
  } = $props();
19
21
  let groups = $derived(
20
- z ? Object.values(groupBy(data, (d) => resolveChannel("z", d, z))) : [data]
22
+ z || fill || stroke ? Object.values(groupBy(data, (d) => resolveChannel("z", d, z || fill || stroke))) : [data]
23
+ );
24
+ let sortedGroups = $derived(
25
+ sort ? groups.sort(
26
+ (a, b) => resolveChannel("sort", a[0], sort) > resolveChannel("sort", b[0], sort) ? 1 : -1
27
+ ) : groups
21
28
  );
22
29
  let linePath = line().x((d) => plot.xScale(resolveChannel("x", d, x))).y((d) => plot.yScale(resolveChannel("y", d, y)));
23
30
  </script>
@@ -34,16 +41,21 @@ let linePath = line().x((d) => plot.xScale(resolveChannel("x", d, x))).y((d) =>
34
41
  {...styleProps}
35
42
  >
36
43
  <g class="lines">
37
- {#each groups as lineData}
38
- <path d={linePath(lineData)} style={getBaseStyles(lineData[0], styleProps)} />
44
+ {#each sortedGroups as lineData}
45
+ <path
46
+ d={linePath(lineData)}
47
+ stroke={stroke
48
+ ? plot.colorScale(resolveChannel('color', lineData[0], stroke))
49
+ : 'currentColor'}
50
+ fill={fill ? plot.colorScale(resolveChannel('color', lineData[0], fill)) : 'none'}
51
+ style={getBaseStyles(lineData[0], styleProps)}
52
+ />
39
53
  {/each}
40
54
  </g>
41
55
  </BaseMark_Line>
42
56
 
43
57
  <style>
44
58
  .lines path {
45
- stroke: currentColor;
46
- fill: none;
47
59
  stroke-width: 1.4px;
48
60
  }
49
61
  </style>
package/dist/types.d.ts CHANGED
@@ -30,6 +30,11 @@ export type Datasets = {
30
30
  body_mass_g: number;
31
31
  sex: string;
32
32
  }[];
33
+ bls: {
34
+ division: string;
35
+ date: Date;
36
+ unemployment: number;
37
+ }[];
33
38
  };
34
39
  export type AxisXAnchor = 'bottom' | 'top' | 'both';
35
40
  export type AxisYAnchor = 'left' | 'right' | 'both';
@@ -80,7 +85,9 @@ export type PlotProps = {
80
85
  legend?: boolean;
81
86
  } | null;
82
87
  color?: {
83
- scheme?: ColorScheme | string[];
88
+ range?: string[];
89
+ domain: RawValue[];
90
+ scheme?: ColorScheme;
84
91
  legend?: boolean;
85
92
  } | null;
86
93
  };
@@ -133,6 +140,9 @@ export type LineMarkProps = MarkProps & BaseMarkStyleProps & {
133
140
  x?: ChannelAccessor;
134
141
  y?: ChannelAccessor;
135
142
  z?: ChannelAccessor;
143
+ sort?: ChannelAccessor | {
144
+ channel: 'stroke' | 'fill';
145
+ };
136
146
  };
137
147
  export type GridOptions = {
138
148
  ticks?: RawValue[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "svelteplot",
3
- "version": "0.0.1-alpha.7",
3
+ "version": "0.0.1-alpha.9",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build",
@@ -49,7 +49,7 @@
49
49
  "prettier": "^3.1.0",
50
50
  "prettier-plugin-svelte": "^3.1.2",
51
51
  "sass": "^1.69.5",
52
- "svelte": "5.0.0-next.20",
52
+ "svelte": "5.0.0-next.22",
53
53
  "svelte-check": "^3.6.2",
54
54
  "svelte-highlight": "^7.4.2",
55
55
  "tslib": "^2.6.2",