Published
Edited
Aug 10, 2020
1 fork
Insert cell
Insert cell
chart = {
const width = 975;
const height = 610;

const zoom = d3
.zoom()
.scaleExtent([1, 4])
.on("zoom", zoomed);

const svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, height])
.on("click", reset);

const g = svg.append("g");

const projection = d3
.geoAlbersUsa()
.fitSize(
[width, height],
topojson.feature(maryland, maryland.objects.Maryland_Counties)
);

const path = d3.geoPath().projection(projection);

g.append("g")
.attr("cursor", "pointer")
.attr("stroke", "grey")
.attr("stroke-width", 0.75)
.selectAll("path")
.data(
topojson.feature(maryland, maryland.objects.Maryland_Counties).features
)
.join("path")
.attr("fill", d => color(mdcases.get(d.properties.FIPS)))
.on("click", clicked)
.attr("d", path)
.on('mouseover', function(d) {
this.classList.add('hovered');
d3.select(this)
.attr("stroke", "black")
.raise();
tooltip.style('display', '');
let node = tooltip.node();
node.innerHTML = "";
node.appendChild(getTooltipContents(d));
})
.on('mousemove', function() {
tooltip
.style('top', Math.min(d3.event.pageY - 10, height - 135) + 'px')
.style(
'left',
(d3.event.pageX + 125 <= width
? d3.event.pageX + 10
: d3.event.pageX - 135) + 'px'
);
})
.on('mouseout', function() {
this.classList.remove('hovered');
d3.select(this)
.attr("stroke", null)
.lower();
tooltip.style('display', 'none');
});

// .on('doubleclick', function (reset) {
// svg.transition().duration(750).call(
// zoom.transform,
// d3.zoomIdentity,
// d3.zoomTransform(svg.node()).invert([width / 2, height / 2])
// );
// });

svg.call(zoom);

function reset() {
svg
.transition()
.duration(750)
.call(
zoom.transform,
d3.zoomIdentity,
d3.zoomTransform(svg.node()).invert([width / 2, height / 2])
);
}

function clicked(d) {
const [[x0, y0], [x1, y1]] = path.bounds(d);
d3.event.stopPropagation();
svg
.transition()
.duration(750)
.call(
zoom.transform,
d3.zoomIdentity
.translate(width / 2, height / 2)
.scale(
Math.min(3, 0.9 / Math.max((x1 - x0) / width, (y1 - y0) / height))
)
.translate(-(x0 + x1) / 2, -(y0 + y1) / 2),
d3.mouse(svg.node())
);
}

function zoomed() {
const { transform } = d3.event;
g.attr("transform", transform);
g.attr("stroke-width", 1 / transform.k);
}

return svg.node();
}
Insert cell
getTooltipContents = d => {
function getlowestfraction(x0) {
var eps = 0.01;
var h, h1, h2, k, k1, k2, a, x;

x = x0;
a = Math.floor(x);
h1 = 1;
k1 = 0;
h = a;
k = 1;

while (x - a > eps * k * k) {
x = 1 / (x - a);
a = Math.floor(x);
h2 = h1;
h1 = h;
k2 = k1;
k1 = k;
h = h2 + a * h1;
k = k2 + a * k1;
}

return h + " in " + k + " residents";
}

return html` <div class = "container">
<div class = "county"> ${d.properties.NAME} </div>
<div class = "totalCases">
<div class = "desc"> Tests per 100,000 residents </div>
<div class = "cases"> ${d3.format(",.1f")(
mdcases.get(d.properties.FIPS)
)} </div>
<div class = "deaths"> ${getlowestfraction(
mdcases.get(d.properties.FIPS) / 100000
)} </div>
</div>
</div> `;
}
Insert cell
Insert cell
Insert cell
html`
<style>
.tooltip {
background: white;
border: 1px solid lightgrey;
padding: 10px;
position: absolute;
font-family: Helvetica, Arial, sans-serif;
}
.county {
font-weight: 700;
font-size: 16px;
}
.desc {
font-size: 11px;
text-transform: uppercase;
color: grey;
}
.descTwo {
font-size: 11px;
text-transform: uppercase;
color: grey;
margin-top: 5px;
}
.deaths {
font-size: 14px;
}
.cases {
font-size: 14px;
}
.lineChart {
float: left;
width:100px;
height:50px;
color: grey;
}
</style>
`
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more