layerchart 0.18.0 → 0.18.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.
@@ -12,6 +12,7 @@ export let rule = false;
12
12
  export let grid = false;
13
13
  /** Control the number of ticks*/
14
14
  export let ticks = placement === 'left' || placement === 'right' ? 4 : undefined;
15
+ /** Length of the tick line */
15
16
  export let tickSize = 4;
16
17
  export let format = undefined;
17
18
  export let labelProps = undefined;
@@ -8,8 +8,8 @@ declare const __propDef: {
8
8
  /** Location of axis */ placement: 'top' | 'bottom' | 'left' | 'right';
9
9
  /** Draw a rule line. Use Rule component for greater rendering order control */ rule?: boolean | SVGAttributes<SVGLineElement> | undefined;
10
10
  /** Draw a grid lines */ grid?: boolean | SVGAttributes<SVGLineElement> | undefined;
11
- /** Control the number of ticks*/ ticks?: number | Function | undefined;
12
- tickSize?: number | undefined;
11
+ /** Control the number of ticks*/ ticks?: number | any[] | Function | undefined;
12
+ /** Length of the tick line */ tickSize?: number | undefined;
13
13
  format?: FormatType;
14
14
  labelProps?: ComponentProps<Text> | undefined;
15
15
  };
@@ -3,6 +3,7 @@ import { max, min } from 'd3-array';
3
3
  import { isScaleBand } from '../utils/scales';
4
4
  import Rect from './Rect.svelte';
5
5
  import { tooltipContext } from './TooltipContext.svelte';
6
+ import { firstValue } from '../utils/rect';
6
7
  const { flatData, x, xScale, xDomain, xRange, xGet, yScale, yDomain, yRange, yGet } = getContext('LayerCake');
7
8
  const tooltip = tooltipContext();
8
9
  export let axis = isScaleBand($yScale) ? 'y' : 'x';
@@ -14,8 +15,8 @@ let dimensions = {
14
15
  };
15
16
  $: {
16
17
  if ($tooltip.data) {
17
- let xCoord = $xGet($tooltip.data);
18
- let yCoord = $yGet($tooltip.data);
18
+ let xCoord = firstValue($xGet($tooltip.data));
19
+ let yCoord = firstValue($yGet($tooltip.data));
19
20
  if (axis === 'x' || axis === 'both') {
20
21
  if (isScaleBand($xScale)) {
21
22
  dimensions.width = $xScale.step();
@@ -9,6 +9,7 @@ export let leftOffset = 10;
9
9
  export let contained = 'container'; // TODO: Support 'window' using getBoundingClientRect()
10
10
  export let animate = true;
11
11
  export let header = undefined;
12
+ export let classes = {};
12
13
  const { containerWidth, containerHeight } = getContext('LayerCake');
13
14
  const tooltip = tooltipContext();
14
15
  let tooltipWidth = 0;
@@ -37,7 +38,7 @@ $: if ($tooltip) {
37
38
 
38
39
  {#if $tooltip.data}
39
40
  <div
40
- class={cls('absolute pointer-events-none z-50', $$props.class)}
41
+ class={cls('absolute pointer-events-none z-50', classes.root)}
41
42
  style:top="{$top}px"
42
43
  style:left="{$left}px"
43
44
  transition:fade={{ duration: 100 }}
@@ -45,18 +46,27 @@ $: if ($tooltip) {
45
46
  bind:clientHeight={tooltipHeight}
46
47
  >
47
48
  <div
48
- class="bg-gray-900/90 backdrop-filter backdrop-blur-[2px] text-white rounded elevation-1 px-2 py-1 h-full"
49
+ class={cls(
50
+ 'bg-gray-900/90 backdrop-filter backdrop-blur-[2px] text-white rounded elevation-1 px-2 py-1 h-full',
51
+ classes.container,
52
+ $$props.class
53
+ )}
49
54
  >
50
55
  {#if header || $$slots.header}
51
- <div class="text-center font-semibold whitespace-nowrap">
56
+ <div class={cls('text-center font-semibold whitespace-nowrap', classes.header)}>
52
57
  <slot name="header" data={$tooltip.data}>
53
- {header($tooltip.data)}
58
+ {header?.($tooltip.data)}
54
59
  </slot>
55
60
  </div>
56
61
  {/if}
57
62
 
58
63
  {#if $$slots.default}
59
- <div class="grid grid-cols-[1fr,auto] gap-x-2 gap-y-1 items-center pt-1">
64
+ <div
65
+ class={cls(
66
+ 'grid grid-cols-[1fr,auto] gap-x-2 gap-y-1 items-center pt-1',
67
+ classes.content
68
+ )}
69
+ >
60
70
  <slot data={$tooltip.data} />
61
71
  </div>
62
72
  {/if}
@@ -7,6 +7,12 @@ declare const __propDef: {
7
7
  contained?: false | "container" | undefined;
8
8
  animate?: boolean | undefined;
9
9
  header?: ((data: any) => any) | undefined;
10
+ classes?: {
11
+ root?: string | undefined;
12
+ container?: string | undefined;
13
+ header?: string | undefined;
14
+ content?: string | undefined;
15
+ } | undefined;
10
16
  };
11
17
  events: {
12
18
  [evt: string]: CustomEvent<any>;
@@ -27,6 +27,7 @@ import { localPoint } from '../utils/event';
27
27
  import { isScaleBand, scaleInvert } from '../utils/scales';
28
28
  import { quadtreeRects } from '../utils/quadtree';
29
29
  import { createPropertySortFunc, createSortFunc } from 'svelte-ux/utils/sort';
30
+ import { firstValue } from '../utils/rect';
30
31
  const dispatch = createEventDispatcher();
31
32
  const { flatData, x, xScale, xGet, xRange, y, yScale, yGet, yRange, width, height, padding } = getContext('LayerCake');
32
33
  /*
@@ -237,8 +238,8 @@ let rects = [];
237
238
  $: if (mode === 'bounds' || mode === 'band') {
238
239
  rects = $flatData
239
240
  .map((d) => {
240
- const xValue = $xGet(d);
241
- const yValue = $yGet(d);
241
+ const xValue = firstValue($xGet(d));
242
+ const yValue = firstValue($yGet(d));
242
243
  const x = Array.isArray(xValue) ? min(xValue) : xValue;
243
244
  const y = Array.isArray(yValue) ? max(yValue) : yValue;
244
245
  const xOffset = isScaleBand($xScale) ? ($xScale.padding() * $xScale.step()) / 2 : 0;
@@ -3,9 +3,10 @@ export let label;
3
3
  export let value = undefined; // Can be pass as slot
4
4
  export let format = undefined;
5
5
  export let valueAlign = 'left';
6
+ export let classes = {};
6
7
  </script>
7
8
 
8
- <div class="text-xs text-white/75 text-right whitespace-nowrap">
9
+ <div class={cls('text-xs text-white/75 text-right whitespace-nowrap', classes.label)}>
9
10
  <slot name="label">{label}:</slot>
10
11
  </div>
11
12
 
@@ -16,6 +17,7 @@ export let valueAlign = 'left';
16
17
  'text-right': valueAlign === 'right',
17
18
  'text-center': valueAlign === 'center'
18
19
  },
20
+ classes.value,
19
21
  $$props.class
20
22
  )}
21
23
  >
@@ -7,6 +7,10 @@ declare const __propDef: {
7
7
  value?: any;
8
8
  format?: FormatType;
9
9
  valueAlign?: "left" | "right" | "center" | undefined;
10
+ classes?: {
11
+ label?: string | undefined;
12
+ value?: string | undefined;
13
+ } | undefined;
10
14
  };
11
15
  events: {
12
16
  [evt: string]: CustomEvent<any>;
@@ -1 +1,4 @@
1
- <div class="rounded bg-white/50 my-1 col-span-full h-px" />
1
+ <script>import { cls } from 'svelte-ux';
2
+ </script>
3
+
4
+ <div class={cls('rounded bg-white/50 my-1 col-span-full h-px', $$props.class)} />
@@ -1,23 +1,16 @@
1
- /** @typedef {typeof __propDef.props} TooltipSeparatorProps */
2
- /** @typedef {typeof __propDef.events} TooltipSeparatorEvents */
3
- /** @typedef {typeof __propDef.slots} TooltipSeparatorSlots */
4
- export default class TooltipSeparator extends SvelteComponentTyped<{
5
- [x: string]: never;
6
- }, {
7
- [evt: string]: CustomEvent<any>;
8
- }, {}> {
9
- }
10
- export type TooltipSeparatorProps = typeof __propDef.props;
11
- export type TooltipSeparatorEvents = typeof __propDef.events;
12
- export type TooltipSeparatorSlots = typeof __propDef.slots;
13
1
  import { SvelteComponentTyped } from "svelte";
14
2
  declare const __propDef: {
15
3
  props: {
16
- [x: string]: never;
4
+ [x: string]: any;
17
5
  };
18
6
  events: {
19
7
  [evt: string]: CustomEvent<any>;
20
8
  };
21
9
  slots: {};
22
10
  };
11
+ export type TooltipSeparatorProps = typeof __propDef.props;
12
+ export type TooltipSeparatorEvents = typeof __propDef.events;
13
+ export type TooltipSeparatorSlots = typeof __propDef.slots;
14
+ export default class TooltipSeparator extends SvelteComponentTyped<TooltipSeparatorProps, TooltipSeparatorEvents, TooltipSeparatorSlots> {
15
+ }
23
16
  export {};
@@ -12,8 +12,18 @@ type DimensionGetterOptions = {
12
12
  };
13
13
  export declare function createDimensionGetter(context: any, options?: DimensionGetterOptions): import("svelte/store").Readable<(item: any) => {
14
14
  x: any;
15
+ y: number;
16
+ width: number;
17
+ height: number;
18
+ } | {
19
+ x: number;
15
20
  y: any;
16
21
  width: number;
17
22
  height: number;
18
23
  }>;
24
+ /**
25
+ * If value is an array, returns first item, else returns original value
26
+ * Useful when x/y getters for band scale are an array (such as for histograms)
27
+ */
28
+ export declare function firstValue(value: number | number[]): number;
19
29
  export {};
@@ -13,7 +13,7 @@ export function createDimensionGetter(context, options) {
13
13
  const y1Scale = groupBy
14
14
  ? groupScaleBand($yScale, $flatData, groupBy, options?.groupPadding)
15
15
  : null;
16
- const y = $yGet(item) + (y1Scale ? y1Scale(item[groupBy]) : 0) + padding / 2;
16
+ const y = firstValue($yGet(item)) + (y1Scale ? y1Scale(item[groupBy]) : 0) + padding / 2;
17
17
  const height = Math.max(0, $yScale.bandwidth ? (y1Scale ? y1Scale.bandwidth() : $yScale.bandwidth()) - padding : 0);
18
18
  const _x = options?.x
19
19
  ? typeof options.x === 'string'
@@ -55,7 +55,7 @@ export function createDimensionGetter(context, options) {
55
55
  const x1Scale = groupBy
56
56
  ? groupScaleBand($xScale, $flatData, groupBy, options?.groupPadding)
57
57
  : null;
58
- const x = $xGet(item) + (x1Scale ? x1Scale(item[groupBy]) : 0) + padding / 2;
58
+ const x = firstValue($xGet(item)) + (x1Scale ? x1Scale(item[groupBy]) : 0) + padding / 2;
59
59
  const width = Math.max(0, $xScale.bandwidth ? (x1Scale ? x1Scale.bandwidth() : $xScale.bandwidth()) - padding : 0);
60
60
  const _y = options?.y
61
61
  ? typeof options.y === 'string'
@@ -95,3 +95,10 @@ export function createDimensionGetter(context, options) {
95
95
  };
96
96
  });
97
97
  }
98
+ /**
99
+ * If value is an array, returns first item, else returns original value
100
+ * Useful when x/y getters for band scale are an array (such as for histograms)
101
+ */
102
+ export function firstValue(value) {
103
+ return Array.isArray(value) ? value[0] : value;
104
+ }
@@ -0,0 +1,11 @@
1
+ import { type ThresholdNumberArrayGenerator } from 'd3-array';
2
+ /**
3
+ * Useful threshold function when using Dates
4
+ * https://observablehq.com/@d3/d3-bin-time-thresholds
5
+ */
6
+ export declare function thresholdTime(n: number): ThresholdNumberArrayGenerator<number>;
7
+ /**
8
+ * Explicit threshold chunks without nicing (not recommended)
9
+ * see: https://observablehq.com/@d3/d3-bin#bin26
10
+ */
11
+ export declare function thresholdChunks(chunks: number): (data: number[], min: number, max: number) => number[];
@@ -0,0 +1,19 @@
1
+ import { range } from 'd3-array';
2
+ import { scaleTime } from 'd3-scale';
3
+ /**
4
+ * Useful threshold function when using Dates
5
+ * https://observablehq.com/@d3/d3-bin-time-thresholds
6
+ */
7
+ export function thresholdTime(n) {
8
+ // TODO: Unable to satifiy `ThresholdNumberArrayGenerator<Value extends number>` with `Date`
9
+ return (data, min, max) => {
10
+ return scaleTime().domain([min, max]).ticks(n);
11
+ };
12
+ }
13
+ /**
14
+ * Explicit threshold chunks without nicing (not recommended)
15
+ * see: https://observablehq.com/@d3/d3-bin#bin26
16
+ */
17
+ export function thresholdChunks(chunks) {
18
+ return (data, min, max) => range(chunks).map((t) => min + (t / chunks) * (max - min));
19
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "author": "Sean Lynch <techniq35@gmail.com>",
4
4
  "license": "MIT",
5
5
  "repository": "techniq/layerchart",
6
- "version": "0.18.0",
6
+ "version": "0.18.2",
7
7
  "scripts": {
8
8
  "dev": "vite dev",
9
9
  "build": "vite build",
@@ -15,12 +15,12 @@
15
15
  "lint": "prettier --ignore-path .gitignore --check --plugin-search-dir=. .",
16
16
  "format": "prettier --ignore-path .gitignore --write --plugin-search-dir=. .",
17
17
  "changeset": "changeset",
18
- "version-package": "changeset version"
18
+ "version": "changeset version"
19
19
  },
20
20
  "devDependencies": {
21
21
  "@rollup/plugin-dsv": "^3.0.2",
22
22
  "@sveltejs/adapter-vercel": "^3.0.1",
23
- "@sveltejs/kit": "^1.20.5",
23
+ "@sveltejs/kit": "^1.22.0",
24
24
  "@sveltejs/package": "^2.1.0",
25
25
  "@svitejs/changesets-changelog-github-compact": "^1.1.0",
26
26
  "@tailwindcss/typography": "^0.5.9",
@@ -36,9 +36,11 @@
36
36
  "@types/d3-scale": "^4.0.3",
37
37
  "@types/d3-shape": "^3.1.1",
38
38
  "@types/lodash-es": "^4.17.7",
39
+ "@types/marked": "^5.0.0",
39
40
  "@types/shapefile": "^0.6.1",
40
41
  "@types/topojson-client": "^3.1.1",
41
42
  "autoprefixer": "^10.4.14",
43
+ "marked": "^5.1.0",
42
44
  "mdsvex": "^0.11.0",
43
45
  "prettier": "^2.8.8",
44
46
  "prettier-plugin-svelte": "^2.10.1",
@@ -48,8 +50,8 @@
48
50
  "svelte-preprocess": "^5.0.4",
49
51
  "svelte2tsx": "^0.6.16",
50
52
  "tailwindcss": "^3.3.2",
51
- "tslib": "^2.5.3",
52
- "typescript": "^5.1.3",
53
+ "tslib": "^2.6.0",
54
+ "typescript": "^5.1.6",
53
55
  "unist-util-visit": "^4.1.2",
54
56
  "us-atlas": "^3.0.1",
55
57
  "vite": "^4.3.9",
@@ -79,7 +81,7 @@
79
81
  "lodash-es": "^4.17.21",
80
82
  "shapefile": "^0.6.6",
81
83
  "svelte": "^3.59.1",
82
- "svelte-ux": "^0.43.3",
84
+ "svelte-ux": "^0.43.5",
83
85
  "topojson-client": "^3.1.0"
84
86
  },
85
87
  "main": "./dist/index.js",