From 9ed36c6e9fda00954e7b4279397d64d60f3e217e Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sat, 31 Aug 2024 17:23:10 +0300 Subject: [PATCH 01/12] fix github issue & pr templates --- .github/ISSUE_TEMPLATE.md | 28 ++++++++++++++++------------ .github/PULL_REQUEST_TEMPLATE.md | 25 ++++++++++++++----------- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 0331978..790e888 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,15 +1,19 @@ -- **I'm submitting a ...** - [ ] bug report - [ ] feature request - [ ] question about the decisions made in the repository - [ ] question about how to use this project +**I'm submitting a ...** -- **Summary** +- [ ] bug report +- [ ] feature request +- [ ] question about the decisions made in the repository +- [ ] question about how to use this project -- **Link to minimal reproduction** - +**Summary** -- **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. StackOverflow, personal fork, etc.) +**Link to minimal reproduction** + + + +**Other information** + + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 5bd3fa4..1c40f1e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,17 +1,20 @@ -- **What kind of change does this PR introduce?** (Bug fix, feature, docs update, ...) +**What kind of change does this PR introduce?** -- **What is the current behavior?** (You can also link to an open issue here) + -- **What is the new behavior (if this is a feature change)?** +**What is the current behavior?** -- **Issue related to this PR** - +**What is the new behavior (if this is a feature change)?** - [ ] The changes have been discussed in an issue and the approach has been approved. +**Issue related to this PR** - issue: + -- **Other information**: +- [ ] The changes have been discussed in an issue and the approach has been approved. + +- issue link: + +**Other information**: From 929f0af452dacb28f341b47edabad3a0235507af Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sat, 31 Aug 2024 17:24:22 +0300 Subject: [PATCH 02/12] fix(types): fix library type definitions --- .vscode/settings.json | 3 ++- package.json | 4 ++-- scripts/patch-types.js | 6 +++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 5e5384b..2811134 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,6 +32,7 @@ Happy linting! 💖 "ticker", "utils", "store", - "styles" + "styles", + "types" ] } diff --git a/package.json b/package.json index bc71873..a882d72 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "serve": "live-server . --open=demo/ --watch=build,demo --cors --quiet", "watch": "nodemon --watch src -e \"*\" ./scripts/build.js --dev", "build": "run-s clean build:*", - "build:lib": "node ./scripts/build.js", "build:ts": "tsc --emitDeclarationOnly --outFile build/racing-bars.d.ts && node ./scripts/patch-types.js", + "build:lib": "node ./scripts/build.js", "build:ts-website": "cd website && npm run typecheck", "build:website": "npm run copy:data && cd website && npm run build", "copy:data": "recursive-copy data website/static/data", @@ -42,7 +42,7 @@ "lint:stylelint-website": "stylelint \"website/**/*.{css,scss}\"", "postinstall": "cd website && npm install", "reset": "git clean -dfx && git reset --hard && npm i", - "clean": "recursive-delete build && recursive-delete tmp && recursive-delete website/build && recursive-delete website/static/data && recursive-delete website/docs/api", + "clean": "recursive-delete build && recursive-delete tmp && recursive-delete website/build && recursive-delete website/static/data && recursive-delete website/static/lib && recursive-delete website/docs/api", "start-release": "node ./scripts/start-release.js" }, "dependencies": { diff --git a/scripts/patch-types.js b/scripts/patch-types.js index ef67c00..c7d91af 100644 --- a/scripts/patch-types.js +++ b/scripts/patch-types.js @@ -8,7 +8,11 @@ const patchTypes = async () => { .replace('declare module "index"', 'declare module "racing-bars"') .replace('from "index"', 'from "racing-bars"') .replace('declare module "react"', 'declare module "racing-bars/react"') - .replace('declare module "vue"', 'declare module "racing-bars/vue"'); + .replace('declare module "vue"', 'declare module "racing-bars/vue"') + .replace(/declare module "lib\//g, 'declare module "racing-bars/lib/') + .replace(/from "lib\//g, 'from "racing-bars/lib/') + .replace(/declare module "shared\//g, 'declare module "racing-bars/shared/') + .replace(/from "shared\//g, 'from "racing-bars/shared/'); fs.writeFile(path.resolve(dtsPath), patched); }; From 5160018b08c8a07683f8865cc9a194fac8cd2adb Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 14:14:06 +0300 Subject: [PATCH 03/12] fix(data): fix worker mixing data for multiple charts --- src/lib/utils/data.ts | 18 ++++++++---------- src/lib/worker/index.ts | 4 ++-- website/docs/guides/multiple-charts.md | 2 +- website/docs/index.md | 3 --- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/src/lib/utils/data.ts b/src/lib/utils/data.ts index a7c6b8a..eac4cfd 100644 --- a/src/lib/utils/data.ts +++ b/src/lib/utils/data.ts @@ -6,7 +6,7 @@ import { loadData } from '../load-data'; // eslint-disable-next-line import/no-internal-modules import workerSrc from '../../../tmp/racing-bars.worker.js'; import { getDates, getNextDate } from './dates'; -import { createWorkerFromContent } from './utils'; +import { createWorkerFromContent, generateId } from './utils'; const worker = createWorkerFromContent(workerSrc); @@ -22,22 +22,20 @@ export async function prepareData( } data = dataTransform(await data); } + const messageId = generateId(); worker.postMessage({ type: 'prepare-data', data, options: removeFnOptions(store.getState().options), baseUrl: location.href, + messageId, }); const preparedData = await new Promise((resolve) => { - worker.addEventListener( - 'message', - (event) => { - if (event.data.type === 'data-prepared') { - resolve(event.data.data); - } - }, - { once: true }, - ); + worker.addEventListener('message', (event) => { + if (event.data.type === 'data-prepared' && event.data.messageId === messageId) { + resolve(event.data.data); + } + }); }); storeDataCollections(preparedData, store, changingOptions); return preparedData; diff --git a/src/lib/worker/index.ts b/src/lib/worker/index.ts index f9a0a57..561caf8 100644 --- a/src/lib/worker/index.ts +++ b/src/lib/worker/index.ts @@ -3,9 +3,9 @@ import { prepareData } from './prepare-data'; const worker: Worker = self as any as Worker; worker.addEventListener('message', async (event) => { - const { type, data, options, baseUrl } = event.data; + const { type, data, options, baseUrl, messageId } = event.data; if (type === 'prepare-data') { const result = await prepareData(data, options, baseUrl); - worker.postMessage({ type: 'data-prepared', data: result }); + worker.postMessage({ type: 'data-prepared', data: result, messageId }); } }); diff --git a/website/docs/guides/multiple-charts.md b/website/docs/guides/multiple-charts.md index b761db9..b229070 100644 --- a/website/docs/guides/multiple-charts.md +++ b/website/docs/guides/multiple-charts.md @@ -14,7 +14,7 @@ Example:
-
From 0734f6aad30d6aa1755212e7b234390f18f61903 Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 14:20:14 +0300 Subject: [PATCH 04/12] remove eventListener when correct data is received from worker --- src/lib/utils/data.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/lib/utils/data.ts b/src/lib/utils/data.ts index eac4cfd..1a459e9 100644 --- a/src/lib/utils/data.ts +++ b/src/lib/utils/data.ts @@ -31,11 +31,13 @@ export async function prepareData( messageId, }); const preparedData = await new Promise((resolve) => { - worker.addEventListener('message', (event) => { + const onMessage = (event: MessageEvent) => { if (event.data.type === 'data-prepared' && event.data.messageId === messageId) { resolve(event.data.data); + worker.removeEventListener('message', onMessage); } - }); + }; + worker.addEventListener('message', onMessage); }); storeDataCollections(preparedData, store, changingOptions); return preparedData; From b30dbb5b0d8a478f8a11d421da5575b537f0139d Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 14:29:36 +0300 Subject: [PATCH 05/12] build(website): allow cors on netlify deploy preview --- website/static/_headers | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 website/static/_headers diff --git a/website/static/_headers b/website/static/_headers new file mode 100644 index 0000000..c776a47 --- /dev/null +++ b/website/static/_headers @@ -0,0 +1,2 @@ +/* + Access-Control-Allow-Origin: * From 9030de44ce89fb4552aa8508983fb1e4f0570cad Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 18:10:30 +0300 Subject: [PATCH 06/12] feat(options): auto detect `dataType` --- src/lib/load-data.ts | 22 +++++++++++++++++++--- src/lib/options/options.models.ts | 2 +- src/lib/options/options.reducer.ts | 2 +- src/lib/worker/prepare-data.ts | 2 +- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/lib/load-data.ts b/src/lib/load-data.ts index 1949568..cb5b631 100644 --- a/src/lib/load-data.ts +++ b/src/lib/load-data.ts @@ -1,14 +1,30 @@ import { json, csv, tsv, xml } from './d3'; -import type { Data, WideData } from './data'; +import type { Options, Data, WideData } from './index'; export function loadData( url: string, - type: 'json' | 'csv' | 'tsv' | 'xml' = 'json', + type: Options['dataType'] = 'auto', ): Promise | Promise { + const supportedTypes: Array> = ['json', 'csv', 'tsv', 'xml']; + const isSupported = (t: any) => supportedTypes.includes(t); + + const detectDataType = () => { + const t = type.toLowerCase(); + if (isSupported(t)) { + return t; + } + const extension = url.split('.').pop()?.toLowerCase() || ''; + if (isSupported(extension)) { + return extension; + } + return 'json'; + }; + const handleError = () => { throw new Error(`Failed to load data as ${type.toUpperCase()} from ${url}`); }; - switch (type) { + + switch (detectDataType()) { case 'json': return json(url).catch(handleError) as Promise | Promise; case 'csv': diff --git a/src/lib/options/options.models.ts b/src/lib/options/options.models.ts index 644292b..0fc1f7c 100644 --- a/src/lib/options/options.models.ts +++ b/src/lib/options/options.models.ts @@ -7,7 +7,7 @@ export interface OptionsAction extends Action { export interface Options { dataShape: 'long' | 'wide'; - dataType: 'json' | 'csv' | 'tsv' | 'xml'; + dataType: 'json' | 'csv' | 'tsv' | 'xml' | 'auto'; dataTransform: null | ((data: Data[] | WideData[]) => Data[] | WideData[]); fillDateGapsInterval: null | 'year' | 'month' | 'day'; fillDateGapsValue: 'last' | 'interpolate'; diff --git a/src/lib/options/options.reducer.ts b/src/lib/options/options.reducer.ts index 05b9a64..1ddf4e3 100644 --- a/src/lib/options/options.reducer.ts +++ b/src/lib/options/options.reducer.ts @@ -5,7 +5,7 @@ import { actionTypes } from './options.actions'; export const defaultOptions: Options = { dataShape: 'long', - dataType: 'json', + dataType: 'auto', dataTransform: null, fillDateGapsInterval: null, fillDateGapsValue: 'interpolate', diff --git a/src/lib/worker/prepare-data.ts b/src/lib/worker/prepare-data.ts index 2ed56bc..052e791 100644 --- a/src/lib/worker/prepare-data.ts +++ b/src/lib/worker/prepare-data.ts @@ -22,7 +22,7 @@ export function prepareData( function fetchData( data: Data[] | WideData[] | Promise | Promise | string, - dataType: 'json' | 'csv' | 'tsv' | 'xml', + dataType: Options['dataType'], baseUrl: string, ) { if (typeof data === 'string') { From 544c39d56f5bf6e914f080e5d3c235e5b8455bfd Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 18:11:18 +0300 Subject: [PATCH 07/12] feat(data): handle empty or invalid data --- src/lib/worker/prepare-data.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/lib/worker/prepare-data.ts b/src/lib/worker/prepare-data.ts index 052e791..08e0b00 100644 --- a/src/lib/worker/prepare-data.ts +++ b/src/lib/worker/prepare-data.ts @@ -12,6 +12,7 @@ export function prepareData( baseUrl: string, ): Promise { return fetchData(data, options.dataType, baseUrl) + .then(handleEmptyData) .then(filterByDate(options.startDate, options.endDate)) .then(wideDataToLong(options.dataShape)) .then(processFixedOrder(options.fixedOrder)) @@ -43,6 +44,12 @@ function isRelativeUrl(url: string) { return !url.startsWith('https://') && !url.startsWith('http://') && !url.startsWith('data:'); } +function handleEmptyData(data: Data[] | WideData[]): Data[] | WideData[] { + return !Array.isArray(data) || data.length === 0 + ? [{ date: getDateString(new Date()), value: 0, name: '' }] + : data; +} + function filterByDate(startDate: string, endDate: string) { return function (data: Data[] | WideData[]): Data[] | WideData[] { return data From 5ede0f7a02a60d2d66e3ddd7dcca4a4be57423a5 Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 18:12:27 +0300 Subject: [PATCH 08/12] feat(data): auto detect data shape --- src/lib/options/options.models.ts | 2 +- src/lib/options/options.reducer.ts | 2 +- src/lib/worker/prepare-data.ts | 13 ++++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/lib/options/options.models.ts b/src/lib/options/options.models.ts index 0fc1f7c..b120c37 100644 --- a/src/lib/options/options.models.ts +++ b/src/lib/options/options.models.ts @@ -6,7 +6,7 @@ export interface OptionsAction extends Action { } export interface Options { - dataShape: 'long' | 'wide'; + dataShape: 'long' | 'wide' | 'auto'; dataType: 'json' | 'csv' | 'tsv' | 'xml' | 'auto'; dataTransform: null | ((data: Data[] | WideData[]) => Data[] | WideData[]); fillDateGapsInterval: null | 'year' | 'month' | 'day'; diff --git a/src/lib/options/options.reducer.ts b/src/lib/options/options.reducer.ts index 1ddf4e3..77cf689 100644 --- a/src/lib/options/options.reducer.ts +++ b/src/lib/options/options.reducer.ts @@ -4,7 +4,7 @@ import type { Options, OptionsAction } from './options.models'; import { actionTypes } from './options.actions'; export const defaultOptions: Options = { - dataShape: 'long', + dataShape: 'auto', dataType: 'auto', dataTransform: null, fillDateGapsInterval: null, diff --git a/src/lib/worker/prepare-data.ts b/src/lib/worker/prepare-data.ts index 08e0b00..b26d410 100644 --- a/src/lib/worker/prepare-data.ts +++ b/src/lib/worker/prepare-data.ts @@ -114,9 +114,20 @@ function calculateLastValues(makeCumulative = false) { }; } +function detectDataShape(data: Data[] | WideData[], dataShape: Options['dataShape']) { + if (dataShape === 'long' || dataShape === 'wide') return dataShape; + const firstRow = data[0]; + if ('date' in firstRow && 'name' in firstRow && 'value' in firstRow) { + return 'long'; + } + return 'wide'; +} + function wideDataToLong(dataShape: Options['dataShape'], nested = false) { return function (data: WideData[]) { - if (dataShape === 'long') return data as Data[]; + if (dataShape === 'long' || detectDataShape(data, dataShape) === 'long') { + return data as Data[]; + } const long = [] as Data[]; data.forEach((row) => { From a6828e9aaf5af53e6361b7a7c3766c6faaf40332 Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 18:25:27 +0300 Subject: [PATCH 09/12] docs(options): edit docs to add `dataShape="auto"` and `dataType="auto"` --- website/docs/documentation/options.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/website/docs/documentation/options.md b/website/docs/documentation/options.md index f4c4df7..f375413 100644 --- a/website/docs/documentation/options.md +++ b/website/docs/documentation/options.md @@ -175,11 +175,11 @@ See the guide on [`chart controls`](../guides/chart-controls.md) for other alter ### dataShape -Instruction whether the data shape is "long" or "wide". +Instruction whether the data shape is "long" or "wide". By default, the library tries to detect the data shape automatically from its structure (after any [transformation](#dataTransform), by finding the columns `date`, `name` and `value`). If the data shape is not detected correctly, it can be manually specified. See ["Data" section](./data.md) for more details and examples. -- Type: `"long" | "wide"` -- Default: `"long"` +- Type: `"long" | "wide" | "auto"` +- Default: `"auto"` - Example: This example uses `"wide"` data shape @@ -243,17 +243,18 @@ So it would be more convenient to be able to also pass a transformation function ### dataType -When a URL to a file containing the data is supplied as the first argument to the [`race`](./api.md#race) function, -the type of that file can be specified using the `"dataType"` option. +When a URL to a file containing the data is supplied as the first argument to the [`race`](./api.md#race) function, the type of that file can be specified using the `"dataType"` option. +By default, the library will try to detect the data type automatically from the file extension, otherwise it is assumed to be `"json"`. -- Type: `"json" | "csv" | "tsv" | "xml"` -- Default: `"json"` +- Type: `"json" | "csv" | "tsv" | "xml" | "auto"` +- Default: `"auto"` - Example: -This example uses `"csv"` data type +These examples use `"csv"` data type ```js -race('/data.csv', '#race', { dataType: 'csv' }); +race('/data.csv', '#race'); +race('/data', '#race', { dataType: 'csv' }); ``` ### dateCounter From eb0a2ecc983d910f205a81614476a14445fc509e Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 18:34:34 +0300 Subject: [PATCH 10/12] refactor(website): update gallery demos to not include `dataType` --- website/docs/gallery/_gallery-demos.ts | 41 -------------------------- 1 file changed, 41 deletions(-) diff --git a/website/docs/gallery/_gallery-demos.ts b/website/docs/gallery/_gallery-demos.ts index 4e8e3a9..4bd3d2d 100644 --- a/website/docs/gallery/_gallery-demos.ts +++ b/website/docs/gallery/_gallery-demos.ts @@ -7,14 +7,12 @@ type ChartProps = Props & { export const autorunFalse: ChartProps = { label: 'Autorun disabled', dataUrl: '/data/population.csv', - dataType: 'csv', autorun: false, }; export const captionDataFunction: ChartProps = { label: 'Caption (data function)', dataUrl: '/data/population.csv', - dataType: 'csv', caption: (_currentDate, dateSlice, _allDates) => `Total: ${Math.round(dateSlice.reduce((acc, curr) => acc + curr.value, 0))}`, dynamicProps: { @@ -26,14 +24,12 @@ export const captionDataFunction: ChartProps = { export const captionString: ChartProps = { label: 'Caption (string)', dataUrl: '/data/population.csv', - dataType: 'csv', caption: 'Source: World Bank', }; export const colorMapGroups: ChartProps = { label: 'Color Map for Groups', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', colorMap: { Asia: 'yellow', @@ -45,7 +41,6 @@ export const colorMapGroups: ChartProps = { export const colorMap: ChartProps = { label: 'Color Map', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', colorMap: { India: 'orange', @@ -57,7 +52,6 @@ export const colorMap: ChartProps = { export const colorPalette: ChartProps = { label: 'Color Palette', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', colorMap: [ '#636EFA', @@ -77,7 +71,6 @@ export const colorPalette: ChartProps = { export const colorSeedRandom: ChartProps = { label: 'Random Color Seed', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', colorSeed: Math.round(Math.random() * 100), dynamicProps: { colorSeed: 'Math.round(Math.random() * 100)' }, @@ -86,7 +79,6 @@ export const colorSeedRandom: ChartProps = { export const colorSeed: ChartProps = { label: 'Color Seed', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', colorSeed: 42, showGroups: false, @@ -95,7 +87,6 @@ export const colorSeed: ChartProps = { export const controlButtonsAll: ChartProps = { label: 'Control Buttons: All', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', subTitle: 'in millions', controlButtons: 'all', @@ -104,7 +95,6 @@ export const controlButtonsAll: ChartProps = { export const controlButtonsPlay: ChartProps = { label: 'Control Buttons: Play', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', subTitle: 'in millions', controlButtons: 'play', @@ -113,7 +103,6 @@ export const controlButtonsPlay: ChartProps = { export const controlButtonsNone: ChartProps = { label: 'Control Buttons: None', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', subTitle: 'in millions', controlButtons: 'none', @@ -122,7 +111,6 @@ export const controlButtonsNone: ChartProps = { export const cumulativeSum: ChartProps = { label: 'Cumulative Sum', dataUrl: '/data/gh-star.csv', - dataType: 'csv', title: 'Top Programming Languages', subTitle: 'Github Stars', makeCumulative: true, @@ -131,7 +119,6 @@ export const cumulativeSum: ChartProps = { export const datasetBrands: ChartProps = { label: 'Brand Values Dataset', dataUrl: '/data/brands.csv', - dataType: 'csv', title: '18 years of Top Global Brands', subTitle: 'Brand value, $m', colorSeed: 45, @@ -140,7 +127,6 @@ export const datasetBrands: ChartProps = { export const datasetCovid: ChartProps = { label: 'Covid-19 Dataset', dataUrl: '/data/covid-19.csv', - dataType: 'csv', title: 'Covid-19', subTitle: 'Number of confirmed cases', dateCounter: 'MMM DD, YYYY', @@ -150,7 +136,6 @@ export const datasetCovid: ChartProps = { export const datasetGdp: ChartProps = { label: 'GDP Dataset', dataUrl: '/data/gdp.csv', - dataType: 'csv', dataTransform: (data) => data.map((d) => ({ ...d, @@ -169,7 +154,6 @@ export const datasetGdp: ChartProps = { export const datasetGhPush: ChartProps = { label: 'GitHub Push Events Dataset', dataUrl: '/data/gh-push.csv', - dataType: 'csv', title: 'Top Programming Languages', subTitle: 'Github Push Events', dateCounter: (currentDate, _dateSlice, _allDates) => { @@ -193,7 +177,6 @@ export const datasetGhPush: ChartProps = { export const datasetGhStars: ChartProps = { label: 'GitHub Stars Dataset', dataUrl: '/data/gh-star.csv', - dataType: 'csv', title: 'Top Programming Languages', subTitle: 'Github Stars', makeCumulative: true, @@ -218,7 +201,6 @@ export const datasetGhStars: ChartProps = { export const datasetPopulation: ChartProps = { label: 'Population Dataset', dataUrl: '/data/population.csv', - dataType: 'csv', dataTransform: (data) => data.map((d) => ({ ...d, @@ -238,7 +220,6 @@ export const datasetPopulation: ChartProps = { export const dataTransform: ChartProps = { label: 'Data Transform', dataUrl: '/data/population.csv', - dataType: 'csv', dataTransform: (data) => data.map((d) => ({ ...d, @@ -255,14 +236,12 @@ export const dataTransform: ChartProps = { export const dateCounterFormat: ChartProps = { label: 'Date Counter (format)', dataUrl: '/data/population.csv', - dataType: 'csv', dateCounter: 'MMM DD, YYYY 🌍', }; export const dateCounterDataFunction: ChartProps = { label: 'Date Counter (data function)', dataUrl: '/data/population.csv', - dataType: 'csv', dateCounter: (currentDate, _dateSlice, allDates) => `${allDates.indexOf(currentDate) + 1} of ${allDates.length}`, dynamicProps: { @@ -274,7 +253,6 @@ export const dateCounterDataFunction: ChartProps = { export const fillDateGapsNull: ChartProps = { label: 'Filling Date Gaps: null (default)', dataUrl: '/data/population.csv', - dataType: 'csv', fillDateGapsInterval: null, dataTransform: function multiplyBy1000(data) { return data.map((d) => ({ @@ -295,7 +273,6 @@ return data.map((d) => ({ export const fillDateGapsMonthInterpolate: ChartProps = { label: 'Filling Date Gaps: month - interpolate', dataUrl: '/data/population.csv', - dataType: 'csv', fillDateGapsInterval: 'month', fillDateGapsValue: 'interpolate', dataTransform: function multiplyBy1000(data) { @@ -317,7 +294,6 @@ return data.map((d) => ({ export const fillDateGapsMonthLast: ChartProps = { label: 'Filling Date Gaps: month - last', dataUrl: '/data/population.csv', - dataType: 'csv', fillDateGapsInterval: 'month', fillDateGapsValue: 'last', dataTransform: function multiplyBy1000(data) { @@ -339,7 +315,6 @@ return data.map((d) => ({ export const fixedOrder: ChartProps = { label: 'Fixed Order', dataUrl: '/data/population.csv', - dataType: 'csv', dateCounter: 'YYYY', fixedOrder: ['Algeria', 'Italy', 'Canada', 'France', 'Argentina'], topN: 3, @@ -349,7 +324,6 @@ export const fixedOrder: ChartProps = { export const fixedScale: ChartProps = { label: 'Fixed Scale', dataUrl: '/data/covid-19.csv', - dataType: 'csv', title: 'Covid-19 Confirmed Cases', fixedScale: true, labelsPosition: 'outside', @@ -358,7 +332,6 @@ export const fixedScale: ChartProps = { export const highlightBars: ChartProps = { label: 'Highlight Bars', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', highlightBars: true, }; @@ -366,7 +339,6 @@ export const highlightBars: ChartProps = { export const icons: ChartProps = { label: 'Icons', dataUrl: '/data/population.csv', - dataType: 'csv', dataTransform: (data) => data.map((d) => ({ ...d, @@ -385,7 +357,6 @@ export const icons: ChartProps = { export const keyboardControls: ChartProps = { label: 'Keyboard Controls', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', keyboardControls: true, }; @@ -393,7 +364,6 @@ export const keyboardControls: ChartProps = { export const labelsPosition: ChartProps = { label: 'Labels Position', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', labelsPosition: 'outside', }; @@ -401,7 +371,6 @@ export const labelsPosition: ChartProps = { export const loop: ChartProps = { label: 'Loop', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', startDate: '1970-01-01', endDate: '1980-01-01', @@ -411,7 +380,6 @@ export const loop: ChartProps = { export const margins: ChartProps = { label: 'Margins', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', marginTop: 40, marginBottom: 40, @@ -423,7 +391,6 @@ export const margins: ChartProps = { export const mouseControls: ChartProps = { label: 'Mouse Controls', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', mouseControls: true, showGroups: true, @@ -432,7 +399,6 @@ export const mouseControls: ChartProps = { export const overlays: ChartProps = { label: 'Overlays', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', overlays: 'all', autorun: false, @@ -442,7 +408,6 @@ export const overlays: ChartProps = { export const selectBars: ChartProps = { label: 'Select Bars', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', selectBars: true, }; @@ -450,7 +415,6 @@ export const selectBars: ChartProps = { export const showGroups: ChartProps = { label: 'Show Groups', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', showGroups: true, }; @@ -458,7 +422,6 @@ export const showGroups: ChartProps = { export const startEndDates: ChartProps = { label: 'Start and End Dates', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', startDate: '1970-01-01', endDate: '1999-12-31', @@ -467,7 +430,6 @@ export const startEndDates: ChartProps = { export const themeDark: ChartProps = { label: 'Dark Theme', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', theme: 'dark', }; @@ -475,7 +437,6 @@ export const themeDark: ChartProps = { export const tickDuration: ChartProps = { label: 'Chart Speed (tickDuration)', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', tickDuration: 100, }; @@ -483,7 +444,6 @@ export const tickDuration: ChartProps = { export const titleSubtitle: ChartProps = { label: 'Title and Sub-Title', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', subTitle: 'in millions', }; @@ -491,7 +451,6 @@ export const titleSubtitle: ChartProps = { export const topN: ChartProps = { label: 'Top N', dataUrl: '/data/population.csv', - dataType: 'csv', title: 'World Population', topN: 5, }; From cbfdb428965ac011cb9dfc913c200235c5a8885c Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 18:49:01 +0300 Subject: [PATCH 11/12] edit docs --- website/docs/documentation/data.md | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/website/docs/documentation/data.md b/website/docs/documentation/data.md index fc1777c..e9afa84 100644 --- a/website/docs/documentation/data.md +++ b/website/docs/documentation/data.md @@ -142,7 +142,9 @@ race(data, '#race'); #### Load data from URL Data can be loaded from a URL. The following formats are supported: -`json` (default), `csv`, `tsv` and `xml`. +`json`, `csv`, `tsv` and `xml`. + +Data type is automatically detected by file extension, otherwise `json` is assumed. - Load JSON from URL @@ -216,7 +218,7 @@ date,Canada,Egypt,Greece,Panama,Singapore ### Usage -For wide data to be processed, the [`options`](./options.md) object should have the field [`dataShape`](./options.md#datashape) set to `"wide"` +For wide data to be processed, the [`options`](./options.md) object should have the field [`dataShape`](./options.md#datashape) set (or auto-detected) to `"wide"` - JS array of objects @@ -281,70 +283,70 @@ Example for long data with [optional fields](#long-data): "date": "2017-01-01", "name": "Egypt", "value": 96.44, - "icon": "https://www.countryflags.io/eg/flat/64.png", + "icon": "https://flagsapi.com/EG/flat/64.png", "group": "Africa" }, { "date": "2017-01-01", "name": "Singapore", "value": 5.61, - "icon": "https://www.countryflags.io/sg/flat/64.png", + "icon": "https://flagsapi.com/SG/flat/64.png", "group": "Asia" }, { "date": "2017-01-01", "name": "Greece", "value": 10.75, - "icon": "https://www.countryflags.io/gr/flat/64.png", + "icon": "https://flagsapi.com/GR/flat/64.png", "group": "Europe" }, { "date": "2017-01-01", "name": "Panama", "value": 4.11, - "icon": "https://www.countryflags.io/pa/flat/64.png", + "icon": "https://flagsapi.com/PA/flat/64.png", "group": "North America" }, { "date": "2018-01-01", "name": "Greece", "value": 10.73, - "icon": "https://www.countryflags.io/gr/flat/64.png", + "icon": "https://flagsapi.com/GR/flat/64.png", "group": "Europe" }, { "date": "2018-01-01", "name": "Singapore", "value": 5.64, - "icon": "https://www.countryflags.io/sg/flat/64.png", + "icon": "https://flagsapi.com/SG/flat/64.png", "group": "Asia" }, { "date": "2018-01-01", "name": "Canada", "value": 37.06, - "icon": "https://www.countryflags.io/ca/flat/64.png", + "icon": "https://flagsapi.com/CA/flat/64.png", "group": "North America" }, { "date": "2018-01-01", "name": "Egypt", "value": 98.42, - "icon": "https://www.countryflags.io/eg/flat/64.png", + "icon": "https://flagsapi.com/EG/flat/64.png", "group": "Africa" }, { "date": "2017-01-01", "name": "Canada", "value": 36.54, - "icon": "https://www.countryflags.io/ca/flat/64.png", + "icon": "https://flagsapi.com/CA/flat/64.png", "group": "North America" }, { "date": "2018-01-01", "name": "Panama", "value": 4.18, - "icon": "https://www.countryflags.io/pa/flat/64.png", + "icon": "https://flagsapi.com/PA/flat/64.png", "group": "North America" } ] From a9f07eec07b4a1860dd592c26b2b14d6a38e97b4 Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 1 Sep 2024 20:18:59 +0300 Subject: [PATCH 12/12] release: v0.2.0 --- CHANGELOG.md | 15 +++++++++++++++ src/package.lib.json | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f3b3cf..efbcd1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file. See [standa --- +## [v0.2.0](https://github.com/hatemhosny/racing-bars/compare/v0.1.2...v0.2.0) (2024-09-01) + +### Bug Fixes + +- **data:** fix worker mixing data for multiple charts ([5160018](https://github.com/hatemhosny/racing-bars/commit/5160018b08c8a07683f8865cc9a194fac8cd2adb)) +- **types:** fix library type definitions ([929f0af](https://github.com/hatemhosny/racing-bars/commit/929f0af452dacb28f341b47edabad3a0235507af)) + +### Features + +- **data:** auto detect `dataShape` ([5ede0f7](https://github.com/hatemhosny/racing-bars/commit/5ede0f7a02a60d2d66e3ddd7dcca4a4be57423a5)) +- **data:** handle empty or invalid data ([544c39d](https://github.com/hatemhosny/racing-bars/commit/544c39d56f5bf6e914f080e5d3c235e5b8455bfd)) +- **options:** auto detect `dataType` ([9030de4](https://github.com/hatemhosny/racing-bars/commit/9030de44ce89fb4552aa8508983fb1e4f0570cad)) + +--- + ## [v0.1.2](https://github.com/hatemhosny/racing-bars/compare/v0.1.1...v0.1.2) (2024-08-30) ### Bug Fixes diff --git a/src/package.lib.json b/src/package.lib.json index cfb69e0..a3b10d3 100644 --- a/src/package.lib.json +++ b/src/package.lib.json @@ -1,6 +1,6 @@ { "name": "racing-bars", - "version": "0.1.2", + "version": "0.2.0", "description": "Bar chart race made easy 📶", "author": "Hatem Hosny", "license": "MIT",