var margin = {top: 30, right: 30, bottom: 130, left: 90}, width = 1000 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; const tooltip_offset = {dx: margin.left+200, dy: margin.right+90} // TODO: set main scales attr here then domain later // const x = d3.scaleBand() // .range([0, width]) // .padding(0.2); // // const y = d3.scaleLinear() // .range([height, 0]); // var color = d3.scaleOrdinal() .range([ "#800000", "#FFFF00", "#808000", "#00FF00", "#008000", "#00FFFF", "#008080", "#0000FF", "#000080", "#FF00FF", "#800080", ]); function build_chart(div_selector, data_url) { const svg = d3.select(div_selector).append("svg") .attr("id", "svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); const tooltip = d3.select(div_selector) .append("div") .style("opacity", 0) .attr("class", "tooltip") var mousemove = function (e, d) { tooltip .style("left", (e.pageX - tooltip_offset.dx) + "px") .style("top", (e.pageY - tooltip_offset.dy) + "px") } var mouseleave = function (d) { tooltip .transition() .duration(100) .style("opacity", 0) } var mouseover = function (e, d) { var category_name = d3.select(this.parentNode).datum().key var category_charge = d.data[category_name] tooltip .transition() .duration(200) .style("opacity", 1); tooltip .html("Categorie: " + category_name + "
" + "Charge: " + category_charge + "%") .style("left", (e.pageX - tooltip_offset.dx) + "px") .style("top", (e.pageY - tooltip_offset.dy) + "px") } d3.csv(data_url).then(data => { var services = data.columns.slice(1) var periods = d3.map(data, d => d.period) var stack = d3.stack() .keys(services) // .order(d3.stackOrderNone) // .offset(d3.stackOffsetNone); var stacked_data = stack(data) const x = d3.scaleBand() .domain(periods) .range([0, width]) .padding(0.1); y_max = d3.max(stacked_data[stacked_data.length - 1], d => d[1]); if (y_max == 0) { y_max = 100 } const y = d3.scaleLinear() .range([height, 0]) .domain([0, y_max]); // Sur l'axe horizontal, on filtre les dates afficher const xAxis = d3.axisBottom(x) // .tickValues(x.domain().filter(d => (d.includes("06/0") || d.includes("21/0")))); const yAxis = d3.axisLeft(y) svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.9em") .attr("dy", ".15em") .attr("transform", "rotate(-65)"); svg.append("g") .attr("class", "y axis") .call(yAxis) // .append("text") // .attr("fill", "#000") // .attr("transform", "rotate(-90)") // .attr("y", 6) // .attr("dy", "0.91em") // .style("text-anchor", "end") // .text("rate"); svg.append("text") .attr("text-anchor", "end") .attr("transform", "rotate(-90)") .attr("y", -margin.left + 40) .attr("x", -margin.top - 70) .text("Charge (% ETP)") let groups = svg.selectAll("g.category") .data(stacked_data) .enter() .append("g") .style("fill", (d) => color(d.key)); let rect = groups.selectAll("rect") .data(d => d) .enter() .append("rect") .attr("class", "bar") .attr("x", d => x(d.data.period)) .attr("width", x.bandwidth()) // .attr("width", 5) .attr("y", d => y(d[1])) .attr("height", d => height - y(d[1] - d[0])) .on("mouseover", mouseover) .on("mousemove", mousemove) .on("mouseleave", mouseleave); }); }