chore: added sankey diagram
This commit is contained in:
parent
dd9d174449
commit
82b1a46617
@ -81,6 +81,7 @@ async function startup() {
|
|||||||
|
|
||||||
browser.menus.onClicked.addListener(async function (e, tab) {
|
browser.menus.onClicked.addListener(async function (e, tab) {
|
||||||
if (e.menuItemId === "mark-page") {
|
if (e.menuItemId === "mark-page") {
|
||||||
|
console.log("set mark-page", tab.id)
|
||||||
await browser.storage.local.set({
|
await browser.storage.local.set({
|
||||||
windows: tab.id,
|
windows: tab.id,
|
||||||
});
|
});
|
||||||
|
1
site/.dockerignore
Normal file
1
site/.dockerignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules/
|
@ -30,10 +30,11 @@
|
|||||||
"tslib": "^2.4.1",
|
"tslib": "^2.4.1",
|
||||||
"typescript": "^5.0.0",
|
"typescript": "^5.0.0",
|
||||||
"typescript-eslint": "^8.0.0-alpha.20",
|
"typescript-eslint": "^8.0.0-alpha.20",
|
||||||
"vite": "^5.0.3"
|
"vite": "^5.0.3",
|
||||||
|
"@sveltejs/adapter-static": "^3.0.5",
|
||||||
|
"@types/d3": "^7.4.3",
|
||||||
|
"d3": "^7.9.0",
|
||||||
|
"d3-sankey": "^0.12.3"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module"
|
||||||
"dependencies": {
|
|
||||||
"@sveltejs/adapter-static": "^3.0.5"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -7,26 +7,34 @@ settings:
|
|||||||
importers:
|
importers:
|
||||||
|
|
||||||
.:
|
.:
|
||||||
dependencies:
|
|
||||||
'@sveltejs/adapter-static':
|
|
||||||
specifier: ^3.0.5
|
|
||||||
version: 3.0.5(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.174)(vite@5.3.3))(svelte@5.0.0-next.174)(vite@5.3.3))
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@sveltejs/adapter-auto':
|
'@sveltejs/adapter-auto':
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.2.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.174)(vite@5.3.3))(svelte@5.0.0-next.174)(vite@5.3.3))
|
version: 3.2.2(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.174)(vite@5.3.3))(svelte@5.0.0-next.174)(vite@5.3.3))
|
||||||
|
'@sveltejs/adapter-static':
|
||||||
|
specifier: ^3.0.5
|
||||||
|
version: 3.0.5(@sveltejs/kit@2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.174)(vite@5.3.3))(svelte@5.0.0-next.174)(vite@5.3.3))
|
||||||
'@sveltejs/kit':
|
'@sveltejs/kit':
|
||||||
specifier: ^2.0.0
|
specifier: ^2.0.0
|
||||||
version: 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.174)(vite@5.3.3))(svelte@5.0.0-next.174)(vite@5.3.3)
|
version: 2.5.18(@sveltejs/vite-plugin-svelte@3.1.1(svelte@5.0.0-next.174)(vite@5.3.3))(svelte@5.0.0-next.174)(vite@5.3.3)
|
||||||
'@sveltejs/vite-plugin-svelte':
|
'@sveltejs/vite-plugin-svelte':
|
||||||
specifier: ^3.0.0
|
specifier: ^3.0.0
|
||||||
version: 3.1.1(svelte@5.0.0-next.174)(vite@5.3.3)
|
version: 3.1.1(svelte@5.0.0-next.174)(vite@5.3.3)
|
||||||
|
'@types/d3':
|
||||||
|
specifier: ^7.4.3
|
||||||
|
version: 7.4.3
|
||||||
'@types/eslint':
|
'@types/eslint':
|
||||||
specifier: ^8.56.7
|
specifier: ^8.56.7
|
||||||
version: 8.56.10
|
version: 8.56.10
|
||||||
autoprefixer:
|
autoprefixer:
|
||||||
specifier: ^10.4.19
|
specifier: ^10.4.19
|
||||||
version: 10.4.19(postcss@8.4.39)
|
version: 10.4.19(postcss@8.4.39)
|
||||||
|
d3:
|
||||||
|
specifier: ^7.9.0
|
||||||
|
version: 7.9.0
|
||||||
|
d3-sankey:
|
||||||
|
specifier: ^0.12.3
|
||||||
|
version: 0.12.3
|
||||||
eslint:
|
eslint:
|
||||||
specifier: ^9.0.0
|
specifier: ^9.0.0
|
||||||
version: 9.6.0
|
version: 9.6.0
|
||||||
@ -410,12 +418,108 @@ packages:
|
|||||||
'@types/cookie@0.6.0':
|
'@types/cookie@0.6.0':
|
||||||
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
|
||||||
|
|
||||||
|
'@types/d3-array@3.2.1':
|
||||||
|
resolution: {integrity: sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg==}
|
||||||
|
|
||||||
|
'@types/d3-axis@3.0.6':
|
||||||
|
resolution: {integrity: sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==}
|
||||||
|
|
||||||
|
'@types/d3-brush@3.0.6':
|
||||||
|
resolution: {integrity: sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==}
|
||||||
|
|
||||||
|
'@types/d3-chord@3.0.6':
|
||||||
|
resolution: {integrity: sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==}
|
||||||
|
|
||||||
|
'@types/d3-color@3.1.3':
|
||||||
|
resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
|
||||||
|
|
||||||
|
'@types/d3-contour@3.0.6':
|
||||||
|
resolution: {integrity: sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==}
|
||||||
|
|
||||||
|
'@types/d3-delaunay@6.0.4':
|
||||||
|
resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==}
|
||||||
|
|
||||||
|
'@types/d3-dispatch@3.0.6':
|
||||||
|
resolution: {integrity: sha512-4fvZhzMeeuBJYZXRXrRIQnvUYfyXwYmLsdiN7XXmVNQKKw1cM8a5WdID0g1hVFZDqT9ZqZEY5pD44p24VS7iZQ==}
|
||||||
|
|
||||||
|
'@types/d3-drag@3.0.7':
|
||||||
|
resolution: {integrity: sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==}
|
||||||
|
|
||||||
|
'@types/d3-dsv@3.0.7':
|
||||||
|
resolution: {integrity: sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==}
|
||||||
|
|
||||||
|
'@types/d3-ease@3.0.2':
|
||||||
|
resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
|
||||||
|
|
||||||
|
'@types/d3-fetch@3.0.7':
|
||||||
|
resolution: {integrity: sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==}
|
||||||
|
|
||||||
|
'@types/d3-force@3.0.10':
|
||||||
|
resolution: {integrity: sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==}
|
||||||
|
|
||||||
|
'@types/d3-format@3.0.4':
|
||||||
|
resolution: {integrity: sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==}
|
||||||
|
|
||||||
|
'@types/d3-geo@3.1.0':
|
||||||
|
resolution: {integrity: sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==}
|
||||||
|
|
||||||
|
'@types/d3-hierarchy@3.1.7':
|
||||||
|
resolution: {integrity: sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==}
|
||||||
|
|
||||||
|
'@types/d3-interpolate@3.0.4':
|
||||||
|
resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
|
||||||
|
|
||||||
|
'@types/d3-path@3.1.0':
|
||||||
|
resolution: {integrity: sha512-P2dlU/q51fkOc/Gfl3Ul9kicV7l+ra934qBFXCFhrZMOL6du1TM0pm1ThYvENukyOn5h9v+yMJ9Fn5JK4QozrQ==}
|
||||||
|
|
||||||
|
'@types/d3-polygon@3.0.2':
|
||||||
|
resolution: {integrity: sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==}
|
||||||
|
|
||||||
|
'@types/d3-quadtree@3.0.6':
|
||||||
|
resolution: {integrity: sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==}
|
||||||
|
|
||||||
|
'@types/d3-random@3.0.3':
|
||||||
|
resolution: {integrity: sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==}
|
||||||
|
|
||||||
|
'@types/d3-scale-chromatic@3.0.3':
|
||||||
|
resolution: {integrity: sha512-laXM4+1o5ImZv3RpFAsTRn3TEkzqkytiOY0Dz0sq5cnd1dtNlk6sHLon4OvqaiJb28T0S/TdsBI3Sjsy+keJrw==}
|
||||||
|
|
||||||
|
'@types/d3-scale@4.0.8':
|
||||||
|
resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==}
|
||||||
|
|
||||||
|
'@types/d3-selection@3.0.10':
|
||||||
|
resolution: {integrity: sha512-cuHoUgS/V3hLdjJOLTT691+G2QoqAjCVLmr4kJXR4ha56w1Zdu8UUQ5TxLRqudgNjwXeQxKMq4j+lyf9sWuslg==}
|
||||||
|
|
||||||
|
'@types/d3-shape@3.1.6':
|
||||||
|
resolution: {integrity: sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA==}
|
||||||
|
|
||||||
|
'@types/d3-time-format@4.0.3':
|
||||||
|
resolution: {integrity: sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==}
|
||||||
|
|
||||||
|
'@types/d3-time@3.0.3':
|
||||||
|
resolution: {integrity: sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw==}
|
||||||
|
|
||||||
|
'@types/d3-timer@3.0.2':
|
||||||
|
resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
|
||||||
|
|
||||||
|
'@types/d3-transition@3.0.8':
|
||||||
|
resolution: {integrity: sha512-ew63aJfQ/ms7QQ4X7pk5NxQ9fZH/z+i24ZfJ6tJSfqxJMrYLiK01EAs2/Rtw/JreGUsS3pLPNV644qXFGnoZNQ==}
|
||||||
|
|
||||||
|
'@types/d3-zoom@3.0.8':
|
||||||
|
resolution: {integrity: sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==}
|
||||||
|
|
||||||
|
'@types/d3@7.4.3':
|
||||||
|
resolution: {integrity: sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==}
|
||||||
|
|
||||||
'@types/eslint@8.56.10':
|
'@types/eslint@8.56.10':
|
||||||
resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==}
|
resolution: {integrity: sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==}
|
||||||
|
|
||||||
'@types/estree@1.0.5':
|
'@types/estree@1.0.5':
|
||||||
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
|
resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
|
||||||
|
|
||||||
|
'@types/geojson@7946.0.14':
|
||||||
|
resolution: {integrity: sha512-WCfD5Ht3ZesJUsONdhvm84dmzWOiOzOAqOncN0++w0lBw1o8OuDNJF2McvvCef/yBqb/HYRahp1BYtODFQ8bRg==}
|
||||||
|
|
||||||
'@types/json-schema@7.0.15':
|
'@types/json-schema@7.0.15':
|
||||||
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==}
|
||||||
|
|
||||||
@ -599,6 +703,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
|
|
||||||
|
commander@7.2.0:
|
||||||
|
resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==}
|
||||||
|
engines: {node: '>= 10'}
|
||||||
|
|
||||||
concat-map@0.0.1:
|
concat-map@0.0.1:
|
||||||
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
|
||||||
|
|
||||||
@ -615,6 +723,145 @@ packages:
|
|||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
d3-array@2.12.1:
|
||||||
|
resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==}
|
||||||
|
|
||||||
|
d3-array@3.2.4:
|
||||||
|
resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-axis@3.0.0:
|
||||||
|
resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-brush@3.0.0:
|
||||||
|
resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-chord@3.0.1:
|
||||||
|
resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-color@3.1.0:
|
||||||
|
resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-contour@4.0.2:
|
||||||
|
resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-delaunay@6.0.4:
|
||||||
|
resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-dispatch@3.0.1:
|
||||||
|
resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-drag@3.0.0:
|
||||||
|
resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-dsv@3.0.1:
|
||||||
|
resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
|
d3-ease@3.0.1:
|
||||||
|
resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-fetch@3.0.1:
|
||||||
|
resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-force@3.0.0:
|
||||||
|
resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-format@3.1.0:
|
||||||
|
resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-geo@3.1.1:
|
||||||
|
resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-hierarchy@3.1.2:
|
||||||
|
resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-interpolate@3.0.1:
|
||||||
|
resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-path@1.0.9:
|
||||||
|
resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==}
|
||||||
|
|
||||||
|
d3-path@3.1.0:
|
||||||
|
resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-polygon@3.0.1:
|
||||||
|
resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-quadtree@3.0.1:
|
||||||
|
resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-random@3.0.1:
|
||||||
|
resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-sankey@0.12.3:
|
||||||
|
resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==}
|
||||||
|
|
||||||
|
d3-scale-chromatic@3.1.0:
|
||||||
|
resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-scale@4.0.2:
|
||||||
|
resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-selection@3.0.0:
|
||||||
|
resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-shape@1.3.7:
|
||||||
|
resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==}
|
||||||
|
|
||||||
|
d3-shape@3.2.0:
|
||||||
|
resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-time-format@4.1.0:
|
||||||
|
resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-time@3.1.0:
|
||||||
|
resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-timer@3.0.1:
|
||||||
|
resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3-transition@3.0.1:
|
||||||
|
resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
peerDependencies:
|
||||||
|
d3-selection: 2 - 3
|
||||||
|
|
||||||
|
d3-zoom@3.0.0:
|
||||||
|
resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
|
d3@7.9.0:
|
||||||
|
resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
debug@4.3.5:
|
debug@4.3.5:
|
||||||
resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==}
|
resolution: {integrity: sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==}
|
||||||
engines: {node: '>=6.0'}
|
engines: {node: '>=6.0'}
|
||||||
@ -631,6 +878,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
|
delaunator@5.0.1:
|
||||||
|
resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==}
|
||||||
|
|
||||||
dequal@2.0.3:
|
dequal@2.0.3:
|
||||||
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -855,6 +1105,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
|
iconv-lite@0.6.3:
|
||||||
|
resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==}
|
||||||
|
engines: {node: '>=0.10.0'}
|
||||||
|
|
||||||
ignore@5.3.1:
|
ignore@5.3.1:
|
||||||
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
|
resolution: {integrity: sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
@ -877,6 +1131,13 @@ packages:
|
|||||||
inherits@2.0.4:
|
inherits@2.0.4:
|
||||||
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
|
||||||
|
|
||||||
|
internmap@1.0.1:
|
||||||
|
resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==}
|
||||||
|
|
||||||
|
internmap@2.0.3:
|
||||||
|
resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
|
||||||
|
engines: {node: '>=12'}
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
|
||||||
engines: {node: '>=8'}
|
engines: {node: '>=8'}
|
||||||
@ -1216,6 +1477,9 @@ packages:
|
|||||||
deprecated: Rimraf versions prior to v4 are no longer supported
|
deprecated: Rimraf versions prior to v4 are no longer supported
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
robust-predicates@3.0.2:
|
||||||
|
resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==}
|
||||||
|
|
||||||
rollup@4.18.0:
|
rollup@4.18.0:
|
||||||
resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==}
|
resolution: {integrity: sha512-QmJz14PX3rzbJCN1SG4Xe/bAAX2a6NpCP8ab2vfu2GiUr8AQcr2nCV/oEO3yneFarB67zk8ShlIyWb2LGTb3Sg==}
|
||||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||||
@ -1224,10 +1488,16 @@ packages:
|
|||||||
run-parallel@1.2.0:
|
run-parallel@1.2.0:
|
||||||
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
|
||||||
|
|
||||||
|
rw@1.3.3:
|
||||||
|
resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==}
|
||||||
|
|
||||||
sade@1.8.1:
|
sade@1.8.1:
|
||||||
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
|
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
|
||||||
|
safer-buffer@2.1.2:
|
||||||
|
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||||
|
|
||||||
sander@0.5.1:
|
sander@0.5.1:
|
||||||
resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==}
|
resolution: {integrity: sha512-3lVqBir7WuKDHGrKRDn/1Ye3kwpXaDOMsiRP1wd6wpZW56gJhsbp5RqQpA6JG/P+pkXizygnr1dKR8vzWaVsfA==}
|
||||||
|
|
||||||
@ -1764,6 +2034,123 @@ snapshots:
|
|||||||
|
|
||||||
'@types/cookie@0.6.0': {}
|
'@types/cookie@0.6.0': {}
|
||||||
|
|
||||||
|
'@types/d3-array@3.2.1': {}
|
||||||
|
|
||||||
|
'@types/d3-axis@3.0.6':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-selection': 3.0.10
|
||||||
|
|
||||||
|
'@types/d3-brush@3.0.6':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-selection': 3.0.10
|
||||||
|
|
||||||
|
'@types/d3-chord@3.0.6': {}
|
||||||
|
|
||||||
|
'@types/d3-color@3.1.3': {}
|
||||||
|
|
||||||
|
'@types/d3-contour@3.0.6':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-array': 3.2.1
|
||||||
|
'@types/geojson': 7946.0.14
|
||||||
|
|
||||||
|
'@types/d3-delaunay@6.0.4': {}
|
||||||
|
|
||||||
|
'@types/d3-dispatch@3.0.6': {}
|
||||||
|
|
||||||
|
'@types/d3-drag@3.0.7':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-selection': 3.0.10
|
||||||
|
|
||||||
|
'@types/d3-dsv@3.0.7': {}
|
||||||
|
|
||||||
|
'@types/d3-ease@3.0.2': {}
|
||||||
|
|
||||||
|
'@types/d3-fetch@3.0.7':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-dsv': 3.0.7
|
||||||
|
|
||||||
|
'@types/d3-force@3.0.10': {}
|
||||||
|
|
||||||
|
'@types/d3-format@3.0.4': {}
|
||||||
|
|
||||||
|
'@types/d3-geo@3.1.0':
|
||||||
|
dependencies:
|
||||||
|
'@types/geojson': 7946.0.14
|
||||||
|
|
||||||
|
'@types/d3-hierarchy@3.1.7': {}
|
||||||
|
|
||||||
|
'@types/d3-interpolate@3.0.4':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-color': 3.1.3
|
||||||
|
|
||||||
|
'@types/d3-path@3.1.0': {}
|
||||||
|
|
||||||
|
'@types/d3-polygon@3.0.2': {}
|
||||||
|
|
||||||
|
'@types/d3-quadtree@3.0.6': {}
|
||||||
|
|
||||||
|
'@types/d3-random@3.0.3': {}
|
||||||
|
|
||||||
|
'@types/d3-scale-chromatic@3.0.3': {}
|
||||||
|
|
||||||
|
'@types/d3-scale@4.0.8':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-time': 3.0.3
|
||||||
|
|
||||||
|
'@types/d3-selection@3.0.10': {}
|
||||||
|
|
||||||
|
'@types/d3-shape@3.1.6':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-path': 3.1.0
|
||||||
|
|
||||||
|
'@types/d3-time-format@4.0.3': {}
|
||||||
|
|
||||||
|
'@types/d3-time@3.0.3': {}
|
||||||
|
|
||||||
|
'@types/d3-timer@3.0.2': {}
|
||||||
|
|
||||||
|
'@types/d3-transition@3.0.8':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-selection': 3.0.10
|
||||||
|
|
||||||
|
'@types/d3-zoom@3.0.8':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-interpolate': 3.0.4
|
||||||
|
'@types/d3-selection': 3.0.10
|
||||||
|
|
||||||
|
'@types/d3@7.4.3':
|
||||||
|
dependencies:
|
||||||
|
'@types/d3-array': 3.2.1
|
||||||
|
'@types/d3-axis': 3.0.6
|
||||||
|
'@types/d3-brush': 3.0.6
|
||||||
|
'@types/d3-chord': 3.0.6
|
||||||
|
'@types/d3-color': 3.1.3
|
||||||
|
'@types/d3-contour': 3.0.6
|
||||||
|
'@types/d3-delaunay': 6.0.4
|
||||||
|
'@types/d3-dispatch': 3.0.6
|
||||||
|
'@types/d3-drag': 3.0.7
|
||||||
|
'@types/d3-dsv': 3.0.7
|
||||||
|
'@types/d3-ease': 3.0.2
|
||||||
|
'@types/d3-fetch': 3.0.7
|
||||||
|
'@types/d3-force': 3.0.10
|
||||||
|
'@types/d3-format': 3.0.4
|
||||||
|
'@types/d3-geo': 3.1.0
|
||||||
|
'@types/d3-hierarchy': 3.1.7
|
||||||
|
'@types/d3-interpolate': 3.0.4
|
||||||
|
'@types/d3-path': 3.1.0
|
||||||
|
'@types/d3-polygon': 3.0.2
|
||||||
|
'@types/d3-quadtree': 3.0.6
|
||||||
|
'@types/d3-random': 3.0.3
|
||||||
|
'@types/d3-scale': 4.0.8
|
||||||
|
'@types/d3-scale-chromatic': 3.0.3
|
||||||
|
'@types/d3-selection': 3.0.10
|
||||||
|
'@types/d3-shape': 3.1.6
|
||||||
|
'@types/d3-time': 3.0.3
|
||||||
|
'@types/d3-time-format': 4.0.3
|
||||||
|
'@types/d3-timer': 3.0.2
|
||||||
|
'@types/d3-transition': 3.0.8
|
||||||
|
'@types/d3-zoom': 3.0.8
|
||||||
|
|
||||||
'@types/eslint@8.56.10':
|
'@types/eslint@8.56.10':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.5
|
'@types/estree': 1.0.5
|
||||||
@ -1771,6 +2158,8 @@ snapshots:
|
|||||||
|
|
||||||
'@types/estree@1.0.5': {}
|
'@types/estree@1.0.5': {}
|
||||||
|
|
||||||
|
'@types/geojson@7946.0.14': {}
|
||||||
|
|
||||||
'@types/json-schema@7.0.15': {}
|
'@types/json-schema@7.0.15': {}
|
||||||
|
|
||||||
'@types/pug@2.0.10': {}
|
'@types/pug@2.0.10': {}
|
||||||
@ -1971,6 +2360,8 @@ snapshots:
|
|||||||
|
|
||||||
commander@4.1.1: {}
|
commander@4.1.1: {}
|
||||||
|
|
||||||
|
commander@7.2.0: {}
|
||||||
|
|
||||||
concat-map@0.0.1: {}
|
concat-map@0.0.1: {}
|
||||||
|
|
||||||
cookie@0.6.0: {}
|
cookie@0.6.0: {}
|
||||||
@ -1983,6 +2374,173 @@ snapshots:
|
|||||||
|
|
||||||
cssesc@3.0.0: {}
|
cssesc@3.0.0: {}
|
||||||
|
|
||||||
|
d3-array@2.12.1:
|
||||||
|
dependencies:
|
||||||
|
internmap: 1.0.1
|
||||||
|
|
||||||
|
d3-array@3.2.4:
|
||||||
|
dependencies:
|
||||||
|
internmap: 2.0.3
|
||||||
|
|
||||||
|
d3-axis@3.0.0: {}
|
||||||
|
|
||||||
|
d3-brush@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-drag: 3.0.0
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||||
|
|
||||||
|
d3-chord@3.0.1:
|
||||||
|
dependencies:
|
||||||
|
d3-path: 3.1.0
|
||||||
|
|
||||||
|
d3-color@3.1.0: {}
|
||||||
|
|
||||||
|
d3-contour@4.0.2:
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
|
||||||
|
d3-delaunay@6.0.4:
|
||||||
|
dependencies:
|
||||||
|
delaunator: 5.0.1
|
||||||
|
|
||||||
|
d3-dispatch@3.0.1: {}
|
||||||
|
|
||||||
|
d3-drag@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
|
||||||
|
d3-dsv@3.0.1:
|
||||||
|
dependencies:
|
||||||
|
commander: 7.2.0
|
||||||
|
iconv-lite: 0.6.3
|
||||||
|
rw: 1.3.3
|
||||||
|
|
||||||
|
d3-ease@3.0.1: {}
|
||||||
|
|
||||||
|
d3-fetch@3.0.1:
|
||||||
|
dependencies:
|
||||||
|
d3-dsv: 3.0.1
|
||||||
|
|
||||||
|
d3-force@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-quadtree: 3.0.1
|
||||||
|
d3-timer: 3.0.1
|
||||||
|
|
||||||
|
d3-format@3.1.0: {}
|
||||||
|
|
||||||
|
d3-geo@3.1.1:
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
|
||||||
|
d3-hierarchy@3.1.2: {}
|
||||||
|
|
||||||
|
d3-interpolate@3.0.1:
|
||||||
|
dependencies:
|
||||||
|
d3-color: 3.1.0
|
||||||
|
|
||||||
|
d3-path@1.0.9: {}
|
||||||
|
|
||||||
|
d3-path@3.1.0: {}
|
||||||
|
|
||||||
|
d3-polygon@3.0.1: {}
|
||||||
|
|
||||||
|
d3-quadtree@3.0.1: {}
|
||||||
|
|
||||||
|
d3-random@3.0.1: {}
|
||||||
|
|
||||||
|
d3-sankey@0.12.3:
|
||||||
|
dependencies:
|
||||||
|
d3-array: 2.12.1
|
||||||
|
d3-shape: 1.3.7
|
||||||
|
|
||||||
|
d3-scale-chromatic@3.1.0:
|
||||||
|
dependencies:
|
||||||
|
d3-color: 3.1.0
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
|
||||||
|
d3-scale@4.0.2:
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
d3-format: 3.1.0
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-time: 3.1.0
|
||||||
|
d3-time-format: 4.1.0
|
||||||
|
|
||||||
|
d3-selection@3.0.0: {}
|
||||||
|
|
||||||
|
d3-shape@1.3.7:
|
||||||
|
dependencies:
|
||||||
|
d3-path: 1.0.9
|
||||||
|
|
||||||
|
d3-shape@3.2.0:
|
||||||
|
dependencies:
|
||||||
|
d3-path: 3.1.0
|
||||||
|
|
||||||
|
d3-time-format@4.1.0:
|
||||||
|
dependencies:
|
||||||
|
d3-time: 3.1.0
|
||||||
|
|
||||||
|
d3-time@3.1.0:
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
|
||||||
|
d3-timer@3.0.1: {}
|
||||||
|
|
||||||
|
d3-transition@3.0.1(d3-selection@3.0.0):
|
||||||
|
dependencies:
|
||||||
|
d3-color: 3.1.0
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-ease: 3.0.1
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
d3-timer: 3.0.1
|
||||||
|
|
||||||
|
d3-zoom@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-drag: 3.0.0
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||||
|
|
||||||
|
d3@7.9.0:
|
||||||
|
dependencies:
|
||||||
|
d3-array: 3.2.4
|
||||||
|
d3-axis: 3.0.0
|
||||||
|
d3-brush: 3.0.0
|
||||||
|
d3-chord: 3.0.1
|
||||||
|
d3-color: 3.1.0
|
||||||
|
d3-contour: 4.0.2
|
||||||
|
d3-delaunay: 6.0.4
|
||||||
|
d3-dispatch: 3.0.1
|
||||||
|
d3-drag: 3.0.0
|
||||||
|
d3-dsv: 3.0.1
|
||||||
|
d3-ease: 3.0.1
|
||||||
|
d3-fetch: 3.0.1
|
||||||
|
d3-force: 3.0.0
|
||||||
|
d3-format: 3.1.0
|
||||||
|
d3-geo: 3.1.1
|
||||||
|
d3-hierarchy: 3.1.2
|
||||||
|
d3-interpolate: 3.0.1
|
||||||
|
d3-path: 3.1.0
|
||||||
|
d3-polygon: 3.0.1
|
||||||
|
d3-quadtree: 3.0.1
|
||||||
|
d3-random: 3.0.1
|
||||||
|
d3-scale: 4.0.2
|
||||||
|
d3-scale-chromatic: 3.1.0
|
||||||
|
d3-selection: 3.0.0
|
||||||
|
d3-shape: 3.2.0
|
||||||
|
d3-time: 3.1.0
|
||||||
|
d3-time-format: 4.1.0
|
||||||
|
d3-timer: 3.0.1
|
||||||
|
d3-transition: 3.0.1(d3-selection@3.0.0)
|
||||||
|
d3-zoom: 3.0.0
|
||||||
|
|
||||||
debug@4.3.5:
|
debug@4.3.5:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms: 2.1.2
|
ms: 2.1.2
|
||||||
@ -1991,6 +2549,10 @@ snapshots:
|
|||||||
|
|
||||||
deepmerge@4.3.1: {}
|
deepmerge@4.3.1: {}
|
||||||
|
|
||||||
|
delaunator@5.0.1:
|
||||||
|
dependencies:
|
||||||
|
robust-predicates: 3.0.2
|
||||||
|
|
||||||
dequal@2.0.3: {}
|
dequal@2.0.3: {}
|
||||||
|
|
||||||
detect-indent@6.1.0: {}
|
detect-indent@6.1.0: {}
|
||||||
@ -2262,6 +2824,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
|
|
||||||
|
iconv-lite@0.6.3:
|
||||||
|
dependencies:
|
||||||
|
safer-buffer: 2.1.2
|
||||||
|
|
||||||
ignore@5.3.1: {}
|
ignore@5.3.1: {}
|
||||||
|
|
||||||
import-fresh@3.3.0:
|
import-fresh@3.3.0:
|
||||||
@ -2280,6 +2846,10 @@ snapshots:
|
|||||||
|
|
||||||
inherits@2.0.4: {}
|
inherits@2.0.4: {}
|
||||||
|
|
||||||
|
internmap@1.0.1: {}
|
||||||
|
|
||||||
|
internmap@2.0.3: {}
|
||||||
|
|
||||||
is-binary-path@2.1.0:
|
is-binary-path@2.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
binary-extensions: 2.3.0
|
binary-extensions: 2.3.0
|
||||||
@ -2545,6 +3115,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
glob: 7.2.3
|
glob: 7.2.3
|
||||||
|
|
||||||
|
robust-predicates@3.0.2: {}
|
||||||
|
|
||||||
rollup@4.18.0:
|
rollup@4.18.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.5
|
'@types/estree': 1.0.5
|
||||||
@ -2571,10 +3143,14 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
queue-microtask: 1.2.3
|
queue-microtask: 1.2.3
|
||||||
|
|
||||||
|
rw@1.3.3: {}
|
||||||
|
|
||||||
sade@1.8.1:
|
sade@1.8.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
mri: 1.2.0
|
mri: 1.2.0
|
||||||
|
|
||||||
|
safer-buffer@2.1.2: {}
|
||||||
|
|
||||||
sander@0.5.1:
|
sander@0.5.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
es6-promise: 3.3.1
|
es6-promise: 3.3.1
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import type { Flair } from './FlairStore.svelte';
|
import type { Flair } from './FlairStore.svelte';
|
||||||
import { post } from './utils';
|
import { post } from './utils';
|
||||||
|
|
||||||
|
export type AsEnum<T> = T[keyof T];
|
||||||
|
|
||||||
export const ApplicationStatus = Object.freeze({
|
export const ApplicationStatus = Object.freeze({
|
||||||
ToApply: 0,
|
ToApply: 0,
|
||||||
WorkingOnIt: 1,
|
WorkingOnIt: 1,
|
||||||
@ -37,7 +39,7 @@ export type Application = {
|
|||||||
user_id: string;
|
user_id: string;
|
||||||
extra_data: string;
|
extra_data: string;
|
||||||
payrange: string;
|
payrange: string;
|
||||||
status: number;
|
status: AsEnum<typeof ApplicationStatus>;
|
||||||
recruiter: string;
|
recruiter: string;
|
||||||
company: string;
|
company: string;
|
||||||
message: string;
|
message: string;
|
||||||
|
@ -12,6 +12,9 @@
|
|||||||
<button class="text-secudanry hover:text-primary px-2" onclick={() => goto('/flair')}>
|
<button class="text-secudanry hover:text-primary px-2" onclick={() => goto('/flair')}>
|
||||||
Flair
|
Flair
|
||||||
</button>
|
</button>
|
||||||
|
<button class="text-secudanry hover:text-primary px-2" onclick={() => goto('/graphs')}>
|
||||||
|
Graphs
|
||||||
|
</button>
|
||||||
<div class="flex-grow"></div>
|
<div class="flex-grow"></div>
|
||||||
<div class="text-secudanry px-2">
|
<div class="text-secudanry px-2">
|
||||||
{userStore.user.username}
|
{userStore.user.username}
|
||||||
|
244
site/src/routes/graphs/+page.svelte
Normal file
244
site/src/routes/graphs/+page.svelte
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import type { Application, AsEnum } from '$lib/ApplicationsStore.svelte';
|
||||||
|
import { ApplicationStatus, ApplicationStatusMaping } from '$lib/ApplicationsStore.svelte';
|
||||||
|
import HasUser from '$lib/HasUser.svelte';
|
||||||
|
import { post } from '$lib/utils';
|
||||||
|
import NavBar from '../NavBar.svelte';
|
||||||
|
import * as d3 from 'd3';
|
||||||
|
import { sankey as mySankey } from './sankey';
|
||||||
|
|
||||||
|
let applications: Application[] = $state([]);
|
||||||
|
|
||||||
|
let chartDiv: HTMLDivElement;
|
||||||
|
|
||||||
|
async function getData() {
|
||||||
|
try {
|
||||||
|
applications = await post('application/list', {});
|
||||||
|
|
||||||
|
chartDiv.innerHTML = '';
|
||||||
|
|
||||||
|
type NodeType =
|
||||||
|
| AsEnum<typeof ApplicationStatus>
|
||||||
|
| 'Linkedin'
|
||||||
|
| 'Glassdoor'
|
||||||
|
| 'Unknown Source'
|
||||||
|
| 'Applications';
|
||||||
|
|
||||||
|
let nodeTypes: Record<NodeType, number> = {
|
||||||
|
[ApplicationStatus.ToApply]: 0,
|
||||||
|
[ApplicationStatus.WorkingOnIt]: 0,
|
||||||
|
[ApplicationStatus.Ignore]: 0,
|
||||||
|
[ApplicationStatus.ApplyedButSaidNo]: 0,
|
||||||
|
[ApplicationStatus.Expired]: 0,
|
||||||
|
[ApplicationStatus.Applyed]: 0,
|
||||||
|
Linkedin: 0,
|
||||||
|
Glassdoor: 0,
|
||||||
|
'Unknown Source': 0,
|
||||||
|
Applications: applications.length
|
||||||
|
};
|
||||||
|
|
||||||
|
const baseLinks: { source: NodeType; target: NodeType; value: 0 | 1 }[] = [
|
||||||
|
{ source: 'Linkedin', target: 'Applications', value: 0 },
|
||||||
|
{ source: 'Glassdoor', target: 'Applications', value: 0 },
|
||||||
|
{ source: 'Unknown Source', target: 'Applications', value: 0 },
|
||||||
|
{ source: 'Applications', target: ApplicationStatus.ToApply, value: 1 },
|
||||||
|
{ source: 'Applications', target: ApplicationStatus.Ignore, value: 1 },
|
||||||
|
{ source: 'Applications', target: ApplicationStatus.Expired, value: 1 },
|
||||||
|
{ source: 'Applications', target: ApplicationStatus.WorkingOnIt, value: 1 },
|
||||||
|
{ source: 'Applications', target: ApplicationStatus.Applyed, value: 1 },
|
||||||
|
|
||||||
|
{
|
||||||
|
source: ApplicationStatus.Applyed,
|
||||||
|
target: ApplicationStatus.ApplyedButSaidNo,
|
||||||
|
value: 1
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
applications.forEach((a) => {
|
||||||
|
if (a.url.includes('linkedin')) {
|
||||||
|
nodeTypes['Linkedin'] += 1;
|
||||||
|
} else if (a.url.includes('glassdoor')) {
|
||||||
|
nodeTypes['Glassdoor'] += 1;
|
||||||
|
} else {
|
||||||
|
nodeTypes['Unknown Source'] += 1;
|
||||||
|
}
|
||||||
|
nodeTypes[a.status] += 1;
|
||||||
|
if (a.status === ApplicationStatus.ApplyedButSaidNo) {
|
||||||
|
nodeTypes[ApplicationStatus.Applyed] += 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let inNodes: string[] = [];
|
||||||
|
|
||||||
|
let nodes = (Object.keys(nodeTypes) as (keyof typeof nodeTypes)[])
|
||||||
|
.filter((a) => nodeTypes[a] > 0)
|
||||||
|
.map((a, i) => {
|
||||||
|
inNodes.push(`${a}`);
|
||||||
|
const base = {
|
||||||
|
value: nodeTypes[a],
|
||||||
|
originalValue: a,
|
||||||
|
id: '',
|
||||||
|
color: 'red',
|
||||||
|
index: i
|
||||||
|
};
|
||||||
|
if (Number.isNaN(Number(a))) {
|
||||||
|
base.id = a as string;
|
||||||
|
} else {
|
||||||
|
base.id = ApplicationStatusMaping[a as AsEnum<typeof ApplicationStatus>];
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
});
|
||||||
|
|
||||||
|
const links = baseLinks
|
||||||
|
.filter(
|
||||||
|
(link) =>
|
||||||
|
inNodes.includes(`${link.source}`) && inNodes.includes(`${link.target}`)
|
||||||
|
)
|
||||||
|
.map((link) => {
|
||||||
|
const source = inNodes.indexOf(`${link.source}`);
|
||||||
|
const target = inNodes.indexOf(`${link.target}`);
|
||||||
|
return {
|
||||||
|
source: source,
|
||||||
|
target: target,
|
||||||
|
value: [nodes[source], nodes[target]][link.value].value
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const bounding = chartDiv.getBoundingClientRect();
|
||||||
|
|
||||||
|
let sankey = mySankey()
|
||||||
|
.nodeWidth(20)
|
||||||
|
.nodePadding(10)
|
||||||
|
.size([bounding.width, bounding.height]);
|
||||||
|
|
||||||
|
let path = sankey.link();
|
||||||
|
|
||||||
|
sankey.nodes(nodes).links(links).layout(32);
|
||||||
|
|
||||||
|
const svg = d3
|
||||||
|
.select(chartDiv)
|
||||||
|
.append('svg')
|
||||||
|
.attr('width', bounding.width)
|
||||||
|
.attr('height', bounding.height)
|
||||||
|
.attr('viewBox', [0, 0, bounding.width, bounding.height])
|
||||||
|
.attr('style', 'max-width: 100%; height: auto; height: intrinsic;');
|
||||||
|
|
||||||
|
let color = d3.schemeSpectral[nodes.length];
|
||||||
|
|
||||||
|
// add in the links
|
||||||
|
var link = svg
|
||||||
|
.append('g')
|
||||||
|
.selectAll('.link')
|
||||||
|
.data(
|
||||||
|
links as ((typeof links)[0] & {
|
||||||
|
dy: number;
|
||||||
|
source: (typeof nodes)[0];
|
||||||
|
target: (typeof nodes)[0];
|
||||||
|
})[]
|
||||||
|
)
|
||||||
|
.enter()
|
||||||
|
.append('path')
|
||||||
|
.attr('class', 'link')
|
||||||
|
.attr('d', path)
|
||||||
|
.style('stroke-width', function (d) {
|
||||||
|
return Math.max(1, d.dy);
|
||||||
|
})
|
||||||
|
.sort(function (a, b) {
|
||||||
|
return b.dy - a.dy;
|
||||||
|
});
|
||||||
|
|
||||||
|
// add the link titles
|
||||||
|
link.append('title').text(function (d) {
|
||||||
|
return d.source.id + ' → ' + d.target.id + '\n' + d.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const node = svg
|
||||||
|
.append('g')
|
||||||
|
.selectAll('.node')
|
||||||
|
.data(
|
||||||
|
nodes as ((typeof nodes)[0] & {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
dy: number;
|
||||||
|
dx: number;
|
||||||
|
index: number;
|
||||||
|
})[]
|
||||||
|
)
|
||||||
|
.enter()
|
||||||
|
.append('g')
|
||||||
|
.attr('class', 'node')
|
||||||
|
.attr('transform', function (d) {
|
||||||
|
return 'translate(' + d.x + ',' + d.y + ')';
|
||||||
|
});
|
||||||
|
|
||||||
|
node.append('rect')
|
||||||
|
.attr('height', function (d) {
|
||||||
|
return d.dy;
|
||||||
|
})
|
||||||
|
.attr('width', sankey.getNodeWidth())
|
||||||
|
.style('fill', function (d) {
|
||||||
|
return color[d.index];
|
||||||
|
})
|
||||||
|
.style('stroke', (d) => {
|
||||||
|
return d3.rgb(color[d.index]).darker(2).toString();
|
||||||
|
})
|
||||||
|
.append('title')
|
||||||
|
.text(function (d) {
|
||||||
|
return d.id + '\n' + d.value;
|
||||||
|
});
|
||||||
|
|
||||||
|
node.append('text')
|
||||||
|
.attr('x', -6)
|
||||||
|
.attr('y', function (d) {
|
||||||
|
return d.dy / 2;
|
||||||
|
})
|
||||||
|
.attr('dy', '.35em')
|
||||||
|
.attr('text-anchor', 'end')
|
||||||
|
.attr('transform', null)
|
||||||
|
.text(function (d) {
|
||||||
|
return `${d.id} (${d.value})`;
|
||||||
|
})
|
||||||
|
.filter(function (d) {
|
||||||
|
return d.x < bounding.width / 2;
|
||||||
|
})
|
||||||
|
.attr('x', 6 + sankey.getNodeWidth())
|
||||||
|
.attr('text-anchor', 'start');
|
||||||
|
} catch (e) {
|
||||||
|
console.log('TODO, inform the user', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
getData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<HasUser redirect="/cv">
|
||||||
|
<div class="flex flex-col h-[100vh]">
|
||||||
|
<NavBar />
|
||||||
|
<div class="flex flex-grow p-5">
|
||||||
|
<div class="bg-white p-3 rounded-lg" style="width: 100%; height: 100%">
|
||||||
|
<div bind:this={chartDiv} style="width: 100%; height: 100%;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</HasUser>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:global(.node rect) {
|
||||||
|
cursor: move;
|
||||||
|
fill-opacity: 0.9;
|
||||||
|
shape-rendering: crispEdges;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.node text) {
|
||||||
|
pointer-events: none;
|
||||||
|
text-shadow: 0 1px 0 #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
:global(.link) {
|
||||||
|
fill: none;
|
||||||
|
stroke: #000;
|
||||||
|
stroke-opacity: 0.2;
|
||||||
|
}
|
||||||
|
</style>
|
455
site/src/routes/graphs/sankey.ts
Normal file
455
site/src/routes/graphs/sankey.ts
Normal file
@ -0,0 +1,455 @@
|
|||||||
|
import * as d3 from 'd3';
|
||||||
|
|
||||||
|
export type SankeyLink<Link> = ((d: Link) => string) & { curvature: (n: number) => SankeyLink<Link> };
|
||||||
|
|
||||||
|
export type Sankey<Node, Link> = {
|
||||||
|
nodeWidth: (w: number) => Sankey<Node, Link>;
|
||||||
|
getNodeWidth: () => number;
|
||||||
|
nodePadding: (padding: number) => Sankey<Node, Link>;
|
||||||
|
nodes: (nodes: Node[]) => Sankey<Node, Link>;
|
||||||
|
links: (links: Link[]) => Sankey<Node, Link>;
|
||||||
|
size: (size: number[]) => Sankey<Node, Link>;
|
||||||
|
layout: (iterations: number) => Sankey<Node, Link>;
|
||||||
|
relayout: () => Sankey<Node, Link>;
|
||||||
|
link: () => SankeyLink<Link>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function sankey<Node = any, Link = any>(): Sankey<Node, Link> {
|
||||||
|
let sankey = {},
|
||||||
|
nodeWidth = 24,
|
||||||
|
nodePadding = 8,
|
||||||
|
size = [1, 1],
|
||||||
|
nodes = [],
|
||||||
|
links = [];
|
||||||
|
|
||||||
|
sankey.getNodeWidth = () => nodeWidth;
|
||||||
|
sankey.nodeWidth = function(w) {
|
||||||
|
nodeWidth = +w;
|
||||||
|
return sankey;
|
||||||
|
};
|
||||||
|
|
||||||
|
sankey.nodePadding = function(_) {
|
||||||
|
if (!arguments.length) return nodePadding;
|
||||||
|
nodePadding = +_;
|
||||||
|
return sankey;
|
||||||
|
};
|
||||||
|
|
||||||
|
sankey.nodes = function(_) {
|
||||||
|
if (!arguments.length) return nodes;
|
||||||
|
nodes = _;
|
||||||
|
return sankey;
|
||||||
|
};
|
||||||
|
|
||||||
|
sankey.links = function(_) {
|
||||||
|
if (!arguments.length) return links;
|
||||||
|
links = _;
|
||||||
|
return sankey;
|
||||||
|
};
|
||||||
|
|
||||||
|
sankey.size = function(_) {
|
||||||
|
if (!arguments.length) return size;
|
||||||
|
size = _;
|
||||||
|
return sankey;
|
||||||
|
};
|
||||||
|
|
||||||
|
sankey.layout = function(iterations) {
|
||||||
|
computeNodeLinks();
|
||||||
|
computeNodeValues();
|
||||||
|
computeNodeBreadths();
|
||||||
|
computeNodeDepths(iterations);
|
||||||
|
computeLinkDepths();
|
||||||
|
return sankey;
|
||||||
|
};
|
||||||
|
|
||||||
|
sankey.relayout = function() {
|
||||||
|
computeLinkDepths();
|
||||||
|
return sankey;
|
||||||
|
};
|
||||||
|
|
||||||
|
sankey.link = function() {
|
||||||
|
var curvature = 0.5;
|
||||||
|
|
||||||
|
function link(d) {
|
||||||
|
var x0 = d.source.x + d.source.dx,
|
||||||
|
x1 = d.target.x,
|
||||||
|
xi = d3.interpolateNumber(x0, x1),
|
||||||
|
x2 = xi(curvature),
|
||||||
|
x3 = xi(1 - curvature),
|
||||||
|
y0 = d.source.y + d.sy + d.dy / 2,
|
||||||
|
y1 = d.target.y + d.ty + d.dy / 2;
|
||||||
|
|
||||||
|
return "M" + x0 + "," + y0
|
||||||
|
+ "C" + x2 + "," + y0
|
||||||
|
+ " " + x3 + "," + y1
|
||||||
|
+ " " + x1 + "," + y1;
|
||||||
|
}
|
||||||
|
|
||||||
|
link.curvature = function(_) {
|
||||||
|
if (!arguments.length) return curvature;
|
||||||
|
curvature = +_;
|
||||||
|
return link;
|
||||||
|
};
|
||||||
|
|
||||||
|
return link;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Populate the sourceLinks and targetLinks for each node.
|
||||||
|
// Also, if the source and target are not objects, assume they are indices.
|
||||||
|
function computeNodeLinks() {
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
node.sourceLinks = [];
|
||||||
|
node.targetLinks = [];
|
||||||
|
});
|
||||||
|
links.forEach(function(link) {
|
||||||
|
var source = link.source,
|
||||||
|
target = link.target;
|
||||||
|
if (typeof source === "number") source = link.source = nodes[link.source];
|
||||||
|
if (typeof target === "number") target = link.target = nodes[link.target];
|
||||||
|
source.sourceLinks.push(link);
|
||||||
|
target.targetLinks.push(link);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute the value (size) of each node by summing the associated links.
|
||||||
|
function computeNodeValues() {
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
node.value = Math.max(
|
||||||
|
d3.sum(node.sourceLinks, value),
|
||||||
|
d3.sum(node.targetLinks, value)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iteratively assign the breadth (x-position) for each node.
|
||||||
|
// Nodes are assigned the maximum breadth of incoming neighbors plus one;
|
||||||
|
// nodes with no incoming links are assigned breadth zero, while
|
||||||
|
// nodes with no outgoing links are assigned the maximum breadth.
|
||||||
|
function computeNodeBreadths() {
|
||||||
|
var remainingNodes = nodes,
|
||||||
|
nextNodes,
|
||||||
|
x = 0;
|
||||||
|
|
||||||
|
while (remainingNodes.length) {
|
||||||
|
nextNodes = [];
|
||||||
|
remainingNodes.forEach(function(node) {
|
||||||
|
node.x = x;
|
||||||
|
node.dx = nodeWidth;
|
||||||
|
node.sourceLinks.forEach(function(link) {
|
||||||
|
nextNodes.push(link.target);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
remainingNodes = nextNodes;
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
moveSinksRight(x);
|
||||||
|
scaleNodeBreadths((size[0] - nodeWidth) / (x - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveSourcesRight() {
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
if (!node.targetLinks.length) {
|
||||||
|
node.x = d3.min(node.sourceLinks, function(d) { return d.target.x; }) - 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveSinksRight(x) {
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
if (!node.sourceLinks.length) {
|
||||||
|
node.x = x - 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function scaleNodeBreadths(kx) {
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
node.x *= kx;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeNodeDepths(iterations) {
|
||||||
|
var nodesByBreadth = nest()
|
||||||
|
.key(function(d) { return d.x; })
|
||||||
|
.sortKeys(d3.ascending)
|
||||||
|
.entries(nodes)
|
||||||
|
.map(function(d) { return d.values; });
|
||||||
|
|
||||||
|
//
|
||||||
|
initializeNodeDepth();
|
||||||
|
resolveCollisions();
|
||||||
|
for (var alpha = 1; iterations > 0; --iterations) {
|
||||||
|
relaxRightToLeft(alpha *= .99);
|
||||||
|
resolveCollisions();
|
||||||
|
relaxLeftToRight(alpha);
|
||||||
|
resolveCollisions();
|
||||||
|
}
|
||||||
|
|
||||||
|
function initializeNodeDepth() {
|
||||||
|
var ky = d3.min(nodesByBreadth, function(nodes) {
|
||||||
|
return (size[1] - (nodes.length - 1) * nodePadding) / d3.sum(nodes, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
nodesByBreadth.forEach(function(nodes) {
|
||||||
|
nodes.forEach(function(node, i) {
|
||||||
|
node.y = i;
|
||||||
|
node.dy = node.value * ky;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
links.forEach(function(link) {
|
||||||
|
link.dy = link.value * ky;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function relaxLeftToRight(alpha) {
|
||||||
|
nodesByBreadth.forEach(function(nodes, breadth) {
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
if (node.targetLinks.length) {
|
||||||
|
var y = d3.sum(node.targetLinks, weightedSource) / d3.sum(node.targetLinks, value);
|
||||||
|
node.y += (y - center(node)) * alpha;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function weightedSource(link) {
|
||||||
|
return center(link.source) * link.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function relaxRightToLeft(alpha) {
|
||||||
|
nodesByBreadth.slice().reverse().forEach(function(nodes) {
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
if (node.sourceLinks.length) {
|
||||||
|
var y = d3.sum(node.sourceLinks, weightedTarget) / d3.sum(node.sourceLinks, value);
|
||||||
|
node.y += (y - center(node)) * alpha;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function weightedTarget(link) {
|
||||||
|
return center(link.target) * link.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveCollisions() {
|
||||||
|
nodesByBreadth.forEach(function(nodes) {
|
||||||
|
var node,
|
||||||
|
dy,
|
||||||
|
y0 = 0,
|
||||||
|
n = nodes.length,
|
||||||
|
i;
|
||||||
|
|
||||||
|
// Push any overlapping nodes down.
|
||||||
|
nodes.sort(ascendingDepth);
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
node = nodes[i];
|
||||||
|
dy = y0 - node.y;
|
||||||
|
if (dy > 0) node.y += dy;
|
||||||
|
y0 = node.y + node.dy + nodePadding;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the bottommost node goes outside the bounds, push it back up.
|
||||||
|
dy = y0 - nodePadding - size[1];
|
||||||
|
if (dy > 0) {
|
||||||
|
y0 = node.y -= dy;
|
||||||
|
|
||||||
|
// Push any overlapping nodes back up.
|
||||||
|
for (i = n - 2; i >= 0; --i) {
|
||||||
|
node = nodes[i];
|
||||||
|
dy = node.y + node.dy + nodePadding - y0;
|
||||||
|
if (dy > 0) node.y -= dy;
|
||||||
|
y0 = node.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function ascendingDepth(a, b) {
|
||||||
|
return a.y - b.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function computeLinkDepths() {
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
node.sourceLinks.sort(ascendingTargetDepth);
|
||||||
|
node.targetLinks.sort(ascendingSourceDepth);
|
||||||
|
});
|
||||||
|
nodes.forEach(function(node) {
|
||||||
|
var sy = 0, ty = 0;
|
||||||
|
node.sourceLinks.forEach(function(link) {
|
||||||
|
link.sy = sy;
|
||||||
|
sy += link.dy;
|
||||||
|
});
|
||||||
|
node.targetLinks.forEach(function(link) {
|
||||||
|
link.ty = ty;
|
||||||
|
ty += link.dy;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function ascendingSourceDepth(a, b) {
|
||||||
|
return a.source.y - b.source.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ascendingTargetDepth(a, b) {
|
||||||
|
return a.target.y - b.target.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function center(node) {
|
||||||
|
return node.y + node.dy / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
function value(link) {
|
||||||
|
return link.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sankey;
|
||||||
|
};
|
||||||
|
|
||||||
|
function nest() {
|
||||||
|
var keys = [],
|
||||||
|
sortKeys = [],
|
||||||
|
sortValues,
|
||||||
|
rollup,
|
||||||
|
nest;
|
||||||
|
|
||||||
|
function apply(array, depth, createResult, setResult) {
|
||||||
|
if (depth >= keys.length) {
|
||||||
|
if (sortValues != null) array.sort(sortValues);
|
||||||
|
return rollup != null ? rollup(array) : array;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = -1,
|
||||||
|
n = array.length,
|
||||||
|
key = keys[depth++],
|
||||||
|
keyValue,
|
||||||
|
value,
|
||||||
|
valuesByKey = map(),
|
||||||
|
values,
|
||||||
|
result = createResult();
|
||||||
|
|
||||||
|
while (++i < n) {
|
||||||
|
if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) {
|
||||||
|
values.push(value);
|
||||||
|
} else {
|
||||||
|
valuesByKey.set(keyValue, [value]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valuesByKey.each(function(values, key) {
|
||||||
|
setResult(result, key, apply(values, depth, createResult, setResult));
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function entries(map, depth) {
|
||||||
|
if (++depth > keys.length) return map;
|
||||||
|
var array, sortKey = sortKeys[depth - 1];
|
||||||
|
if (rollup != null && depth >= keys.length) array = map.entries();
|
||||||
|
else array = [], map.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); });
|
||||||
|
return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nest = {
|
||||||
|
object: function(array) { return apply(array, 0, createObject, setObject); },
|
||||||
|
map: function(array) { return apply(array, 0, createMap, setMap); },
|
||||||
|
entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); },
|
||||||
|
key: function(d) { keys.push(d); return nest; },
|
||||||
|
sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; },
|
||||||
|
sortValues: function(order) { sortValues = order; return nest; },
|
||||||
|
rollup: function(f) { rollup = f; return nest; }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const prefix = "$";
|
||||||
|
|
||||||
|
function Map() {}
|
||||||
|
|
||||||
|
Map.prototype = map.prototype = {
|
||||||
|
constructor: Map,
|
||||||
|
has: function(key) {
|
||||||
|
return (prefix + key) in this;
|
||||||
|
},
|
||||||
|
get: function(key) {
|
||||||
|
return this[prefix + key];
|
||||||
|
},
|
||||||
|
set: function(key, value) {
|
||||||
|
this[prefix + key] = value;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
remove: function(key) {
|
||||||
|
var property = prefix + key;
|
||||||
|
return property in this && delete this[property];
|
||||||
|
},
|
||||||
|
clear: function() {
|
||||||
|
for (var property in this) if (property[0] === prefix) delete this[property];
|
||||||
|
},
|
||||||
|
keys: function() {
|
||||||
|
var keys = [];
|
||||||
|
for (var property in this) if (property[0] === prefix) keys.push(property.slice(1));
|
||||||
|
return keys;
|
||||||
|
},
|
||||||
|
values: function() {
|
||||||
|
var values = [];
|
||||||
|
for (var property in this) if (property[0] === prefix) values.push(this[property]);
|
||||||
|
return values;
|
||||||
|
},
|
||||||
|
entries: function() {
|
||||||
|
var entries = [];
|
||||||
|
for (var property in this) if (property[0] === prefix) entries.push({key: property.slice(1), value: this[property]});
|
||||||
|
return entries;
|
||||||
|
},
|
||||||
|
size: function() {
|
||||||
|
var size = 0;
|
||||||
|
for (var property in this) if (property[0] === prefix) ++size;
|
||||||
|
return size;
|
||||||
|
},
|
||||||
|
empty: function() {
|
||||||
|
for (var property in this) if (property[0] === prefix) return false;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
each: function(f) {
|
||||||
|
for (var property in this) if (property[0] === prefix) f(this[property], property.slice(1), this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function map(object, f) {
|
||||||
|
var map = new Map;
|
||||||
|
|
||||||
|
// Copy constructor.
|
||||||
|
if (object instanceof Map) object.each(function(value, key) { map.set(key, value); });
|
||||||
|
|
||||||
|
// Index array by numeric index or specified key function.
|
||||||
|
else if (Array.isArray(object)) {
|
||||||
|
var i = -1,
|
||||||
|
n = object.length,
|
||||||
|
o;
|
||||||
|
|
||||||
|
if (f == null) while (++i < n) map.set(i, object[i]);
|
||||||
|
else while (++i < n) map.set(f(o = object[i], i, object), o);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert object to map.
|
||||||
|
else if (object) for (var key in object) map.set(key, object[key]);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createObject() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setObject(object, key, value) {
|
||||||
|
object[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createMap() {
|
||||||
|
return map();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setMap(map, key, value) {
|
||||||
|
map.set(key, value);
|
||||||
|
}
|
@ -2,5 +2,10 @@ import { sveltekit } from '@sveltejs/kit/vite';
|
|||||||
import { defineConfig } from 'vite';
|
import { defineConfig } from 'vite';
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [sveltekit()]
|
plugins: [sveltekit()],
|
||||||
|
build: {
|
||||||
|
commonjsOptions: {
|
||||||
|
esmExternals: true
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user