Published
Edited
Aug 26, 2020
1 star
Insert cell
Insert cell
svg = {
let svg_width = width;
let svg_height =
((bounds.ymax - bounds.ymin) / (bounds.xmax - bounds.xmin)) * svg_width;
let svg = d3
.create('svg')
.attr('width', svg_width)
.attr('height', svg_height);

let x_scale = d3
.scaleLinear()
.domain([bounds.xmin, bounds.xmax])
.range([0, svg_width]);
let y_scale = d3
.scaleLinear()
.domain([bounds.ymin, bounds.ymax])
.range([svg_height, 0]);
let pts_to_path = d3
.line()
.x(function(d) {
return x_scale(d[0]);
})
.y(function(d) {
return y_scale(d[1]);
});

svg
.selectAll('path.tri')
.data(all_triangles.flat(1))
.join("path")
.attr('class', 'tri')
.attr('d', function(d) {
return pts_to_path(d.pts) + 'Z';
})
.attr("stroke", "white")
.attr("stroke-width", .2)
.attr('fill', d => color(d.province_code));

svg
.selectAll('path.seg')
.data(all_segments)
.enter()
.append("path")
.attr('class', 'seg')
.attr('d', function(d) {
return pts_to_path(d);
})
.attr("stroke", "black")
.attr("stroke-width", 2)
.attr('fill', 'none');

return svg.node();
}
Insert cell
bounds = {
let xs = all_pts.map(xy => xy[0]);
let ys = all_pts.map(xy => xy[1]);
let xmin = d3.min(xs);
let xmax = d3.max(xs);
let ymin = d3.min(ys);
let ymax = d3.max(ys);
return { xmin: xmin, ymin: ymin, xmax: xmax, ymax: ymax };
}
Insert cell
triangulated_regions = FileAttachment('provinces_triangulated.json').json()
Insert cell
d3 = require('d3@5')
Insert cell
// all_triangles = triangulated_regions.map(o => Object.values(o.pts)).flat()

all_triangles = {
return triangulated_regions.map(function(region) {
let result = {};
let all_pts = region.pts;
let all_triangles = region.triangles;
for (let key in all_triangles) {
let pts = all_pts[key];
let triangles = all_triangles[key];
result[key] = triangles.map(t => t.map(v => pts[v]));
}
let array_result = [];
for (let key in result) {
array_result.push(result[key]);
}
array_result = array_result.flat(1);
let province_code = region.properties.PROVCODE;
return array_result.map(pts => ({
province_code,
pts
}));
});
}
Insert cell
all_pts = {
return triangulated_regions
.map(function(region) {
let result = {};
let all_pts = region.pts;
for (let key in all_pts) {
let pts = all_pts[key];
result[key] = pts;
}
let array_result = [];
for (let key in result) {
array_result.push(result[key]);
}
return array_result.flat(1);
})
.flat(1);
}
Insert cell
all_segments = {
return triangulated_regions
.map(function(region) {
let result = {};
let all_pts = region.pts;
let all_segments = region.segments;
for (let key in all_segments) {
let pts = all_pts[key];
let segments = all_segments[key];
result[key] = segments.map(t => t.map(v => pts[v]));
}
let array_result = [];
for (let key in result) {
array_result.push(result[key]);
}
return array_result.flat(1);
})
.flat(1);
}
Insert cell
function color(p) {
if (p == 'AB') {
return d3.schemeCategory10[0];
} else if (p == 'QC') {
return d3.schemeCategory10[5];
} else if (p == 'ON') {
return d3.schemeCategory10[2];
} else if (p == 'NS') {
return d3.schemeCategory10[3];
} else if (p == 'SK') {
return d3.schemeCategory10[4];
} else if (p == 'BC') {
return d3.schemeCategory10[5];
} else if (p == 'PE') {
return d3.schemeCategory10[6];
} else if (p == 'MB') {
return d3.schemeCategory10[7];
} else if (p == 'NL') {
return d3.schemeCategory10[8];
} else if (p == 'YT') {
return d3.schemeCategory10[9];
} else if (p == 'NT') {
return d3.schemeCategory10[2];
} else if (p == 'NU') {
return d3.schemeCategory10[1];
} else if (p == 'NB') {
return d3.schemeCategory10[0];
} else {
return 'black';
}
}
Insert cell
all_triangles
Insert cell
triangulated_regions.map(o =>
Object.values(o.pts).map(pp => ({
province_code: o.properties.PROVCODE,
pts: o.pts
}))
)
Insert cell
triangulated_regions
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