Published
Edited
Aug 10, 2019
Insert cell
Insert cell
Insert cell
Insert cell
firstName = "Alan"
Insert cell
lastName = "McConchie"
Insert cell
handle = "mappingmashups"
Insert cell
us = d3.json("https://gist.githubusercontent.com/almccon/3ab3802dc6837949775a58c7eef65bb5/raw/bd155ff6eff784ba0bff22cca5dd85c49f542828/us.json")
Insert cell
points = d3.csv("https://gist.githubusercontent.com/almccon/3ab3802dc6837949775a58c7eef65bb5/raw/bd155ff6eff784ba0bff22cca5dd85c49f542828/pvscoords.csv");
Insert cell
d3 = require("d3@5", "d3-hexbin@0.2")
Insert cell
topojson = require("https://d3js.org/topojson.v2.min.js");
Insert cell
hexbin = require("https://d3js.org/d3-hexbin.v0.2.min.js");
Insert cell
projection = d3.geoAlbersUsa().translate([width/2,height/1.83]).scale(width*1.35);
Insert cell
path = d3.geoPath().projection(projection);
Insert cell
hexbinRadius = 20;
Insert cell
hexbinner = d3.hexbin().extent([[0, 0], [width, height]]).radius(hexbinRadius);
Insert cell
hexbinner.x(d => {
return projection([+d.lon,+d.lat]) ? projection([+d.lon,+d.lat])[0] : null;
});
Insert cell
hexbinner.y(d => {
return projection([+d.lon,+d.lat]) ? projection([+d.lon,+d.lat])[1] : null;
});
Insert cell
points.forEach(d => {
d.SUMPOP = +d.pop;
d.SUMSODA = +d.soda;
d.SUMCOKE = +d.coke;
d.SUMOTHER = +d.other;
d.PCTPOP = d.SUMPOP/+d.count;
d.PCTSODA = d.SUMSODA/+d.count;
d.PCTCOKE = d.SUMCOKE/+d.count;
d.PCTOTHER = d.SUMOTHER/+d.count;
d.lat = +d.lat;
d.lon = +d.lon;
d.count = +d.count;
});
Insert cell
bins = hexbinner(points);
Insert cell
clip = new Path2D(path(topojson.feature(us, us.objects.land)));
Insert cell
// Your D3 code goes here.
// The function badgeCode gets called below to generate the previews.
function badgeCode(g, context, frameNumber) {
// g: a <g>, i.e. d3.select(... the node)
// context: a canvas context, useful for doing canvas drawing
// frameNumber: a number that represents the frame (1, 2, … 10) for psuedo-animation.
// width & height are available via the environment, as is d3
// Note: the <g> is drawn on top of the <canvas>

context.fillStyle = "#34495e";
context.fillRect(0, 0, width, height);
context.fillStyle = "#fff";

context.fill(clip);
//context.globalCompositeOperation = "source-atop";
var hex = new Path2D(hexbinner.hexagon());
bins.forEach(function(bin) {
context.translate(bin.x,bin.y);
var arrayvalues = Array.from(bin);
var sum = d3.sum(arrayvalues, i => i.count)
bin.PCTPOP = d3.sum(arrayvalues, i => i.SUMPOP)/sum;
bin.PCTSODA = d3.sum(arrayvalues, i => i.SUMSODA)/sum;
bin.PCTCOKE = d3.sum(arrayvalues, i => i.SUMCOKE)/sum;
bin.PCTOTHER = d3.sum(arrayvalues, i => i.SUMOTHER)/sum;

if (bin.PCTPOP == 0 && bin.PCTSODA == 0 && bin.PCTCOKE == 0 && bin.PCTOTHER == 0) {
context.fillStyle = "white";
} else {
var color = "white";
switch(frameNumber) {
case 1:
color = "rgb("
+ Math.round((1-bin.PCTSODA) * 100) + "%,"
+ Math.round((1) * 100) + "%,"
+ Math.round((1) * 100) + "%)";
break;
case 2:
color = "rgb("
+ Math.round((1-bin.PCTSODA) * 100) + "%,"
+ Math.round((1) * 100) + "%,"
+ Math.round((1-(0.3*bin.PCTPOP)) * 100) + "%)";
break;
case 3:
color = "rgb("
+ Math.round((1-(0.3*bin.PCTSODA)) * 100) + "%,"
+ Math.round((1) * 100) + "%,"
+ Math.round((1-bin.PCTPOP) * 100) + "%)";
break;
case 4:
color = "rgb("
+ Math.round((1) * 100) + "%,"
+ Math.round((1) * 100) + "%,"
+ Math.round((1-bin.PCTPOP) * 100) + "%)";
break;
case 5:
color = "rgb("
+ Math.round((1) * 100) + "%,"
+ Math.round((1-(0.3*bin.PCTCOKE)) * 100) + "%,"
+ Math.round((1-bin.PCTPOP) * 100) + "%)";
break;
case 6:
color = "rgb("
+ Math.round((1) * 100) + "%,"
+ Math.round((1-bin.PCTCOKE) * 100) + "%,"
+ Math.round((1-(0.3*bin.PCTPOP)) * 100) + "%)";
break;
case 7:
color = "rgb("
+ Math.round((1) * 100) + "%,"
+ Math.round((1-bin.PCTCOKE) * 100) + "%,"
+ Math.round((1) * 100) + "%)";
break;
case 8:
color = "rgb("
+ Math.round((1-(0.3*bin.PCTSODA)) * 100) + "%,"
+ Math.round((1-bin.PCTCOKE) * 100) + "%,"
+ Math.round((1) * 100) + "%)";
break;
case 9:
color = "rgb("
+ Math.round((1-bin.PCTSODA) * 100) + "%,"
+ Math.round((1-(0.3*bin.PCTCOKE)) * 100) + "%,"
+ Math.round((1) * 100) + "%)";
break;
case 10:
color = "rgb("
+ Math.round((1-bin.PCTSODA) * 100) + "%,"
+ Math.round((1) * 100) + "%,"
+ Math.round((1) * 100) + "%)";
break;
}
context.fillStyle = color;
}
context.fill(hex);
context.setTransform(1, 0, 0, 1, 0, 0);
});
context.stroke(clip);

}
Insert cell
isTextLight = true
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
import {preview, animation, download, width, height}
with {firstName, lastName, handle, isTextLight, badgeCode}
from "b93171820ba3f268"
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