Public
Edited
Jun 8, 2023
Insert cell
Insert cell
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
/* Define the styles for the Gantt chart */
.bar {
fill: steelblue;
}

.bar-row {
fill-opacity: 0.5;
stroke: none;
rx: 5;
ry: 5;
}

.bar-text {
fill: #fff;
font-size: 12px;
text-anchor: middle;
}

.axis {
font-size: 10px;
}

.row {
display: flex;
align-items: center;
margin-bottom: 10px;
}

.name {
margin-right: 10px;
}

.institution {
flex-grow: 1;
}
</style>
</head>
<body>
<svg id="ganttChart"></svg>

<script src="https://d3js.org/d3.v7.min.js"></script>
<script>
// JavaScript code here...
</script>
</body>
</html>
Insert cell
{
// Read the data
const data = [
{
name: "Abigail Snyder",
institution: "PNNL - Pacific Northwest National Laboratory",
startTime: -4.0,
teams: ["Strategic Ensemble Design"]
},
{
name: "Abigail Swann",
institution: "University of Washington",
startTime: -4.0,
teams: ["Strategic Ensemble Design"]
},
{
name: "Ag Stephens",
institution: "STFC - Science and Technology Facilities Council",
startTime: 1.0,
teams: ["Data Access"]
},
{
name: "Aiko Voigt",
institution: "University of Vienna",
startTime: 2.0,
teams: ["Data Access"]
},
{
name: "Alex Crawford",
institution: "University of Manitoba",
startTime: -3.0,
teams: ["Model Documentation", "Data Request"]
},
{
name: "Alison Pamment",
institution: "NCAS - National Centre for Atmospheric Science",
startTime: 1.0,
teams: ["Data Request"]
}
];

// Define the team member categories and their corresponding colors
const categories = [
"Strategic Ensemble Design",
"Data Access",
"Model Documentation",
"Data Request"
];
const categoryColors = ["#FF7F0E", "#1F77B4", "#FFBB78", "#2CA02C"];

// Initialize the Gantt chart dimensions and margins
const margin = { top: 20, right: 30, bottom: 50, left: 50 };
const width = 600 - margin.left - margin.right;
const height = 200 - margin.top - margin.bottom;

// Calculate the time range
const minStartTime = d3.min(data, (d) => d.startTime);
const maxStartTime = d3.max(data, (d) => d.startTime);
const timeRange = Math.abs(maxStartTime - minStartTime);

// Set up the x scale for the Gantt chart
const x = d3
.scaleLinear()
.domain([-24, 24])
.range([0, width]);

// Set up the y scale for the Gantt chart
const y = d3
.scaleBand()
.domain(data.map((d, i) => i))
.range([0, height])
.padding(0.1);

// Set up the SVG container for the chart
const svg = d3
.select("#ganttChart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

// Draw the Gantt chart bars
const bars = svg
.selectAll(".bar-row")
.data(data)
.enter()
.append("g")
.attr("class", "bar-row")
.attr("transform", (d, i) => `translate(0,${y(i)})`);

bars
.append("rect")
.attr("class", "bar")
.attr("x", (d) => x(9 + d.startTime))
.attr("y", 0)
.attr("width", (d) => x(17 + d.startTime) - x(9 + d.startTime))
.attr("height", y.bandwidth())
.attr("fill", "#2CA02C")
.attr("rx", 5)
.attr("ry", 5);

// Add text labels to the bars
bars
.append("text")
.attr("class", "bar-text")
.attr("x", (d) => x((17 + 9 + 2 * d.startTime) / 2))
.attr("y", y.bandwidth() / 2)
.attr("dy", "0.35em")
.attr("text-anchor", "middle")
.text((d) => d.name);

// Set up the x-axis
const xAxis = d3
.axisBottom(x)
.tickValues(d3.range(-24, 25, 6))
.tickFormat((d) => `${d}h`)
.tickSizeOuter(0);

svg
.append("g")
.attr("class", "axis")
.attr("transform", `translate(0,${height})`)
.call(xAxis);

// Add rows with names and institutions
const rows = svg
.selectAll(".row")
.data(data)
.enter()
.append("g")
.attr("class", "row")
.attr("transform", (d, i) => `translate(0,${y(i) + y.bandwidth() / 2})`);

rows
.append("text")
.attr("class", "name")
.attr("x", -10)
.attr("text-anchor", "end")
.text((d) => d.name);

rows
.append("text")
.attr("class", "institution")
.attr("x", width + 10)
.attr("text-anchor", "start")
.text((d) => d.institution);
}
Insert cell

One platform to build and deploy the best data apps

Experiment and prototype by building visualizations in live JavaScript notebooks. Collaborate with your team and decide which concepts to build out.
Use Observable Framework to build data apps locally. Use data loaders to build in any language or library, including Python, SQL, and R.
Seamlessly deploy to Observable. Test before you ship, use automatic deploy-on-commit, and ensure your projects are always up-to-date.
Learn more