-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmap.mjs
92 lines (79 loc) · 2.31 KB
/
map.mjs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { XMLParser, XMLBuilder } from 'fast-xml-parser';
import chroma from 'chroma-js';
import { optimize } from 'svgo';
import fs from 'fs/promises';
import path from 'path';
import { getStates } from './states.mjs';
import { compileTemplate } from '@vue/compiler-sfc';
const MAP = path.join(__dirname, 'map.svg');
let handle;
const scale = chroma.scale(['#E3BADF', '#43398C', '#1D122B']).domain([0, 100]);
async function renderSvg() {
const states = await getStates(false);
const parser = new XMLParser({ ignoreAttributes: false });
const builder = new XMLBuilder({ ignoreAttributes: false });
const map = parser.parse(await fs.readFile(MAP, { encoding: 'utf-8' }));
for (const state of states) {
const el = map.svg.g.path.find((p) => p['@_id'] === state.slug);
if (el) {
el['@_fill'] = scale(state.performance[0].percentage).hex();
}
}
const { data } = optimize(builder.build(map), {
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false,
cleanupIds: false,
},
},
},
],
});
return data;
}
export default function () {
const virtualFileId = '@data/map';
return {
name: 'virtual-map',
resolveId(id) {
if (id.startsWith(virtualFileId)) {
return id;
}
},
async configureServer(server) {
const svg = await renderSvg();
server.middlewares.use((req, res, next) => {
if (req.url === `/${virtualFileId}`) {
res.setHeader('Content-Type', 'image/svg+xml');
return res.end(svg, 'utf-8');
}
next();
});
},
async load(id) {
if (id.startsWith(virtualFileId)) {
const svg = await renderSvg();
if (id.endsWith('?component')) {
const { code } = compileTemplate({
id: JSON.stringify(id),
source: svg,
transformAssetUrls: false,
});
return `${code}\nexport default render`;
}
if (this.meta.watchMode) {
return `const data = '/${virtualFileId}'; export default data;`;
}
handle = this.emitFile({
name: 'map.svg',
source: svg,
type: 'asset',
});
return `export default import.meta.ROLLUP_FILE_URL_${handle};`;
}
},
};
}