Public
Edited
May 10, 2023
Insert cell
# HOW IMPORTANT IS YOUR SLEEPZZZZ?
Insert cell
SLEEP DATA@2.csv
Type Table, then Shift-Enter. Ctrl-space for more options.

Insert cell
SLEEP = FileAttachment("SLEEP DATA@2.csv").csv()
Insert cell
Inputs.table(SLEEP)
Insert cell
tallSLEEPdata = {
const tallSLEEPdata = [];
SLEEP.forEach(d => {
for (let i=1; i<=7; i++) {
tallSLEEPdata.push({"Days": d["Days"], STATS: i, value: d[i]});
}
})
return tallSLEEPdata;
}
Insert cell
Inputs.table(tallSLEEPdata)
Insert cell
SLEEPmap1 = Plot.plot({
width: 400,
//x: {axis: null},
marks: [
Plot.cell(tallSLEEPdata, {
x: "STATS",
y: "Days",
fill: "value"
})
]
})
Insert cell
SLEEPmap1
Insert cell
Insert cell
<svg width="800" height="1000">
<g id="SLEEPmap"></g>
<text x="500" y="20" style="font-size: 14px; font-weight: bold;">Float over and click on cells.</text>
<text x="500" y="130" style="font-size: 14px; font-weight: bold;">STATS - PRANJAL SLEEP :P</text>
<text x="500" y="160" style="font-size: 14px; font-weight: bold;">(1)Mental Recovery - Score.</text>
<text x="500" y="190" style="font-size: 14px; font-weight: bold;">(2)Physical Recovery - Score.</text>
<text x="500" y="220" style="font-size: 14px; font-weight: bold;">(3)Movement Awakening - Mins.</text>
<text x="500" y="250" style="font-size: 14px; font-weight: bold;">(4)Sleep Cycles - Count.</text>
<text x="500" y="280" style="font-size: 14px; font-weight: bold;">(5)Efficiency - Score.</text>
<text x="500" y="310" style="font-size: 14px; font-weight: bold;">(6)Sleep Points - Score.</text>
<text x="500" y="340" style="font-size: 14px; font-weight: bold;">(7)Sleep Duration - Mins.</text>
<text id="explain" x="500" y="100" style="font-size: 20px; font-weight: bold;"></text>
</svg>

<div id="controls">
<button id="show">Show All</button>
</div>

<style>
#controls {position: absolute; top:40px; left: 495px;}
button {background-color: #fefefe; border: 1px solid #eee; border-radius: 3px; cursor: pointer;}
</style>
Insert cell
SMElem = d3.select(svgContainer).select("#SLEEPmap")
Insert cell
SLEEPmap2 = dvSLEEPmap(SMElem,tallSLEEPdata,"STATS","Days","value",options)
Insert cell
options = ({
boxSize: 14,
paddingX: 1,
colorScale: colorScale, // next cell below
startPos: {x:100,y:20}, // shifts it to accomodate the side and top labels
rotateColumnTextDeg: -90 // negative directions go counter-clockwise. Azimuth not Cartesian.
})
Insert cell
colorScale = d3.scaleLinear().domain([0,50,100,400]).range(["red","orange","yellow","green"])
Insert cell
explain = (evt,d) => {
let thisElem = evt.currentTarget;
let elemD3 = d3.select(thisElem);
d3.select("#explain").text(d["Days"] + " Day" + " : (STAT " + d.STATS + ") = " + d.value) ;
}
Insert cell
highlightYear = (evt,d) => {
let thisElem = evt.currentTarget;
let selectedSTATS = d.STATS;
dimAll();
SLEEPmap2.filter(d => d.STATS == selectedSTATS).style("opacity","");
}
Insert cell
dimAll = () => {
SLEEPmap2.style("opacity",0.1)
}
Insert cell
showAll = () => {
SLEEPmap2.style("opacity","")
}
Insert cell
SLEEPmap2.on("mouseover", explain)
Insert cell
SLEEPmap2.on("click", highlightYear)
Insert cell
{
// register event listeners
const btns = d3.select(svgContainer).select("#controls");
btns.select("#show").on("click", showAll);
}
Insert cell
highlight = {
SLEEPmap2.filter(d => toNum(d.value) < Range.low || toNum(d.value) > Range.high).style("stroke","");
SLEEPmap2.filter(d => toNum(d.value) >= Range.low && toNum(d.value) <= Range.high).style("stroke","steelblue");
}
Insert cell
toNum = (text) => {
if (typeof(text) === "string") {return Number(text.replace(/,/g,''))}
else {return text}
}
Insert cell
dvSLEEPmap = (elem,data,xField,yField,valueField,options) => {
// options
if (typeof(options) === "undefined") {options = {}}
if (typeof(options.boxSize) === "undefined") {options.boxSize = 5}
if (typeof(options.boxSizeX) === "undefined") {options.boxSizeX = options.boxSize}
if (typeof(options.boxSizeY) === "undefined") {options.boxSizeY = options.boxSize}
if (typeof(options.startPos) === "undefined") {options.startPos = {x:0,y:0}}
if (typeof(options.padding) === "undefined") {options.padding = 1}
if (typeof(options.paddingX) === "undefined") {options.paddingX = options.padding}
if (typeof(options.paddingY) === "undefined") {options.paddingY = options.padding}
if (typeof(options.colorScale) === "undefined") {options.colorScale = d3.scaleLinear().domain(d3.extent(data,d=>toNum(d[valueField]))).range(["white","black"])}
if (typeof(options.rotateColumnTextDeg) === "undefined") {options.rotateColumnTextDeg = -90}
// build a list of the x and y entries, each entry shows up only once.
let listOfYField = [];
data.forEach(d => {if (!listOfYField.includes(d[yField])) {listOfYField.push(d[yField]);}});

let listOfXField = [];
data.forEach(d => {if (!listOfXField.includes(d[xField])) {listOfXField.push(d[xField]);}});
let hm = elem.selectAll(".heatBox")
.data(data)
.join("rect")
.classed("heatBox",true)
.attr("title", d => d["Country Name"] + ": " + d.year)
.attr("width", options.boxSizeX)
.attr("height", options.boxSizeY)
.attr("x", d => options.startPos.x + listOfXField.indexOf(d[xField]) * (options.boxSizeX + options.paddingX))
.attr("y", d => options.startPos.y + listOfYField.indexOf(d[yField]) * (options.boxSizeY + options.paddingY))
.attr("fill", d => options.colorScale(toNum(d[valueField])))

let hm_labelY = elem.selectAll(".heatBoxLabelY")
.data(listOfYField)
.join("text")
.style("text-anchor","end")
.style("font-size", options.boxSizeY)
.classed("heatBoxLabelY", true)
.text(d => d)
.attr("x", options.startPos.x - 5)
.attr("y", (d,i) => options.startPos.y + i * (options.boxSizeY + options.paddingY) + options.boxSizeY)

let hm_labelX = elem.selectAll(".heatBoxLabelX")
.data(listOfXField)
.join("text")
.style("font-size", options.boxSizeX)
.classed("heatBoxLabelX", true)
.text(d => d)
.attr("x", (d,i) => options.startPos.x + i * (options.boxSizeX + options.paddingX) + options.boxSizeX)
.attr("y", options.startPos.y - 5)
.attr("transform", (d,i,nodes) => {return "rotate(" + options.rotateColumnTextDeg + " " + nodes[i].getAttribute("x") + "," + nodes[i].getAttribute("y") + ")"});
return hm;
}
Insert cell
uglySketchAndPrototypePranjalKale = FileAttachment("Ugly Sketch and prototype - Pranjal-Kale.pdf")
Insert cell
kalePranjalStaticVersonOfSleepMap = FileAttachment("KALE PRANJAL STATIC VERSON OF SLEEP MAP.jpg").image()
Insert cell
kale_pranjal_finalProject_visualizingComplexity1 = FileAttachment("Kale_Pranjal_Final Project_Visualizing Complexity@1.pdf")
Insert cell
kale_pranjal_finalProject_visualizingComplexity_pa = FileAttachment("Kale_Pranjal_Final Project_Visualizing Complexity_Page_01.jpg").image()
Insert cell
uglySketchAndPrototypePranjalKale_page_1 = FileAttachment("Ugly Sketch and prototype - Pranjal-Kale_Page_1.jpg").image()
Insert cell
kale_pranjal_finalProject_visualizingComplexity3 = FileAttachment("Kale_Pranjal_Final Project_Visualizing Complexity@3.pdf")
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