{"_id":"@data-fair/app-chord-diagram","_rev":"4-e7d8a4074abc3cdbe4b1c3dcd3ed1b14","name":"@data-fair/app-chord-diagram","dist-tags":{"latest":"1.0.0"},"versions":{"0.1.0":{"name":"@data-fair/app-chord-diagram","version":"0.1.0","_id":"@data-fair/app-chord-diagram@0.1.0","maintainers":[{"name":"albanm","email":"alban.mouton@gmail.com"},{"name":"bonnel-n","email":"nicolas.bonnel@gmail.com"}],"dist":{"shasum":"a8c758f6edb669cdef5eb1eb33f0dd7fc06fbd62","tarball":"https://registry.npmjs.org/@data-fair/app-chord-diagram/-/app-chord-diagram-0.1.0.tgz","fileCount":20,"integrity":"sha512-1qPf/Ol1xhLV9c5ytbMUft/7/AFjndXftT9gQoCa1SGd0n8QpDetLxCjW0x3NfNr95MnVu6SIfF0zev48AKSHg==","signatures":[{"sig":"MEQCIBsvmdDUMqWHfD2TsgNd7hFzXUQO7Vh6p2VavUJ/33CUAiBjXsxeOkBVPxfdt09jeNNtTYKLBsWysamxuEP64oD1SA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":4431380},"gitHead":"98c61f15cdb0b9de2b0d136348912c1e4632ce9b","scripts":{"dev":"cross-env df-dev-server","lint":"eslint . --fix","build":"rm -rf dist && PUBLIC_URL=https://cdn.jsdelivr.net/npm/@data-fair/app-dashboards@${npm_package_version}/dist nuxt generate && rm dist && cp -rf .output/public ./dist","dev-src":"nuxt dev","prepublishOnly":"npm run build"},"_npmUser":{"name":"bonnel-n","email":"nicolas.bonnel@gmail.com"},"_npmVersion":"9.6.7","description":"This template should help get you started developing with Vue 3 in Vite.","directories":{},"_nodeVersion":"16.13.2","dependencies":{"nuxt":"3.5.2","axios":"^1.5.0","d3-chord":"^3.0.1","d3-shape":"^3.2.0","google-palette":"^1.1.1","vue-window-size":"^2.0.0","vite-plugin-vuetify":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.48.0","cross-env":"^7.0.3","@types/node":"^18","@data-fair/dev-server":"^1.12.0","@nuxtjs/eslint-config-typescript":"^12.0.0","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/app-chord-diagram_0.1.0_1698325391259_0.9719303595134792","host":"s3://npm-registry-packages"}},"0.1.1":{"name":"@data-fair/app-chord-diagram","version":"0.1.1","_id":"@data-fair/app-chord-diagram@0.1.1","maintainers":[{"name":"albanm","email":"alban.mouton@gmail.com"},{"name":"bonnel-n","email":"nicolas.bonnel@gmail.com"}],"dist":{"shasum":"de405a929de701f8a2f8627436a041ce609fcc26","tarball":"https://registry.npmjs.org/@data-fair/app-chord-diagram/-/app-chord-diagram-0.1.1.tgz","fileCount":21,"integrity":"sha512-agKr3GAVd3LjHYzYDxsuqNiGqrsjWKQ04+trrx+oc6VjaLqWQovfQN4PRETkqIam/rmUE70aIKzoog4jVe6IYQ==","signatures":[{"sig":"MEUCIQDVkofNUmmyhtQhCW8R/4dMKOTiO9LmBPtUllK2L5ChmgIgfbd4E1QceJ3ZtJoqxCdNZQ1li5nHf6hhC+QtI0+ZEE0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":4613349},"gitHead":"6c940e03504e4a153700bf1b79aa0c6d308ea3e6","scripts":{"dev":"cross-env df-dev-server","lint":"eslint . --fix","build":"rm -rf dist && PUBLIC_URL=https://cdn.jsdelivr.net/npm/@data-fair/app-chord-diagram@${npm_package_version}/dist nuxt generate && rm dist && cp -rf .output/public ./dist","dev-src":"nuxt dev","prepublishOnly":"npm run build"},"_npmUser":{"name":"bonnel-n","email":"nicolas.bonnel@gmail.com"},"_npmVersion":"9.6.7","description":"This template should help get you started developing with Vue 3 in Vite.","directories":{},"_nodeVersion":"16.13.2","dependencies":{"nuxt":"3.5.2","axios":"^1.5.0","d3-chord":"^3.0.1","d3-shape":"^3.2.0","google-palette":"^1.1.1","vue-window-size":"^2.0.0","vite-plugin-vuetify":"^1.0.2"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^8.48.0","cross-env":"^7.0.3","@types/node":"^18","@data-fair/dev-server":"^1.12.0","@nuxtjs/eslint-config-typescript":"^12.0.0","@typescript-eslint/eslint-plugin":"^5.59.8"},"_npmOperationalInternal":{"tmp":"tmp/app-chord-diagram_0.1.1_1698325828497_0.9322832268119803","host":"s3://npm-registry-packages"}},"1.0.0":{"name":"@data-fair/app-chord-diagram","version":"1.0.0","description":"Application data-fair : diagramme de cordes des flux entre deux champs d'un jeu de données","type":"module","scripts":{"dev":"df-dev-env && dotenv -- zellij --layout .zellij.kdl","dev-server":"df-dev-server","dev-app":"vite","build":"vite build","prepublishOnly":"PUBLIC_URL=https://cdn.jsdelivr.net/npm/@data-fair/app-chord-diagram@${npm_package_version}/dist npm run build","build-types":"df-build-types src/config","lint":"eslint .","lint-fix":"eslint --fix .","prepare":"husky || true","type-check":"vue-tsc --noEmit","test":"df-dev-env && dotenv -- playwright test --max-failures=1","test-unit":"playwright test --project unit","test-e2e":"df-dev-env && dotenv -- playwright test --project e2e","quality":"npm run lint && npm run build-types && npm run type-check && npm run build && npm test && npm audit --omit=dev --audit-level=critical"},"dependencies":{"@data-fair/lib-utils":"^1.13.1","@data-fair/lib-vue":"^1.30.1","@data-fair/lib-vuetify":"^2.4.3","@mdi/js":"^7.4.47","@vueuse/core":"^14.4.0","chroma-js":"^3.2.0","d3-chord":"^3.0.1","d3-shape":"^3.2.0","dayjs":"^1.11.23","ofetch":"^1.5.1","vue":"^3.5.42","vue-i18n":"^11.4.10","vuetify":"^4.1.12"},"devDependencies":{"@commitlint/cli":"^19.8.0","@commitlint/config-conventional":"^19.8.0","@data-fair/dev-server":"^2.5.0","@data-fair/lib-common-types":"^1.22.0","@data-fair/lib-types-builder":"^1.14.3","@intlify/unplugin-vue-i18n":"^11.2.5","@playwright/test":"^1.62.1","@types/chroma-js":"^3.1.2","@types/d3-chord":"^3.0.6","@types/d3-shape":"^3.1.7","@types/node":"^24.0.0","@typescript-eslint/parser":"^8.68.0","@vitejs/plugin-vue":"^6.0.8","dotenv-cli":"^11.0.0","eslint":"^9.39.5","eslint-plugin-vue":"^10.10.0","eslint-plugin-vuetify":"^2.7.2","husky":"^9.1.7","neostandard":"^0.13.0","sass-embedded":"^1.103.1","typescript":"^6.0.3","vite":"^8.2.2","vite-plugin-vuetify":"^2.1.3","vue-eslint-parser":"^10.4.1","vue-tsc":"^3.3.11"},"gitHead":"2aaee5dafcae2c9ac4e824428fdd2dcc9ca6db72","_id":"@data-fair/app-chord-diagram@1.0.0","_nodeVersion":"24.17.0","_npmVersion":"11.13.0","dist":{"integrity":"sha512-VQBtnH3CiRGAQRbGm8wZOQOS87vVjxqo9dVJ3FP9LKVkCzHb0wmVr5Y0ZrwPRR7mflTphK3tbU2zGdHnec8TBg==","shasum":"48def14216fb6f11df74bdbd7da53e6a1cfcb731","tarball":"https://registry.npmjs.org/@data-fair/app-chord-diagram/-/app-chord-diagram-1.0.0.tgz","fileCount":11,"unpackedSize":885831,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCICYOh/ZA6lubt2hdKj6FWu9kilzTT6m3PsjGEBwWvV/RAiAZ7egiwCYhhg69bM1Vn+8Ek+Q2+rJaIW3vaAGSYGxPIA=="}]},"_npmUser":{"name":"bonnel-n","email":"nicolas.bonnel@gmail.com"},"directories":{},"maintainers":[{"name":"albanm","email":"alban.mouton@gmail.com"},{"name":"bonnel-n","email":"nicolas.bonnel@gmail.com"},{"name":"batledev","email":"baptiste.guerny@koumoul.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/app-chord-diagram_1.0.0_1788947090260_0.319732174592942"},"_hasShrinkwrap":false}},"time":{"created":"2023-10-26T13:03:11.189Z","modified":"2026-09-09T09:44:50.583Z","0.1.0":"2023-10-26T13:03:11.624Z","0.1.1":"2023-10-26T13:10:29.057Z","1.0.0":"2026-09-09T09:44:50.406Z"},"description":"Application data-fair : diagramme de cordes des flux entre deux champs d'un jeu de données","maintainers":[{"name":"albanm","email":"alban.mouton@gmail.com"},{"name":"bonnel-n","email":"nicolas.bonnel@gmail.com"},{"name":"batledev","email":"baptiste.guerny@koumoul.com"}],"readme":"# Chord diagram\n\nA [data-fair](https://koumoul-dev.github.io/data-fair/) application: a chord diagram showing the flows between the\nvalues of two text fields of a dataset — one arc per value, one ribbon per pair of connected values, sized by the\naggregated flow.\n\n## Identifiers\n\nThe repository, the folder and the package are named `app-chord-diagram`. The `application-name` meta of\n`index.html` is `chord-diagram`: it is the key data-fair uses to group the versions of a single application and to\noffer version upgrades, so it must stay stable across releases.\n\nThe `version` of the package is managed by maintainers at release time — never bump it as a side effect of another\nchange.\n\n## Stack\n\n- Vue 3.5 (Composition API, `<script setup lang=\"ts\">`)\n- Vuetify 4\n- Vite 8\n- TypeScript, strict mode\n- Rendering: plain SVG via d3-chord / d3-shape (arc and ribbon generators)\n- Colors: chroma-js (ColorBrewer palettes), dynamic session theme (light / dark / high-contrast)\n- Data loading: a single reactive `values_agg` request (`field=source;target`), refreshed on config or filter change\n\n## Development\n\n```\nnpm install\nnpm run dev\n```\n\n`dev` opens a [zellij](https://zellij.dev/) layout that runs the app (`npm run dev-app`, Vite on the app URL) and\nthe data-fair dev server (`npm run dev-server`) side by side. To run them separately instead:\n\n```\nnpm run dev-app     # Vite dev server for the application\nnpm run dev-server  # data-fair dev server (context: dataset, config, session)\n```\n\n### Ports\n\nNo port is hardcoded, so several applications can run in parallel. On its first run `npm run dev` calls\n`df-dev-env`, which draws three free consecutive ports and writes them to a git-ignored `.env`:\n\n```\nAPP_PORT=24730        # Vite (and its HMR websocket)\nDEV_SERVER_PORT=24731 # df-dev-server — the URL to open\nE2E_PORT=24732        # Vite booted by the Playwright webServer\nAPP_PATH=/app/\n```\n\nThe file is written once and then left alone: the ports must stay stable for bookmarks and open tabs. Vite reads\nit through `loadEnv`, `df-dev-server` through `dotenv`, and the npm scripts through `dotenv --`. Running\n`dev-app` or `dev-server` on their own therefore needs the `.env` to exist already — run `npx df-dev-env` once on\na fresh clone. In case of a collision, `npx df-dev-env --force` draws a new triplet (and keeps `APP_PATH`).\n\n`.dev-config.json` is local state too — the configuration the dev server holds in memory and rewrites on every\nsave. It is git-ignored; edit it through the dev server form, not by hand.\n\n## Configuration schema\n\nThe configuration form is generated from `public/config-schema.json` (VJSF 3 / json-layout vocabulary, written by\nhand and served as-is to data-fair). Main keys:\n\n- `datasets` — the dataset, plus `staticFilters` applied to every request (values in / out, numeric interval, exists / notExists)\n- `sourceField`, `targetField` — the two text columns whose values are connected by the ribbons\n- `maxNodes` — only the most connected nodes are displayed, the rest is grouped into an « Autres » node\n- `nodeSort` — nodes ordered by decreasing flow, or alphabetically\n- `colorscheme` — `qualitative` (ColorBrewer palette via chroma-js), `theme` (cycles primary / secondary / accent\n  of the current session theme) or `manual` (one color per value)\n\n`src/config/schema.ts` re-exports the schema so that `df-build-types` can generate the TypeScript configuration\ntypes consumed by the app:\n\n```\nnpm run build-types\n```\n\nThis must run before `type-check` and `build` — `src/config/.type/` is gitignored and `src/config/index.ts`\nre-exports it, so a fresh clone/CI run fails without this step first.\n\n## Publishing\n\nThe package is published on npm as `@data-fair/app-chord-diagram` and served through jsdelivr.\n`npm publish` builds `dist/` with `base` set to the jsdelivr URL of the released version\n(`prepublishOnly` runs the build with the right `PUBLIC_URL`).\n\n## Tests\n\n```\nnpm run lint         # eslint (read-only; npm run lint-fix rewrites)\nnpm run type-check   # vue-tsc --noEmit\nnpm run test-unit    # Playwright, unit project (pure functions: matrix, colors, chord geometry)\nnpm run test-e2e     # Playwright, e2e project (real Vite server + browser, mocked data-fair endpoints)\nnpm run test         # both projects\nnpm run build        # production build\nnpm run quality      # everything, plus audit — what the pre-push hook runs\n```\n\nThe e2e suite mocks `simple-directory` (session, `_public.js`, `_theme.css`) and the dataset `values_agg` endpoint\n(see `tests/e2e/fixtures.ts`), and injects `window.APPLICATION` through `page.addInitScript`, so no real\ndata-fair instance is needed.\n","readmeFilename":"README.md"}