class Chart {
constructor(dataMap, radius, fill = {}) {
const data = Array.from(dataMap).map((d) => d[1]);
const interval = 500;
const width = 960;
const height = 600;
const path = d3.geoPath();
const projection = d3.geoAlbersUsa().scale(1280).translate([width / 2, height / 2]);
this.radius = radius;
this.fill = fill;
const svg = d3.select(DOM.svg(width, height))
.style("width", "100%")
.style("font-family", "sans-serif")
.style("height", "auto");
svg.append("path")
.datum(topojson.feature(us, us.objects.nation))
.attr("fill", "#ccc")
.attr("d", path);
svg.append("path")
.datum(topojson.mesh(us, us.objects.states, (a, b) => a !== b))
.attr("fill", "none")
.attr("stroke", "white")
.attr("stroke-linejoin", "round")
.attr("d", path);
this.circles = svg.append("g")
.attr("stroke", "#fff")
.attr("opacity", () => (this.fill.scale !== undefined) ? 1 : 0.5)
.attr("stroke-width", 0.5)
.selectAll("circle")
.data(data).enter()
.append("circle")
.attr("transform", d => `translate(${projection(d.geometry.coordinates)})`)
.attr("r", 5);
this.div = DOM.element("div");
const input = this.drawInput(1, 12);
this.div.appendChild(svg.node());
this.div.appendChild(input);
}
drawInput(min, max) {
const div = html`
<input type=range min=${min} max=${max} value=${min} step=1>
<input type=number min=${min} max=${max} value=${min} style="width:50px">
`;
const range = div.querySelector("[type=range]");
const number = div.querySelector("[type=number]");
div.value = range.value = number.value = min;
const update = _.debounce(() => { this.update(div.value); }, 300);
range.addEventListener("input", () => {
number.value = div.value = range.valueAsNumber;
update();
});
number.addEventListener("input", () => {
range.value = div.value = number.valueAsNumber;
update();
});
return div;
}
}