Published
Edited
Dec 8, 2020
Insert cell
md`# scooter`
Insert cell
Insert cell
Insert cell
Insert cell
geo2square = {
//create SVG artboard
let svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("width", width)
.attr("height", height)
.attr('id', 'mapArea');

//create svg background color
let bg = svg
.append('rect')
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.attr('fill', '#000');

// create Map grouping for asset management
let mapGroup = svg.append("g").attr("id", "map");

//convert area of shapes to 0-1 range, and therefore colors
let areaScale = d3
.scaleLinear()
.domain(
d3.extent(areas.features, d => parseFloat(d.properties.area_numbe))
);

//we start in geography mode
let toggle = 0;

//draw shapes
mapGroup
.selectAll('.areas')
.data(areas.features)
.enter()
.append('path')
.attr('class', 'areas')
.attr('d', d => d.properties.geoPath)
.attr('opacity', 1)
.attr('fill', d =>
d3.interpolateWarm(areaScale(parseFloat(d.properties.area_numbe)))
)

//when clicked....
.on('click', function(clickedArea) {
//check if we're in geography mode
if (toggle == 0) {
//if so, transform to square mode
d3.selectAll('.areas')
.data(areas.features)
//transition to transform, recolor, and slide the squares over
.transition()
.duration(1000)
.attr('opacity', function(d) {
if (d.properties.area_numbe == 1) {
return 0;
} else {
return 1;
}
})
.transition()
.duration(1000)

.attr('fill', d =>
d3.interpolateCool(areaScale(parseFloat(d.properties.area_numbe)))
)
//switch to square paths
.attr('d', function(d) {
if (d.properties.area_numbe == 1) {
return d.properties.geoPath;
} else {
return d.properties.squarePath;
}
})
.attr('transform', function(d) {
let xMove =
width / 2 - d.properties.squareX + parseInt(d.properties.x);
let yMove = parseInt(d.properties.y) - d.properties.squareY;

return 'translate(' + xMove + ',' + yMove + ')';
});

//now we're in square mode!
toggle = 1;
} else {
//undo the transformations back to geography mode
mapGroup
.selectAll('.areas')
.data(areas.features)
.transition()
.duration(1000)
.attr('fill', d =>
d3.interpolateCool(areaScale(parseFloat(d.properties.area_numbe)))
)
.attr('d', d => d.properties.geoPath)
.attr('fill', d =>
d3.interpolateWarm(areaScale(parseFloat(d.properties.area_numbe)))
)
.attr('transform', "")
.transition()
.duration(1000)
.attr('opacity', 1);
//now we're in geography mode again
toggle = 0;
}
});

return svg.node();
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
buildPaths = {
for (let i = 0; i < areas.features.length; i++) {
let area = areas.features[i];

//project coordinates to pixels
let projected = area.geometry.coordinates[0][0].map(projection);

//store drawing instruction for the geographic shape
area.properties.geoPath = path(area);

let squarePath = d3.geo2square(projected, squareSize, squareSize);

//store drawing instruction for the rectangular shape
area.properties.squarePath = line(squarePath);

//store the left coordinate of the generated square
area.properties.squareX = d3.min(squarePath, d => d[0]);

//store the top coordinate of the generated square
area.properties.squareY = d3.min(squarePath, d => d[1]);
}
return "square paths built!";
}
Insert cell
Insert cell
d3 = require('d3@5')
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