Public
Edited
Jun 8, 2023
Insert cell
Insert cell
Insert cell
{
const data =
`0,Abigail Snyder,PNNL - Pacific Northwest National Laboratory,Strategic Ensemble Design,Pacific Northwest National Laboratory,-119.28446,46.28569,-4.0
1,Abigail Swann,University of Washington,Strategic Ensemble Design,University of Washington,-122.33207,47.60621,-4.0
2,Ag Stephens,STFC - Science and Technology Facilities Council,Data Access,Science and Technology Facilities Council,-1.78116,51.55797,1.0
3,Aiko Voigt,University of Vienna,Data Access,University of Vienna,16.37208,48.20849,2.0
4,Alex Crawford,University of Manitoba,Model Documentation,University of Manitoba,-97.138343,49.806892,-3.0
5,Alison Pamment,"""NCAS - National Centre for Atmospheric Science
""",CEDA - Centre for Environment & Data Analysis ,RAL - Rutherford Appleton Laboratory",Data Request,National Centre for Atmospheric Science,-1.5614247,53.8044912,1.0`
.split("\n")
.map((row) => row.split(","));

// Extract the team member categories
const teamMembers = Array.from(new Set(data.map((row) => row[3])));

// Create the team member filter dropdown
const teamMemberSelect = document.getElementById("teamMemberSelect");
teamMembers.forEach((member) => {
const option = document.createElement("option");
option.value = member;
option.text = member;
teamMemberSelect.appendChild(option);
});

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

// Parse the time format
const parseTime = d3.timeParse("%H:%M");

// Filter function for team member categories
function filterByTeamMember() {
const selectedMember = teamMemberSelect.value;
let filteredData = data;
if (selectedMember !== "all") {
filteredData = data.filter((row) => row[3] === selectedMember);
}

updateGanttChart(filteredData);
}

// Update the Gantt chart based on the filtered data
function updateGanttChart(filteredData) {
// Clear the existing chart
d3.select("#ganttChart").selectAll("*").remove();

// Set up the x and y scales
const x = d3
.scaleUtc()
.domain([new Date(Date.UTC(0, 0, 0, 0)), new Date(Date.UTC(0, 0, 0, 23))])
.range([0, width]);

const y = d3
.scaleBand()
.domain(filteredData.map((row, 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 bars
svg
.selectAll(".bar")
.data(filteredData)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", (d) => x(parseTime("09:00")))
.attr("y", (d, i) => y(i))
.attr("width", (d) => x(parseTime("17:00")) - x(parseTime("09:00")))
.attr("height", y.bandwidth());

// Add text labels to the bars
svg
.selectAll(".bar-text")
.data(filteredData)
.enter()
.append("text")
.attr("class", "bar-text")
.attr("x", (d) => (x(parseTime("09:00")) + x(parseTime("17:00"))) / 2)
.attr("y", (d, i) => y(i) + y.bandwidth() / 2)
.attr("dy", "0.35em")
.text((d) => d[1]);

// Set up the x-axis
const xAxis = d3
.axisBottom(x)
.tickFormat(d3.timeFormat("%H:%M"))
.tickSizeOuter(0);

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

// Set up the y-axis
const yAxis = d3.axisLeft(y).tickSizeOuter(0);

svg.append("g").attr("class", "axis").call(yAxis);
}

// Add event listener for team member filter change
teamMemberSelect.addEventListener("change", filterByTeamMember);

// Initial Gantt chart rendering
updateGanttChart(data);
}
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