1
0
mirror of https://github.com/d3/d3.git synced 2025-12-08 19:46:24 +00:00
d3/docs/components/UsMap.vue
2023-06-09 15:38:01 -07:00

53 lines
1.7 KiB
Vue

<script setup>
import * as d3 from "d3";
import * as topojson from "topojson-client";
import deferRender from "./deferRender.js";
</script>
<script>
let objectsPromise;
async function render(node, {projection}) {
const {statemesh, countymesh, nation} = await objectsPromise;
const path = d3.geoPath(projection);
const svg = d3.select(node);
svg.selectAll("[name='countymesh']").attr("d", path(countymesh));
svg.selectAll("[name='statemesh']").attr("d", path(statemesh));
svg.selectAll("[name='nation']").attr("d", path(nation));
}
export default {
props: {
projection: {type: Function},
width: {type: Number, default: 688},
height: {type: Number, default: 400},
},
mounted() {
objectsPromise ??= d3 // TODO counties, states?
.json(`https://cdn.jsdelivr.net/npm/us-atlas@3.0.1/counties-10m.json`)
.then((us) => ({
nation: topojson.feature(us, us.objects.nation),
statemesh: topojson.mesh(us, us.objects.states, (a, b) => a !== b),
countymesh: topojson.mesh(us, us.objects.counties, (a, b) => a !== b && (a.id / 1000 | 0) === (b.id / 1000 | 0)),
}));
this.disconnect = deferRender(this.$el, async () => render(this.$el, this));
},
updated() {
render(this.$el, this);
},
unmounted() {
if (this.disconnect) this.disconnect();
}
}
</script>
<template>
<svg :width="width" :height="height" :viewBox="[0, 0, width, height].join(' ')" style="max-width: 100%; height: auto;">
<path name="nation" stroke="currentColor" fill="var(--vp-c-bg-alt)" />
<path name="statemesh" fill="none" stroke="currentColor" stroke-width="0.5" />
<path name="countymesh" fill="none" stroke="currentColor" stroke-width="0.5" stroke-opacity="0.5" />
</svg>
</template>