Published
Edited
Apr 30, 2021
1 star
Insert cell
md`## SIGGRAPH Conferences Map and Calendar`
Insert cell
map = {
const node = DOM.svg(width, 500)
const svg = d3.select(node)
.attr('style',
'border: 1px solid salmon;' +
'background-color: PowderBlue;'
)
;
svg.append('path')
.attr('d', projLand)
.attr('fill','LightGreen')
.attr('stroke','salmon')
;
svg.selectAll('circle')
.data(viewable_year_map_data).enter()
.append("circle")
.attr("cx", function (d) { return proj(d.latlng)[0]; })
.attr("cy", function (d) { return proj(d.latlng)[1]; })
.attr("r", "3px")
.attr("fill", "red")
;
return svg.node();
}
Insert cell
calendar = {
const svg = d3.create("svg")
.attr("viewBox", [0, 0, width, height*2.0])
.attr("font-family", "sans-serif")
.attr("font-size", 10);
//const year = svg.selectAll("g")
const year = svg.append("g")
.attr("transform", `translate(40.5,${cellHeight * 5.0})`);
year.append("g")
.attr("text-anchor", "end")
.selectAll("text")
.data(d3.range(7))
.join("text")
.attr("x", -5)
.attr("y", i => (i + 0.5) * cellHeight)
.attr("dy", "0.31em")
.text(formatDay);
year.append("text")
.attr("x", -5)
.attr("y", -5)
.attr("font-weight", "bold")
.attr("text-anchor", "end")
.text(ACTIVEYEAR);
year.append("g")
.selectAll("rect")
.data(viewable_year_cal_all_day_data)
.join("rect")
.attr("width", cellWidth - 1)
.attr("height", cellHeight - 1)
.attr("x", d => timeWeek.count(d3.utcYear(d), d) * cellWidth + 0.5)
.attr("y", d => d.getUTCDay() * cellHeight + 0.5)
.attr("fill", d => "#ededed")
.attr("fill-opacity", d => "1.0")
.attr('stroke-width', '0.25')
.attr("stroke", "black")
.attr("stroke-opacity", d => "0.0");
return svg.node();
}
Insert cell
aa = [-122.490402, 370.786453];
Insert cell
bb = [-122.389809, 37.72728];
Insert cell
md`## Data Construction`
Insert cell
ACTIVEYEAR = 2020;
Insert cell
viewable_year_cal_all_day_data = allDays(ACTIVEYEAR);
Insert cell
viewable_year_map_data = year_map_data.find(d => d[0] == ACTIVEYEAR)[1];
Insert cell
year_cal_data = d3.groups(cal_data, d => d.Day.getUTCFullYear()).reverse();
Insert cell
year_map_data = d3.groups(map_data, d => d.Year).reverse()
Insert cell
cal_data = {
const data = [];
raw_data.forEach((c, i) => {
const start = toUTC(c.Starts);
const end = toUTC(c.Ends);
const tmp = d3.utcDays(start,end);
tmp.push(end);
tmp.forEach((d, j) => {
//datemap[d] = datemap[d] ? datemap[d] + 1 : 1;
const item = {
ConferenceTitle: c.ConferenceTitle,
ConfID: i,
Day: d,
StartDay: (j == 0) ? true : false,
EndDay: (j == tmp.length - 1) ? true : false,
Length: tmp.length,
SharedAmount: 0,
DayOrder: 0
};
data.push(item);
});
//data.push(tmp);
});
return data;
}
Insert cell
map_data = {
return raw_data.map(d => {
return {ConferenceTitle: d.ConferenceTitle, Year: toUTC(d.Starts).getUTCFullYear(), latlng: latlng(d.lat,d.lng)};
});
}
Insert cell
raw_data = {
let row = [];
const spreadsheet = await d3.tsv(raw_data_url).then(data => data.forEach(d=>row.push(d)));
return row.filter(d => d.Starts != "");
}
Insert cell
raw_data_url = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQiP4DJVxXWyeU6Bm3bEWtS2TdaAQ7Dly1IEr8V-zL6zHOQE2rfg6BrwgHS6YzT3yUVw1wW48Ckzeiy/pub?gid=0&single=true&output=tsv"
Insert cell
md`## Map Setup`
Insert cell
function projLand(a) {
return `${d3.geoPath(proj)(land)}`;
}
Insert cell
proj = d3.geoMercator()
.center([0, 0])
.fitWidth(width,land)
.translate([width/2,325])
Insert cell
land = FileAttachment("countries-50m.json").json()
.then(topology => topojson.feature(topology, topology.objects.countries))
Insert cell
md`## Helper Functions`
Insert cell
function allDays(year) {
return d3.utcDays(Date.UTC(year,0,1,0,0,0),Date.UTC(year+1,0,1,0,0,0));
}
Insert cell
function allMonths(year) {
return d3.utcMonths(Date.UTC(year,0,0,0,0,0),Date.UTC(year+1,0,0,0,0,0));
}
Insert cell
function latlng(lat,lng) {
if (lat == '#N/A' || lng == '#N/A') {
lat = '';
lng = '';
}
//return [lat,lng];
return [lng,lat];
}
Insert cell
timeWeek = d3.utcSunday
Insert cell
formatDate = d3.utcFormat("%x")
Insert cell
formatDay = i => "SMTWTFS"[i]
Insert cell
formatMonth = d3.utcFormat("%b")
Insert cell
function toUTC(date) {
const pieces = date.split("/");
const month = monthName2Num(parseInt(pieces[1].replace(/^0+/, '')));
const utcDate = new Date(Date.UTC(pieces[2],pieces[1],pieces[0],0,0,0));
return utcDate;
}
Insert cell
monthName2Num = i => ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sept","Oct","Nov","Dec"].indexOf(i);
Insert cell
md`## Variables`
Insert cell
cellWidth = 17
Insert cell
cellHeight = 1*cellWidth
Insert cell
height = cellHeight * 9
Insert cell
md`## Imports and Requires`
Insert cell
topojson = require("topojson-client@3")
Insert cell
d3 = require("d3@6","d3-geo@2", "d3-tile@1")
Insert cell
import {legend} from "@d3/color-legend"
Insert cell
import {Button, Checkbox, Toggle, Radio, Range, Select, Text, Textarea, Search, Table} from "@observablehq/inputs"
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