2025-05-24 19:35:29 +01:00

203 lines
4.9 KiB
JavaScript

function drawBar(id) {
const svg = d3.select(`${id}`);
const backgroundwidth = +svg.attr("width");
const backgroundradius = 10;
const width = 600; //+svg.attr("width");
const height = 200; //+svg.attr("height");
const margin = { top: 40, right: 30, bottom: 60, left: 30 };
// Draw the white background
// Draw the rounded rectangle
svg.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", backgroundwidth)
.attr("height", height)
.attr("rx", backgroundradius)
.attr("ry", backgroundradius)
.attr("fill", "white");
// .attr("stroke", "white")
// .attr("stroke-width", 2);
const data = {
"-3": 0,
"-2": 1,
"-1": 3,
"0": 0,
"1": 2,
"2": 0,
"3": 10
};
const dataArray = Object.entries(data).map(([key, count]) => ({
key: +key,
count: count
}));
const x = d3.scaleBand()
.domain([-3,-2,-1,0,1,2,3])
.range([margin.left, width - margin.right])
.padding(0);
const y = d3.scaleLinear()
.domain([0, d3.max(dataArray, d => d.count)])
.nice()
.range([height - margin.bottom, margin.top]);
// X Axis
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x)
.tickSize(0))
.selectAll("text")
.attr("x", 0)
.attr("y", 10)
.style("text-anchor", "middle")
.style("font-size", "12px");
// Add the required ticks
const xTicks = d3.scaleLinear()
.domain([-3.5, 3.5])
.range([margin.left, width - margin.right]);
svg.append("g")
.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(xTicks).tickValues(d3.range(-3.5, 4, 1)))
.selectAll("text")
.style("visibility", "hidden"); // This hides the labels
// Y Axis
//svg.append("g")
// .attr("transform", `translate(${margin.left},0)`)
// .call(d3.axisLeft(y).ticks(5));
// Bars
svg.selectAll(".bar")
.data(dataArray)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", d => x(d.key))
.attr("y", d => y(d.count))
.attr("width", x.bandwidth())
.attr("height", d => y(0) - y(d.count))
.attr("fill", "#003c4b"); // From brand guidelines
// Labels
svg.selectAll(".label")
.data(dataArray)
.enter()
.append("text")
.attr("x", d => x(d.key) + x.bandwidth() / 2)
.attr("y", d => d.count > 0 ? y(d.count) - 5 : y(0))
.attr("text-anchor", "middle")
.attr("font-size", "12px")
.attr("font-style", "italic")
.attr("fill", "black")
.text(d => d.count > 0 ? d.count : "");
// Average line
const format = d3.format(".2f");
const totalCount = d3.sum(dataArray, d => d.count);
const weightedSum = d3.sum(dataArray, d => d.key * d.count);
const average = totalCount > 0 ? format(weightedSum / totalCount) : 0;
const xLinear = d3.scaleLinear()
.domain([-3, 3])
.range([margin.left + x.bandwidth() / 2, width - margin.right - x.bandwidth() / 2]);
// const avgX = xLinear(average);
const avgX = xLinear(2.7); // Temporary for testing
svg.append("line")
.attr("x1", avgX)
.attr("x2", avgX)
.attr("y1", y(0)+20)
.attr("y2", y(d3.max(dataArray, d => d.count)) - 20)
.attr("stroke", "#e40074") // From brand guidelines
.attr("stroke-width", 4)
.attr("stroke-dasharray", "6,2");
/*
svg.append("text")
.attr("x", avgX)
.attr("y", y(d3.max(dataArray, d => d.count)) - 30)
.attr("text-anchor", "middle")
.attr("fill", "#e40074")
.attr("font-size", "12px")
.text("Average ("+average+")");
*/
// Title beneath the graph
svg.append("text")
.attr("x", width / 2)
.attr("y", height - 10) // Just below the x-axis
.attr("text-anchor", "middle")
.attr("font-size", "14px")
.attr("fill", "black")
.text("Demo bar graph");
// Add infor to right of bar chart
// Oblong settings
const boxx = 620;
const boxy = 60;
const boxwidth = 150;
const boxheight = 80;
const cornerRadius = 10;
// Draw the rounded rectangle
svg.append("rect")
.attr("x", boxx)
.attr("y", boxy)
.attr("width", boxwidth)
.attr("height", boxheight)
.attr("rx", cornerRadius)
.attr("ry", cornerRadius)
.attr("fill", "white")
.attr("stroke", "#333")
.attr("stroke-width", 2);
// Draw the horizontal divider
svg.append("line")
.attr("x1", boxx)
.attr("x2", boxx + boxwidth)
.attr("y1", boxy + boxheight / 2)
.attr("y2", boxy + boxheight / 2)
.attr("stroke", "#333")
.attr("stroke-width", 1);
// Add text to the top half
svg.append("text")
.attr("x", boxx + boxwidth / 2)
.attr("y", boxy + boxheight / 4)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle")
.attr("font-size", "20px")
.attr("font-weight", "900") // 400 is normal, 700 is bold, 900 is extra-bold
.attr("font-family", "sans-serif")
.text("Average : 1.69");
// Add text to the bottom half
svg.append("text")
.attr("x", boxx + boxwidth / 2)
.attr("y", boxy + 3 * boxheight / 4)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "middle")
.attr("font-size", "20px")
.attr("font-weight", "900") // 400 is normal, 700 is bold, 900 is extra-bold
.attr("font-family", "sans-serif")
.text("Score Gap : 6");
}