Published
Edited
Oct 5, 2022
Importers
Insert cell
Insert cell
svg= {

const svg= d3.create("svg").attr("viewBox", [0, 0, width, height]);

const grouping= svg.append("g")
.attr("transform", `translate( ${margin.left}, ${margin.top})`);

grouping.append("g")
.call(d3.axisBottom(x).tickFormat(dateFmt))
.attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
.call((axis) =>
axis
.append("text")
.text(x_attr)
.style("fill", "black")
.attr("transform", `translate( ${x.range()[1]}, +30)`)
.style("text-anchor", "end")
.style("font-size", 20)
)
.call((axis) => axis.selectAll("line").remove())
.call((axis) => axis.selectAll("path").remove());

grouping.append("g")
.call(d3.axisLeft(y))
.call((axis) =>
axis
.append("text")
.text(y_attr)
.style("fill", "black")
.style("text-anchor", "middle")
.attr("y", -15)
.style("font-size", 20)
)
.call((axis) => axis.selectAll("line").remove())
.call((axis) => axis.selectAll("path").remove());


// circle
// grouping.append("circle")
// .join("circle")
// .attr("cx", 12)
// .attr("cy", 10)
// .attr("r", 5)
// .attr("fill", "blue");

// HEATMAP
// join all 'RECT' => searches by class 'cell'
// ATTRS: x=> by day, starts at DAY '0'
// y=> by hours

// BANDWIDTH of the Scaleband using as width and height
grouping.selectAll(".cell")
.data(grouped)
.join("rect")
.attr("class", "cell")
.attr("x", d=> x(d.day))
.attr("y", d=> y(d.hour))
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.attr("fill", d=> color(d.value))

// LEGEND
// const legend= svg.append("g")
// .attr("transform", `translate(${margin.left}, 0`);
// legend
// .selectAll("rect")
// .data(selected)
// .enter()
// .append("rect")
// .attr("x", (d, i) => legendElementWidth * i)
// .attr("y", height - (2*legendHeight))
// .attr("width", legendElementWidth)
// .attr("height", legendHeight)
// .style("fill", d => x(d));
// legend
// .selectAll("text")
// .data(legendBins)
// .enter()
// .append("text")
// .text(d => "≥ " + (100*d).toFixed(1))
// .attr("x", (d, i) => legendElementWidth * i)
// .attr("y", height - (legendHeight / 2))
// .style("font-size", "9pt")
// .style("font-family", "Consolas, courier")
// .style("fill", "#aaa");

return svg.node();
}

Insert cell
Insert cell
bins= selected.map(d => d.created_at.getDay())
Insert cell
legendHeight= 20
Insert cell
legendElementWidth= 44
Insert cell
Insert cell
grouped
Insert cell
// valRange = [0, d3.max(grouped, d => d3.max(d.day)) ]
valRange = (d3.extent(grouped, d=> d.hour) )
Insert cell
legendBins = [...Array(9).keys()].map(x => d3.quantile(valRange, x * 0.1))
Insert cell
Insert cell
dateFmt= d=> "SMTWHFS"[d]
Insert cell
viewof selected = navio(tweets, {
height: 300,
addAllAttribsIncludeObjects: true
})
Insert cell
Insert cell
Insert cell
Insert cell
grouped= d3.rollups(
selected,
v=> d3.mean(v, d=> d.retweet_count),
d => d.created_at.getDay(),
d => d.created_at.getHours() + 5
).map( ([day, v]) => v.map(([hour, value]) => ({ day, hour, value})))
.flat()
Insert cell
selected.map(d => d.created_at.getDay())
Insert cell
x.bandwidth()
Insert cell
Insert cell
color= d3.scaleSequential( d3.interpolateReds)
.domain( d3.extent( grouped, d => d.value))
Insert cell
Insert cell
x= d3.scaleBand()
.domain(d3.range(7))
.range([0, iwidth])
Insert cell
// start from top
y= d3.scaleBand()
.domain(d3.range(24))
.range([0, iheight])
Insert cell
Insert cell
y_attr= "Hours"
Insert cell
x_attr= "Day of the Week"
Insert cell
Insert cell
Insert cell
viewof file = fileInput({ initialValue: FileAttachment("tweet@1.js").blob() })
Insert cell
// jsonFile = await Files.text(e)
Insert cell
tweets={
let tweets= [];

const text= await Files.text(file);
try{
tweets= JSON.parse(text.slice(25)).map(t => t.tweet);
} catch{
tweets= JSON.parse(text);
}

return tweets.map(t => {
t.retweet_count =+ t.retweet_count;
t.favorite_count =+ t.favorite_count;
t.created_at = new Date(t.created_at);
t.hour= t.created_at.getHours();

return t;
});
}
Insert cell
Insert cell
margin= ({ left: 50, top: 40, right: 30, bottom: 50})
Insert cell
iwidth= width- margin.left - margin.right
Insert cell
iheight= height - margin.top - margin.bottom
Insert cell
Insert cell
height= 400
Insert cell
d3= require("d3@6")
Insert cell
import {navio} from "@john-guerra/navio"
Insert cell
import { fileInput } from "@mbostock/file-input-with-initial-value"
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