Published
Edited
Nov 17, 2020
1 fork
Insert cell
md`# Pattern Language UI Prototype`
Insert cell
d3 = require("d3@5")
Insert cell
nbs = FileAttachment("boundaries_neighborhoods.geojson").json()
Insert cell
Insert cell
UI={
//svg variables
let width = 800;
let height = 400;
let bar = 25;
let expand = 6;
let panelLeft = 0;
let panelBottom = 0;
let panelRight = 0;
let panelTop = 0;
//create SVG artboard
let svg = d3
.create("svg")
.attr("viewBox", [0, 0, width, height])
.attr("width", width)
.attr("height", height);
//create svg background color
let bg = svg
.append('rect')
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.attr('fill', '#FFFFFF');
// create Map grouping for asset management
let mapGroup = svg
.append("g")
.attr("id","map")

function zoomed() {
mapGroup
.selectAll('path') // To prevent stroke width from scaling
.attr('transform', d3.event.transform);
}

const zoom = d3.zoom()
.scaleExtent([1, 10])
.on('zoom', zoomed);

mapGroup.call(zoom);
// Use Mercator projection - how we interrelate svg coordinates to map coordinates
var projection = d3.geoMercator()
.fitExtent([[20, 20], [width, height]], nbs);

var path = d3.geoPath()
.projection(projection);
// Make area scale
let areaScale = d3.scaleLinear()
.domain(d3.extent(nbs.features,d=>parseFloat (d.properties.shape_area)))
//d=>d.shape_area, same as d function d.shape_area "in lay terms, within each element (row) get me shape area (column)"
.range([0,1])
// Draw each geoentity as a path
mapGroup.selectAll('path')
.data(nbs.features)
.enter().append('path')
.attr('d', path)
// Styling
.style('fill',
function (d){
return d3.interpolateGreys(areaScale(parseFloat(d.properties.shape_area)))
// take data point as string (shape_area) turn it into number (parse float), turn it into parameter between 0 and 1 (areaScale), turn that into a color (interpolatePlasma)
})
.style('stroke', '#ccc')

// create UI grouping for asset management
let uiGroup = svg
.append("g")
.attr("id","UI")
//top-options
let options = uiGroup
.append('rect')
.attr("x", 0)
.attr("y", 0)
.attr("width", width-bar)
.attr("height", bar)
.attr('fill', '#FFFFFF')
.attr('stroke','#000000')
.attr('stroke-width',2);
//right-people
let people = uiGroup
.append('rect')
.attr("x", width-bar)
.attr("y", 0)
.attr("width", bar)
.attr("height", height-bar)
.attr('fill', '#E2B100')
.attr('stroke','#000000')
.attr('stroke-width',2)
.on("click",function(){
if(panelRight == 0){
//expand
d3.select(this)
.transition()
.duration(600)
.attr("width",bar*expand)
.attr("x",width-bar*expand)
panelRight = 1;
}
else{
d3.select(this)
.transition()
.duration(600)
.attr("width",bar)
.attr("x",width-bar)
panelRight = 0;
}
})
;
//bottom-place
let place = uiGroup
.append('rect')
.attr("x", bar)
.attr("y", height-bar)
.attr("width", width-bar)
.attr("height", bar)
.attr('fill', '#B64B0E')
.attr('stroke','#000000')
.attr('stroke-width',2)
.on("click",function(){
if(panelBottom == 0){
//expand
d3.select(this)
.transition()
.duration(600)
.attr("height",bar*expand)
.attr("y",height-bar*expand)
panelBottom = 1;
}
else{
d3.select(this)
.transition()
.duration(600)
.attr("height",bar)
.attr("y",height-bar)
panelBottom = 0;
}
})
;
//left-pattern
let pattern = uiGroup
.append('rect')
.attr("x", 0)
.attr("y", bar)
.attr("width", bar)
.attr("height", height-bar)
.attr('stroke','#000000')
.attr('stroke-width',2)
.attr('fill', '#4800E2')
.on("click",function(){
if(panelLeft == 0){
//expand
d3.select(this)
.transition()
.duration(600)
.attr("width",bar*expand)
panelLeft = 1;
}
else{
d3.select(this)
.transition()
.duration(600)
.attr("width",bar)
panelLeft = 0;
}
})
;

return svg.node();
}
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