Skip to content

Commit 789a105

Browse files
authored
Merge pull request #113 from svelteplot/ts/pass-thru-data-type
Pass data type through mark components
2 parents db996a4 + 75edbb7 commit 789a105

File tree

177 files changed

+3266
-1027
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

177 files changed

+3266
-1027
lines changed

package.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "svelteplot",
3-
"version": "0.3.3",
3+
"version": "0.3.2",
44
"license": "ISC",
55
"author": {
66
"name": "Gregor Aisch",
@@ -68,10 +68,14 @@
6868
"@types/d3-geo": "^3.1.0",
6969
"@types/d3-interpolate": "^3.0.4",
7070
"@types/d3-path": "^3.1.1",
71+
"@types/d3-quadtree": "^3.0.6",
7172
"@types/d3-random": "^3.0.3",
7273
"@types/d3-scale": "^4.0.9",
7374
"@types/d3-scale-chromatic": "^3.1.0",
7475
"@types/d3-shape": "^3.1.7",
76+
"@types/geojson": "^7946.0.16",
77+
"@types/topojson": "^3.2.6",
78+
"@types/topojson-client": "^3.1.5",
7579
"@typescript-eslint/eslint-plugin": "^8.34.0",
7680
"@typescript-eslint/parser": "^8.34.0",
7781
"csstype": "^3.1.3",

pnpm-lock.yaml

Lines changed: 63 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

screenshot-examples.js

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ const OUTPUT_DIR = path.join(__dirname, 'static', 'examples');
1212
const SCREENSHOT_WIDTH = 600;
1313
const DEVICE_PIXEL_RATIO = 2;
1414

15+
// Only take missing screenshots if ENV variable is set
16+
const ONLY_MISSING = process.env.ONLY_MISSING == 1;
17+
1518
// Start the development server and return server instance and local URL
1619
const startServer = () => {
1720
console.log('Starting development server...');
@@ -70,6 +73,26 @@ const getSvelteFiles = async (dir) => {
7073
return files.flat();
7174
};
7275

76+
const getExistingScreenshots = async (dir) => {
77+
const entries = await fs.readdir(dir, { withFileTypes: true });
78+
79+
const files = await Promise.all(
80+
entries.map(async (entry) => {
81+
const fullPath = path.join(dir, entry.name);
82+
83+
if (entry.isDirectory()) {
84+
return getExistingScreenshots(fullPath);
85+
} else if (entry.isFile() && entry.name.endsWith('.png')) {
86+
return [fullPath];
87+
}
88+
89+
return [];
90+
})
91+
);
92+
93+
return files.flat();
94+
};
95+
7396
// Convert file path to URL path
7497
const filePathToUrlPath = (filePath) => {
7598
const relativePath = path.relative(EXAMPLES_DIR, filePath);
@@ -161,9 +184,35 @@ const screenshotExamples = async () => {
161184
});
162185

163186
// Get all example Svelte files
164-
const svelteFiles = await getSvelteFiles(EXAMPLES_DIR);
187+
let svelteFiles = await getSvelteFiles(EXAMPLES_DIR);
165188
console.log(`Found ${svelteFiles.length} example files to screenshot`);
166189

190+
if (ONLY_MISSING) {
191+
// Filter to only include files that don't have screenshots ()
192+
const existingScreenshots = (await getExistingScreenshots(OUTPUT_DIR)).map((file) =>
193+
path.relative(OUTPUT_DIR, file)
194+
);
195+
196+
console.log(`Found ${existingScreenshots.length} existing screenshots`);
197+
198+
// Filter out files that already have screenshots
199+
svelteFiles = svelteFiles.filter((filePath) => {
200+
return (
201+
!existingScreenshots.find((screenshot) =>
202+
filePath.endsWith(screenshot.replace('.png', '.svelte'))
203+
) ||
204+
!existingScreenshots.find((screenshot) =>
205+
filePath.endsWith(screenshot.replace('.dark.png', '.svelte'))
206+
)
207+
);
208+
});
209+
210+
console.log(
211+
`Filtered down to ${svelteFiles.length} files needing screenshots`,
212+
svelteFiles
213+
);
214+
}
215+
167216
// Process each file
168217
for (const filePath of svelteFiles) {
169218
const urlPath = filePathToUrlPath(filePath);

src/lib/Mark.svelte

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
1-
<script lang="ts">
2-
import { getContext, untrack, type Snippet } from 'svelte';
1+
<script lang="ts" generics="Datum extends DataRecord">
2+
interface MarkProps extends Partial<BaseMarkProps<Datum>> {
3+
data?: Datum[];
4+
automatic?: boolean;
5+
type: MarkType;
6+
channels?: ScaledChannelName[];
7+
required?: ScaledChannelName[];
8+
requiredScales?: Partial<Record<ScaleName, ScaleType[]>>;
9+
children?: Snippet<
10+
[
11+
{
12+
mark: Mark<GenericMarkOptions>;
13+
usedScales: ReturnType<typeof getUsedScales>;
14+
scaledData: ScaledDataRecord[];
15+
}
16+
]
17+
>;
18+
defaults?: Partial<Record<ScaledChannelName, RawValue>>;
19+
}
320
21+
import { getContext, untrack, type Snippet } from 'svelte';
422
import { CHANNEL_SCALE, INDEX } from '$lib/constants.js';
523
import type {
624
ScaledChannelName,
@@ -17,32 +35,12 @@
1735
ResolvedDataRecord,
1836
ScaledDataRecord,
1937
ScaleType
20-
} from './types.js';
38+
} from './types/index.js';
2139
import { isEqual } from 'es-toolkit';
2240
import { getUsedScales, projectXY, projectX, projectY } from './helpers/scales.js';
2341
import { testFilter, isValid } from '$lib/helpers/index.js';
2442
import { resolveChannel, resolveProp } from './helpers/resolve.js';
2543
26-
type MarkProps = {
27-
data?: DataRecord[];
28-
automatic?: boolean;
29-
type: MarkType;
30-
channels?: ScaledChannelName[];
31-
required?: ScaledChannelName[];
32-
requiredScales?: Partial<Record<ScaleName, ScaleType[]>>;
33-
children?: Snippet<
34-
[
35-
{
36-
mark: Mark<GenericMarkOptions>;
37-
usedScales: ReturnType<typeof getUsedScales>;
38-
scaledData: ScaledDataRecord[];
39-
}
40-
]
41-
>;
42-
defaults?: Partial<Record<ScaledChannelName, RawValue>>;
43-
} & Partial<Record<ChannelName, ChannelAccessor>> &
44-
Partial<BaseMarkProps>;
45-
4644
let {
4745
data = [],
4846
children,
@@ -134,13 +132,13 @@
134132
const { getTestFacet } = getContext<FacetContext>('svelteplot/facet');
135133
const testFacet = $derived(getTestFacet());
136134
137-
const resolvedData: ResolvedDataRecord[] = $derived(
135+
const resolvedData: ResolvedDataRecord<Datum>[] = $derived(
138136
data
139137
.map((d, i) => ({ ...d, [INDEX]: i }))
140138
.flatMap((row) => {
141-
const channels = options as Record<ChannelName, ChannelAccessor>;
139+
const channels = options as Record<ChannelName, ChannelAccessor<Datum>>;
142140
if (!testFacet(row, channels) || !testFilter(row, channels)) return [];
143-
const out: ResolvedDataRecord = {
141+
const out: ResolvedDataRecord<Datum> = {
144142
datum: row
145143
};
146144
for (const [channel] of Object.entries(CHANNEL_SCALE) as [
@@ -208,7 +206,7 @@
208206
*/
209207
const scaledData = $derived(
210208
resolvedData.flatMap((row) => {
211-
const out: ScaledDataRecord = {
209+
const out: ScaledDataRecord<Datum> = {
212210
datum: row.datum,
213211
valid: true
214212
};

src/lib/Plot.svelte

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
<script lang="ts">
1313
import Plot from './core/Plot.svelte';
1414
15-
import type { PlotDefaults, PlotOptions } from './types.js';
15+
import type { PlotDefaults, PlotOptions } from './types/index.js';
1616
1717
// implicit marks
1818
import AxisX from './marks/AxisX.svelte';
@@ -28,7 +28,6 @@
2828
import { autoScale, autoScaleColor } from './helpers/autoScales.js';
2929
import { namedProjection } from './helpers/autoProjection.js';
3030
import { isObject } from './helpers/index.js';
31-
import { getContext } from 'svelte';
3231
3332
let {
3433
header: userHeader,

src/lib/core/Facet.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script lang="ts">
22
import { setContext, type Snippet } from 'svelte';
33
import { resolveChannel } from '../helpers/resolve.js';
4-
import type { BaseMarkProps, DataRecord, RawValue } from '../types.js';
4+
import type { BaseMarkProps, DataRecord, RawValue } from '../types/index.js';
55
66
let {
77
fx,

src/lib/core/FacetAxes.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
-->
55
<script lang="ts">
66
import { getContext } from 'svelte';
7-
import type { PlotContext } from '../types.js';
7+
import type { PlotContext } from '../types/index.js';
88
import { scaleBand } from 'd3-scale';
99
import BaseAxisX from '../marks/helpers/BaseAxisX.svelte';
1010
import BaseAxisY from '../marks/helpers/BaseAxisY.svelte';

src/lib/core/FacetGrid.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
-->
66
<script lang="ts">
77
import { getContext, type Snippet } from 'svelte';
8-
import type { PlotContext, GenericMarkOptions, Mark } from '../types.js';
8+
import type { PlotContext, GenericMarkOptions, Mark } from '../types/index.js';
99
import { scaleBand } from 'd3-scale';
1010
import Facet from './Facet.svelte';
1111
import { getEmptyFacets } from '../helpers/facets.js';

src/lib/core/Plot.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
PlotDefaults,
2323
PlotState,
2424
RawValue
25-
} from '../types.js';
25+
} from '../types/index.js';
2626
import FacetGrid from './FacetGrid.svelte';
2727
2828
import mergeDeep from '../helpers/mergeDeep.js';

src/lib/helpers/autoTicks.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export function autoTicks(
4242
if (interval) {
4343
const [lo, hi] = extent(domain);
4444
const I = maybeInterval(interval, type);
45-
return I.range(lo, I.offset(hi));
45+
return I.range(lo, I.offset(hi)).filter((d) => d >= lo && d <= hi);
4646
}
4747
return typeof scaleFn.ticks === 'function' ? scaleFn.ticks(count) : [];
4848
}

0 commit comments

Comments
 (0)