Public
Edited
Feb 24
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
chart = {
const margin = {top: 30, right: 10, bottom: 10, left: 0},
width = 500 - margin.left - margin.right,
height = 100 - margin.top - margin.bottom;

// append the svg object to the body of the page
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
// add a background color to show the are of the svg
.style("background-color", "yellow");
const group = svg.append("g")
.attr("transform",
`translate(${margin.left},${margin.top})`)
// add a rect to show the area of the group element
group.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr('width', width)
.attr('height', height)
.style('fill', 'black')
return svg.node()
}
Insert cell
Insert cell
chart_updated = {
const margin = {top: 30, right: 30, bottom: 30, left: 30}, // Set all margins to 30
width = 500 - margin.left - margin.right,
height = 100 - margin.top - margin.bottom;

// Append the svg object
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.style("background-color", "yellow");

// Create a group element with translation
const group = svg.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

// Add a rectangle to visualize the group area
group.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height)
.style("fill", "black");

return svg.node();
}
Insert cell
Insert cell
shipTable = {
const columns = ['Name', 'Country', 'Ship Class', 'Builder', 'Laid Down'];

const table = d3.create("table")
.attr("border", "1")
.style("width", "100%")
.style("border-collapse", "collapse");

const thead = table.append("thead");
const tbody = table.append("tbody");

// Add table header
thead.append("tr")
.selectAll("th")
.data(columns)
.enter()
.append("th")
.text(d => d)
.style("padding", "8px")
.style("background", "#ddd")
.style("border", "1px solid black")
.style("text-align", "left");

// Add table rows
const rows = tbody.selectAll("tr")
.data(data_cleaned)
.enter()
.append("tr")
.style("background-color", d => d.Country === "Japan" ? "lightcoral" : d.Country === "USA" ? "lightblue" : "white");

// Add cells
rows.selectAll("td")
.data(d => columns.map(col => d[col]))
.enter()
.append("td")
.text(d => d)
.style("padding", "8px")
.style("border", "1px solid black");

return table.node();
}

Insert cell
Insert cell
histogramChart = {
// Set up margins and dimensions
const margin = { top: 30, right: 30, bottom: 50, left: 50 },
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;

// Create SVG container
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left}, ${margin.top})`);

// Define attributes available in dropdown
const attributes = ["Displacement", "Length", "Beam", "Draft", "Speed", "Crew"];
let selectedAttribute = "Displacement"; // Default attribute

// Create X and Y scales
const xScale = d3.scaleLinear().range([0, width]);
const yScale = d3.scaleLinear().range([height, 0]);

// Create axes
const xAxis = svg.append("g").attr("transform", `translate(0, ${height})`);
const yAxis = svg.append("g");

// Function to update histogram
function updateHistogram(attribute) {
selectedAttribute = attribute;

// Extract data values for the selected attribute
const values = data_cleaned.map(d => +d[attribute]).filter(d => !isNaN(d));

// Create bins using d3.bin()
const binGenerator = d3.bin()
.domain([d3.min(values), d3.max(values)])
.thresholds(10); // 10 bins

const bins = binGenerator(values);

// Update X scale
xScale.domain([bins[0].x0, bins[bins.length - 1].x1]);

// Update Y scale based on bin frequencies
yScale.domain([0, d3.max(bins, d => d.length)]);

// Bind data to rectangles
const bars = svg.selectAll("rect").data(bins);

// ENTER: Create bars
bars.enter()
.append("rect")
.merge(bars) // Update existing bars
.attr("x", d => xScale(d.x0))
.attr("width", d => xScale(d.x1) - xScale(d.x0) - 1)
.attr("y", d => yScale(d.length))
.attr("height", d => height - yScale(d.length))
.attr("fill", "steelblue");

// EXIT: Remove bars not needed
bars.exit().remove();

// Update axes
xAxis.call(d3.axisBottom(xScale).ticks(10));
yAxis.call(d3.axisLeft(yScale));
}

// Dropdown menu
const dropdown = d3.create("select")
.on("change", function() {
updateHistogram(this.value);
});

// Populate dropdown options
dropdown.selectAll("option")
.data(attributes)
.enter()
.append("option")
.text(d => d)
.attr("value", d => d);

// Initial plot with default attribute
updateHistogram(selectedAttribute);

// Return dropdown and SVG together
return html`<div>${dropdown.node()}</div><div>${svg.node()}</div>`;
}

Insert cell
Insert cell
scatterPlot = {
// Set margins and dimensions
const margin = { top: 30, right: 30, bottom: 50, left: 50 },
width = 600 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;

// Append SVG
const svg = d3.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

// Define color scale for ship types
const colorScale = d3.scaleOrdinal()
.domain(["Battleship", "Carrier", "Cruiser"])
.range(["red", "blue", "green"]);

// Extract Length (x) and Beam (y)
const x = d3.scaleLinear()
.domain([d3.min(data_cleaned, d => +d.Length), d3.max(data_cleaned, d => +d.Length)])
.range([0, width]);

const y = d3.scaleLinear()
.domain([d3.min(data_cleaned, d => +d.Beam), d3.max(data_cleaned, d => +d.Beam)])
.range([height, 0]);

// Add axes
svg.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));

svg.append("g")
.call(d3.axisLeft(y));

// Add scatter points
svg.selectAll("circle")
.data(data_cleaned)
.enter().append("circle")
.attr("cx", d => x(+d.Length))
.attr("cy", d => y(+d.Beam))
.attr("r", 5)
.attr("fill", d => colorScale(d.Type))
.attr("opacity", 0.8);

// Add labels
svg.append("text")
.attr("x", width / 2)
.attr("y", height + 40)
.attr("text-anchor", "middle")
.text("Ship Length");

svg.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -height / 2)
.attr("y", -40)
.attr("text-anchor", "middle")
.text("Ship Beam");

// Add legend
const legend = svg.append("g")
.attr("transform", `translate(${width - 100}, 20)`);

["Battleship", "Carrier", "Cruiser"].forEach((type, i) => {
legend.append("circle")
.attr("cx", 0)
.attr("cy", i * 20)
.attr("r", 5)
.attr("fill", colorScale(type));

legend.append("text")
.attr("x", 10)
.attr("y", i * 20 + 5)
.text(type)
.attr("alignment-baseline", "middle");
});

return svg.node();
}

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