Published
Edited
Nov 16, 2020
3 forks
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
map = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, 975, 610]);

svg.append(legend)
.attr("transform", "translate(870,450)");

var countyMap = svg.append("g")
.selectAll("path")
.data(topojson.feature(us, us.objects.counties).features)
.join("path")
.attr("fill", d => color(data.get(d.id+" "+dateToString(date))))
.attr("d", path)
.append("title")
.text(d => `${d.properties.name}, ${states.get(d.id.slice(0, 2)).name}
${format(data.get(d.id+" "+ dateToString(date)))}`);

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);

// Update the fill based on date scrubber
function update(date) {
countyMap.attr("fill", function(d) {
var fclass = data.get(d.id+" "+dateToString(date));
//console.log(d.id+" "+dateToString(date))
//console.log(fclass)
//console.log(data.get(d.id+" "+dateToString(date)))
//if (fclass) {
// var fcolor = color(fclass);
// } else {
// var fcolor = "#cccc";
// }
// return fcolor ;

});
}
//return svg.node();
return Object.assign(svg.node(), {update});
}
Insert cell
legend = () => {
const k = 24;
const arrow = DOM.uid();
return svg`<g font-family=sans-serif font-size=10>
<g transform="translate(-${k * n / 2},-${k * n / 2}) rotate(-45 ${k * n / 2},${k * n / 2})">
<marker id="${arrow.id}" markerHeight=10 markerWidth=10 refX=6 refY=3 orient=auto>
<path d="M0,0L9,3L0,6Z" />
</marker>
${d3.cross(d3.range(n), d3.range(n)).map(([i, j]) => svg`<rect width=${k} height=${k} x=${i * k} y=${(n - 1 - j) * k} fill=${colors[j * n + i]}>
<title>${data.title[0]}${ labelsRR[j]&&` (${labelsRR[j]})` }
${data.title[1]}${labels[i] && ` (${labels[i]})`}</title>
</rect>`)}
<line marker-end="${arrow}" x1=0 x2=${n * k} y1=${n * k} y2=${n * k} stroke=black stroke-width=1.5 />
<line marker-end="${arrow}" y2=0 y1=${n * k} stroke=black stroke-width=1.5 />
<text font-weight="bold" dy="0.71em" transform="rotate(90) translate(${n / 2 * k},6)" text-anchor="middle">${data.title[0]}</text>
<text font-weight="bold" dy="0.71em" transform="translate(${n / 2 * k},${n * k + 6})" text-anchor="middle">${data.title[1]}</text>
</g>
</g>`;
}
Insert cell
Insert cell
Insert cell
//counties = FileAttachment("us_states@1.json").json()
Insert cell
data = Object.assign(new Map(
await d3.csv("https://raw.githubusercontent.com/YuLan1014/Vis/master/biv14RR1_1001.csv", ({LOC_ID, date, REL_RISK, cc}) => [(LOC_ID+ " "+date), [+REL_RISK, +cc]])),
{title: ["Relative Risk", "#HighRiskCluster"]}
)

//number of days within the cluster
//https://raw.githubusercontent.com/YuLan1014/Vis/master/biv_1017.csv

//number of days within the cluster with the thresholde of 14 days (rr>0)
//https://raw.githubusercontent.com/YuLan1014/Vis/master/biv14_1001.csv

//number of days within the cluster with the thresholde of 14 days (rr>1)
//https://raw.githubusercontent.com/YuLan1014/Vis/master/biv14RR1_1001.csv
//test
//https://raw.githubusercontent.com/YuLan1014/Vis/master/test.csv
Insert cell
labels = ["lowest", "low","medium", "high"]

Insert cell
labelsRR= ["Group 1", "Group 2","Group 3", "Group 4"]
Insert cell
n = Math.floor(Math.sqrt(colors.length))
Insert cell
//x = d3.scaleLinear([0.053, 0.128,0.295 ,1000], d3.range(n))
x = d3.scaleQuantile(Array.from(data.values(), d => d[0]), d3.range(n))
Insert cell
//y = d3.scaleLinear([0.053, 0.128,0.295 ,1000], d3.range(n))
//y = d3.scaleQuantile(Array.from(data.values(), d => d[1]), d3.range(n))
y = d3.scaleQuantile([1,14], d3.range(n))
Insert cell
path = d3.geoPath()
Insert cell
color = {
return value => {
if (!value) return "#ccc";
let [a, b] = value;
return colors[y(b) + x(a) * n];
};
}
Insert cell
Insert cell
format = (value) => {
if (!value) return "N/A";
let [a, b] = value;
return `${data.title[0]} ${a} ${labelsRR[x(a)] && ` (${labelsRR[x(a)]})`}
${data.title[1]} ${b} ${labels[y(b)] && ` (${labels[y(b)]})`}`;
}
Insert cell
//clean.filter(d => d[1] === dates[dates.length-1]).map(d => d[2])
Insert cell
//d => d[1] === dates[dates.length-1]
Insert cell
schemes = [
{
name: "RdBu",
colors: [
"#D3CFE6", "#A5BEDB", "#76ADD0","#489CC5",
"#D0A2CE", "#A395C5", "#7588BA","#477AB1",
"#CD74B5", "#A06BAD", "#7361A4","#46589C",
"#CA479E", "#9E4196", "#713B8F","#453687"
]
},
{
name: "RdBu",
colors: [
"#D3CFE6", "#A5BEDB", "#76ADD0","#489CC5",
"#D0A2CE", "#A395C5", "#7588BA","#477AB1",
"#CD74B5", "#A06BAD", "#7361A4","#46589C",
"#CA479E", "#9E4196", "#713B8F","#453687"
]
}
]
Insert cell
//color = d3.scaleQuantile(d3.schemeRdPu[bins]).domain(clean.filter(d => d[1] === dates[dates.length-1]).map(d => d[2]));
Insert cell
//path = d3.geoPath().projection(projection);
Insert cell
//projection = d3.geoAlbersUsa().ranslate( [width/2, height/2] );
Insert cell
//states = new Map(us.objects.states.geometries.map(d => [d.id, d.properties]));
states = new Map(us.objects.states.geometries.map(d => [d.id, d.properties]));

Insert cell
us = FileAttachment("counties-albers-10m@9.json").json()
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3@5")
Insert cell
Insert cell
//import {legend} from "@d3/color-legend"
Insert cell
Insert cell
Insert cell
Insert cell
function dateToString(date) {
var year = date.getFullYear();
var month = ("0" + (date.getMonth() + 1)).slice(-2);
var day = ("0" + date.getDate()).slice(-2);
return `${year}-${month}-${day}`;
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
md
`## References

1. Animated Map of COVID-19 Cases:
https://observablehq.com/@onoratod/animated-map-of-covid-19-cases

2. Bivariate Choropleth:
https://observablehq.com/@d3/bivariate-choropleth
`
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more