Public
Edited
Dec 13, 2024
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
function drawSchedule(nbTracks, data) {
let lineHeight = 20;
let trackColWidth = 15;
let colWidth = (width - trackColWidth) / (sessionDuration * 7);
let fontSize = 12;

let progressInData = 0;

let svg = d3
.create("svg")
.attr("width", width)
.attr("height", lineHeight * (6 + nbTracks) * sessionNumber)
.style("background-color", "white");

for (let session = 0; session < sessionNumber; session++) {
let gSession = svg
.append("g")
.attr("x", 0)
.attr("y", 0)
.attr(
"transform",
`translate(0, ${lineHeight * (6 + nbTracks) * session})`
);

// session header
gSession
.append("g")
.call((g) =>
g
.append("rect")
.attr("x", trackColWidth)
.attr("y", 0)
.attr("width", width - trackColWidth)
.attr("height", lineHeight)
.attr("fill", "white")
.attr("stroke", "black")
.attr("stroke-width", 1)
)
.call((g) =>
g
.append("text")
.attr("x", (width - trackColWidth) / 2)
.attr("y", (lineHeight / 4) * 3)
.attr("font-size", fontSize)
.attr("font-family", "Calibri")
.text(
`Période de ${sessionDuration} semaines n°${session + 1} - ${
sessionDuration * 7
} jours`
)
);

for (let week = 0; week < sessionDuration; week++) {
let weekColor = week % 2 === 0 ? evenWeekColor : oddWeekColor;
let gWeek = gSession
.append("g")
.attr("x", 0)
.attr("y", 0)
.attr(
"transform",
`translate(${week * 7 * colWidth + trackColWidth}, ${lineHeight})`
);

// week header
gWeek
.append("g")
.attr("transform", `translate(0, ${lineHeight})`)
.call((g) =>
g
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", colWidth * 7)
.attr("height", lineHeight)
.attr("fill", "white")
.attr("stroke", "black")
.attr("stroke-width", 1)
)
.call((g) =>
g
.append("text")
.attr("x", 0)
.attr("y", (lineHeight / 4) * 3)
.attr("font-size", fontSize)
.attr("font-family", "Calibri")
.text(`Semaine ${session * sessionDuration + week + 1}`)
);

for (
let localProgressInData = 0;
localProgressInData < 7;
localProgressInData++
) {
let dayData = data[progressInData + localProgressInData];
let gDay = gWeek
.append("g")
.attr("x", 0)
.attr("y", 0)
.attr("transform", `translate(${localProgressInData * colWidth}, 0)`);

// day number
gDay
.append("g")
.call((g) =>
g
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", colWidth)
.attr("height", lineHeight)
.attr("fill", "white")
.attr("stroke", "black")
.attr("stroke-width", 1)
)
.call((g) =>
g
.append("text")
.attr("x", 0)
.attr("y", (lineHeight / 4) * 3)
.attr("font-size", fontSize - 1)
.attr("font-family", "Calibri")
.text(`${progressInData + localProgressInData + 1}`)
);

// day text
gDay
.append("g")
.call((g) =>
g
.append("rect")
.attr("x", 0)
.attr("y", lineHeight * 2)
.attr("width", colWidth)
.attr("height", lineHeight)
.attr("fill", weekColor)
.attr("stroke", "black")
.attr("stroke-width", 1)
)
.call((g) =>
g
.append("text")
.attr("x", 0)
.attr("y", lineHeight * 2 + (lineHeight / 4) * 3)
.attr("font-size", fontSize)
.attr("font-family", "Calibri")
.text(formatDayText(dayData.date.getDay()))
);

// day date
gDay
.append("g")
.call((g) =>
g
.append("rect")
.attr("x", 0)
.attr("y", lineHeight * 3)
.attr("width", colWidth)
.attr("height", lineHeight)
.attr("fill", weekColor)
.attr("stroke", "black")
.attr("stroke-width", 1)
)
.call((g) =>
g
.append("text")
.attr("x", 0)
.attr("y", lineHeight * 3 + (lineHeight / 4) * 3)
.attr("font-size", fontSize - 2)
.attr("font-family", "Calibri")
.text(`${dayData.date.getDate()}/${dayData.date.getMonth() + 1}`)
);

// day task
gDay
.append("g")
.call((g) =>
g
.append("rect")
.attr("x", 0)
.attr("y", lineHeight * 4)
.attr("width", colWidth)
.attr("height", lineHeight)
.attr("fill", dayData.isWeekend ? weekColor : "white")
.attr("stroke", "black")
.attr("stroke-width", 1)
)
.call((g) =>
g
.append("text")
.attr("x", 0)
.attr("y", lineHeight * 4 + (lineHeight / 4) * 3)
.attr("font-size", fontSize)
.attr("font-family", "Calibri")
.text(`${dayData.isWeekend ? "W" : ""}`)
);

// day track cells
for (let track = 0; track < nbTracks; track++) {
gDay.append("g").call((g) =>
g
.append("rect")
.attr("x", 0)
.attr("y", lineHeight * (5 + track))
.attr("width", colWidth)
.attr("height", lineHeight)
.attr("fill", dayData.isWeekend ? weekColor : "white")
.attr("stroke", "black")
.attr("stroke-width", 1)
);
// .call((g) =>
// g
// .append("text")
// .attr("x", 0)
// .attr("y", lineHeight * (5 + track) + (lineHeight / 4) * 3)
// .attr("font-size", fontSize)
// .attr("font-family", "Calibri")
// .text(``)
// );
}
}

progressInData += 7;
}

for (let track = 0; track < nbTracks; track++) {
let gTrack = gSession
.append("g")
.attr("x", 0)
.attr("y", 0)
.attr("transform", `translate(0, ${lineHeight * (track + 6)})`);

gTrack
.append("g")
.call((g) =>
g
.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", trackColWidth)
.attr("height", lineHeight)
.attr("fill", "white")
.attr("stroke", "black")
.attr("stroke-width", 1)
)
.call((g) =>
g
.append("text")
.attr("x", 0)
.attr("y", (lineHeight / 4) * 3)
.attr("font-size", fontSize)
.attr("font-family", "Calibri")
.text(`P${track + 1}`)
);
}
}

return svg.node();
}
Insert cell
function formatDayText(day) {
switch (day) {
case 0:
return "Di";
case 1:
return "Lu";
case 2:
return "Ma";
case 3:
return "Me";
case 4:
return "Je";
case 5:
return "Ve";
case 6:
return "Sa";
default:
return "";
}
}
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