Public
Edited
Mar 5, 2023
Insert cell
Insert cell
Insert cell
csvfile
Insert cell
import { SummaryTable } from "@observablehq/summary-table"
Insert cell
Insert cell
Inputs.table(data)
Insert cell
Inputs.table(search, {})
Insert cell
Insert cell
column_names = data.columns
Insert cell
column_names_2 = data.columns.concat("")
Insert cell
viewof select_x = Inputs.select(column_names, {
label: "Select X column"
})
Insert cell
Insert cell
viewof select_facet = Inputs.select(column_names, {
label: "Select Grouping Column",
value: "What is your gender?"
})
Insert cell
viewof toggle = Inputs.toggle({label: "Active", value: true})
Insert cell
viewof radios = Inputs.radio(["A", "B"], {label: "Select one", value: "A"})
Insert cell
Insert cell
viewof select_line_type = Inputs.select(["Straight line", "Curved line"], {
label: "Select one"
})
Insert cell
select_line_type_function = {
if (select_line_type == "Straight line") {
return Plot.lineY(data, {
x: select_x,
y: select_y,
stroke: "black",
strokeDasharray: "4,5",
strokeWidth: 2
});
} else {
return Plot.line(data, {
x: select_x,
y: select_y,
stroke: "black",
strokeWidth: 2,
curve: "catmull-rom",
marker: "circle"
});
}
}
Insert cell
addTooltips(
Plot.plot({
width,
height: 300,
facet: {
data: data,
y: select_facet,
marginRight: 40
//label: "Target"
},
marks: [
select_line_type_function,
Plot.dot(data, {
x: select_x,
y: select_y,
r: range,
fill: select_facet,
title: (d) =>
`Data: \n x-value: ${d[select_x]} \n y-value: ${d[select_y]} \n color parameter: ${d[select_facet]}`
})
],
marginLeft: 30,
marginBottom: 50,
insetBottom: 20,
insetLeft: 20,
grid: true,
color: {
legend: true
}
})
)
Insert cell
df_penguins = aq.from(data)
Insert cell
df_penguins.groupby("ID").count().view()
Insert cell
TESTING = "d." + select_x
Insert cell
test = `d.${[select_x]}`
Insert cell
Wrangler(df_penguins)
Insert cell
`${[select_x]}`
Insert cell
Plot.dot(df_penguins, {
x: "body_mass_g",
y: "bill_length_mm",
stroke: "species"
}).plot({y: {type:"linear"}, x:{type:"linear"}})
Insert cell
viewof summary_data = SummaryTable(data, { label: "Penguins Data" })
Insert cell
viewof analyze_input = Inputs.select(["mean", "median", "mode"], {
label: "Select one"
})
Insert cell
viewof analyze_column = Inputs.select(column_names, {
label: "Analyze column"
})
Insert cell
d3.mean(data, (d) => d.analyze_column)
Insert cell
mean(select_x)
Insert cell
function mean(values) {
return sum(values) / count(values);
}
Insert cell
function count(values) {
let count = 0;
for (let i = 0, n = values.length; i < n; ++i) {
const v = +values[i];
if (v === v) ++count;
}
return count;
}
Insert cell
function sum(values) {
let sum = 0;
for (let i = 0, n = values.length; i < n; ++i) {
const v = +values[i];
if (v) sum += v;
}
return sum;
}
Insert cell
addTooltips = (chart, styles) => {
const stroke_styles = { stroke: "blue", "stroke-width": 3 };
const fill_styles = { fill: "blue", opacity: 0.5 };

// Workaround if it's in a figure
const type = d3.select(chart).node().tagName;
let wrapper =
type === "FIGURE" ? d3.select(chart).select("svg") : d3.select(chart);

// Workaround if there's a legend....
const svgs = d3.select(chart).selectAll("svg");
if (svgs.size() > 1) wrapper = d3.select([...svgs].pop());
wrapper.style("overflow", "visible"); // to avoid clipping at the edges

// Set pointer events to visibleStroke if the fill is none (e.g., if its a line)
wrapper.selectAll("path").each(function (data, index, nodes) {
// For line charts, set the pointer events to be visible stroke
if (
d3.select(this).attr("fill") === null ||
d3.select(this).attr("fill") === "none"
) {
d3.select(this).style("pointer-events", "visibleStroke");
if (styles === undefined) styles = stroke_styles;
}
});

if (styles === undefined) styles = fill_styles;

const tip = wrapper
.selectAll(".hover")
.data([1])
.join("g")
.attr("class", "hover")
.style("pointer-events", "none")
.style("text-anchor", "middle");

// Add a unique id to the chart for styling
const id = id_generator();

// Add the event listeners
d3.select(chart).classed(id, true); // using a class selector so that it doesn't overwrite the ID
wrapper.selectAll("title").each(function () {
// Get the text out of the title, set it as an attribute on the parent, and remove it
const title = d3.select(this); // title element that we want to remove
const parent = d3.select(this.parentNode); // visual mark on the screen
const t = title.text();
if (t) {
parent.attr("__title", t).classed("has-title", true);
title.remove();
}
// Mouse events
parent
.on("pointerenter pointermove", function (event) {
const text = d3.select(this).attr("__title");
const pointer = d3.pointer(event, wrapper.node());
if (text) tip.call(hover, pointer, text.split("\n"));
else tip.selectAll("*").remove();

// Raise it
d3.select(this).raise();
// Keep within the parent horizontally
const tipSize = tip.node().getBBox();
if (pointer[0] + tipSize.x < 0)
tip.attr(
"transform",
`translate(${tipSize.width / 2}, ${pointer[1] + 7})`
);
else if (pointer[0] + tipSize.width / 2 > wrapper.attr("width"))
tip.attr(
"transform",
`translate(${wrapper.attr("width") - tipSize.width / 2}, ${
pointer[1] + 7
})`
);
})
.on("pointerout", function (event) {
tip.selectAll("*").remove();
// Lower it!
d3.select(this).lower();
});
});

// Remove the tip if you tap on the wrapper (for mobile)
wrapper.on("touchstart", () => tip.selectAll("*").remove());

// Define the styles
chart.appendChild(html`<style>
.${id} .has-title { cursor: pointer; pointer-events: all; }
.${id} .has-title:hover { ${Object.entries(styles)
.map(([key, value]) => `${key}: ${value};`)
.join(" ")} }`);

return chart;
}
Insert cell
// Function to position the tooltip
hover = (tip, pos, text) => {
const side_padding = 10;
const vertical_padding = 5;
const vertical_offset = 15;

// Empty it out
tip.selectAll("*").remove();

// Append the text
tip
.style("text-anchor", "middle")
.style("pointer-events", "none")
.attr("transform", `translate(${pos[0]}, ${pos[1] + 7})`)
.selectAll("text")
.data(text)
.join("text")
.style("dominant-baseline", "ideographic")
.text((d) => d)
.attr("y", (d, i) => (i - (text.length - 1)) * 15 - vertical_offset)
.style("font-weight", (d, i) => (i === 0 ? "bold" : "normal"));

const bbox = tip.node().getBBox();

// Add a rectangle (as background)
tip
.append("rect")
.attr("y", bbox.y - vertical_padding)
.attr("x", bbox.x - side_padding)
.attr("width", bbox.width + side_padding * 2)
.attr("height", bbox.height + vertical_padding * 2)
.style("fill", "white")
.style("stroke", "#d3d3d3")
.lower();
}
Insert cell
// To generate a unique ID for each chart so that they styles only apply to that chart
id_generator = () => {
var S4 = function () {
return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
};
return "a" + S4() + S4();
}
Insert cell
tooltipPlugin = (Plot) => {
const { plot } = Plot;
Plot.plot = ({ tooltip, ...options }) => addTooltips(plot(options), tooltip);
return Plot;
}
Insert cell
viewof select_group = Inputs.select(column_names, {
label: "Select group by column"
})
Insert cell
viewof select_group_2 = Inputs.select(column_names, {
label: "Select average by column"
})
Insert cell
import { aq, op } from "@uwdata/arquero"
Insert cell
viewof FiO2 = Inputs.range([0.21, 1], {
label: "FiO2",
step: 0.01,
value: 0.21
})
Insert cell
viewof Pb = Inputs.range([650, 1100], {
label: "Pb",
step: 1,
value: 760
})
Insert cell
viewof PaCO2 = Inputs.range([20, 120], {
label: "PaCO2",
step: 1,
value: 40
})
Insert cell
viewof RQ = Inputs.range([0.7, 1.1], {
label: "RQ",
step: 0.1,
value: 0.8
})
Insert cell
viewof RQ_food = Inputs.radio(["Fats (0.7)", "Proteins (0.8)", "Carbs (1)"], {
label: "Select RQ",
value: "Carbs"
})
Insert cell
RQ_selected = {
if (RQ_food == "Fats (0.7)") {
return "0.7";
} else if (RQ_food == "Proteins (0.8)") {
return "0.8";
} else {
return "1";
}
}
Insert cell
PAO2 = (FiO2 * (Pb - 48) - PaCO2 / RQ_selected).toLocaleString(undefined, {
maximumFractionDigits: 0
})
Insert cell
viewof color = Inputs.color({label: "Favorite color", value: "#4682b4"})
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