Published
Edited
Dec 8, 2019
1 star
Insert cell
Insert cell
Insert cell
chart = {
const svg = d3
.create("svg")
.attr("viewBox", [-14, 0, width + 28, height])
.style("margin", "0 -14px")
.style("background", "#000")
.style("color", "#fff")
.style("display", "block")
.attr("fill", "currentColor")
.attr("font-family", "sans-serif")
.attr("font-size", 10);

svg
.append("g")
.selectAll("circle")
.data(data)
.join("circle")
.attr("cx", d => x(d.color))
.attr("cy", d => y(d.absolute_magnitude))
.attr("fill", d => z(d.color))
.attr("r", 0.5);

svg
.append("g")
.attr("transform", `translate(${margin.left},0)`)
.call(
d3.axisLeft(
d3.scaleLog(y.domain().map(m => Math.pow(10, 4.83 - m)), y.range())
)
);

svg
.append("g")
.attr("transform", `translate(${width - margin.right},0)`)
.call(d3.axisRight(y).ticks(null, "+"));

svg
.append("g")
.attr("transform", `translate(0,${margin.top})`)
.call(d3.axisTop(d3.scaleLinear(x.domain().map(temperature), x.range())));

svg
.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).ticks(null, "+f"));

svg.selectAll(".domain").remove();

svg
.append("text")
.attr("dy", 12)
.attr("text-anchor", "middle")
.attr(
"transform",
`translate(${margin.left},${(margin.top + height - margin.bottom) /
2}) rotate(-90)`
)
.call(text =>
text
.append("tspan")
.attr("fill-opacity", 0.8)
.text("← darker\xa0")
)
.call(text =>
text
.append("tspan")
.attr("font-weight", "bold")
.text("\xa0Luminosity L☉\xa0")
)
.call(text =>
text
.append("tspan")
.attr("fill-opacity", 0.8)
.text("\xa0brighter →")
);

svg
.append("text")
.attr("dy", -6)
.attr("text-anchor", "middle")
.attr(
"transform",
`translate(${width - margin.right},${(margin.top +
height -
margin.bottom) /
2}) rotate(-90)`
)
.call(text =>
text
.append("tspan")
.attr("fill-opacity", 0.8)
.text("← darker\xa0")
)
.call(text =>
text
.append("tspan")
.attr("font-weight", "bold")
.text("\xa0Absolute magnitude M\xa0")
)
.call(text =>
text
.append("tspan")
.attr("fill-opacity", 0.8)
.text("\xa0brighter →")
);

svg
.append("text")
.attr("x", (margin.left + width - margin.right) / 2)
.attr("y", margin.top)
.attr("dy", 12)
.attr("text-anchor", "middle")
.call(text =>
text
.append("tspan")
.attr("fill-opacity", 0.8)
.text("← hotter\xa0")
)
.call(text =>
text
.append("tspan")
.attr("font-weight", "bold")
.text("\xa0Temperature K\xa0")
)
.call(text =>
text
.append("tspan")
.attr("fill-opacity", 0.8)
.text("\xa0colder →")
);

svg
.append("text")
.attr("x", (margin.left + width - margin.right) / 2)
.attr("y", height - margin.bottom)
.attr("dy", -6)
.attr("text-anchor", "middle")
.call(text =>
text
.append("tspan")
.attr("fill-opacity", 0.8)
.text("← blue\xa0")
)
.call(text =>
text
.append("tspan")
.attr("font-weight", "bold")
.text("\xa0Color B-V\xa0")
)
.call(text =>
text
.append("tspan")
.attr("fill-opacity", 0.8)
.text("\xa0red →")
);

return html`<div style="position: relative">${svg.node()}<div style="position: absolute; top: ${margin.top +
20}px; left: ${margin.left + 20}px; width: ${width -
margin.left -
margin.right -
40}px; height: ${height -
margin.top -
margin.bottom -
40}px;" class="cover"></div>`;
}
Insert cell
data = d3.csvParse(await FileAttachment("catalog.csv").text(), d3.autoType)
Insert cell
Insert cell
z = bv2rgb
Insert cell
function bv2rgb(bv) {
bv = Math.max(-0.4, Math.min(2, bv));
let t;
return `#${[
bv < 0 ? (t = (bv + 0.4) / 0.4, 0.61 + (0.11 * t) + (0.1 * t * t))
: bv < 0.4 ? (t = bv / 0.4, 0.83 + (0.17 * t))
: 1,
bv < 0 ? (t = (bv + 0.4) / 0.4, 0.70 + (0.07 * t) + (0.1 * t * t))
: bv < 0.4 ? (t = bv / 0.4, 0.87 + (0.11 * t))
: bv < 1.6 ? (t = (bv - 0.4) / 1.20, 0.98 - (0.16 * t))
: (t = (bv - 1.6) / 0.4, 0.82 - (0.5 * t * t)),
bv < 0.4 ? 1
: bv < 1.5 ? (t = (bv - 0.4) / 1.1, 1 - (0.47 * t) + (0.1 * t * t))
: bv < 1.94 ? (t = (bv - 1.5) / 0.44, 0.63 - (0.6 * t * t))
: 0
].map(t => Math.round(t * 255).toString(16).padStart(2, "0")).join("")}`;
}
Insert cell
function temperature(color) {
return 4600 * (1 / (0.92 * color + 1.7) + 1 / (0.92 * color + 0.62));
}
Insert cell
x = d3.scaleLinear([-0.39, 2.19], [margin.left, width - margin.right])
Insert cell
y = d3.scaleLinear([-7, 19], [margin.top, height - margin.bottom])
Insert cell
margin = ({top: 40, right: 40, bottom: 40, left: 40})
Insert cell
width = 954
Insert cell
height = Math.round(width * 1.2)
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