Vincent lui
Vincent lui

Reputation: 33

text labels are wrong in grouped bar chart d3js

I am newbie in d3js, I do not know why all labels in the bar are wrong.

My code and captures are shown as below, then you can see that all labels are different from my data.

Anyone know what's going on in my text label section?

// set the dimensions and margins of the graph

var margin = { top: 10, right: 30, bottom: 40, left: 50 },
    width = 700 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;

const dataUrl = "https://raw.githubusercontent.com/yushinglui/IV/main/time_distance_status_v2.csv"

//fetch the data
d3.csv(dataUrl)
    .then((data) => {

        // append the svg object to the body of the page
        var svg = d3.select("#graph-2")
            .append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
            .append("g")
            .attr("transform",
                "translate(" + margin.left + "," + margin.top + ")")



        // List of subgroups = header of the csv files = soil condition here
        var subgroups = data.columns.slice(1)

        // List of groups = species here = value of the first column called group -> I show them on the X axis
        var groups = d3.map(data, function (d) { return (d.startTime) })

        // Add X axis
        var x = d3.scaleBand()
            .domain(groups)
            .range([0, width])
            .padding([0.2])
        svg.append("g")
            .attr("transform", "translate(0," + height + ")")
            .call(d3.axisBottom(x).tickSize(0));

        // Add Y axis
        var y = d3.scaleLinear()
            .domain([0, 20])
            .range([height, 0]);
        svg.append("g")
            .call(d3.axisLeft(y));

        // Another scale for subgroup position?
        var xSubgroup = d3.scaleBand()
            .domain(subgroups)
            .range([0, x.bandwidth()])
            .padding([0.05])

        // color palette = one color per subgroup
        var color = d3.scaleOrdinal()
            .domain(subgroups)
            .range(['#98abc5', '#8a89a6'])



        // Show the bars
        svg.append("g")
            .selectAll("g")

            // Enter in data = loop group per group
            .data(data)
            .enter()
            .append("g")
            .attr("transform", function (d) { return "translate(" + x(d.startTime) + ",0)"; })

            .selectAll("rect")
            .data(function (d) { return subgroups.map(function (key) { return { key: key, value: d[key] }; }); })
            .enter()
            .append("rect")
            .attr("x", function (d) { return xSubgroup(d.key); })
            .attr("y", function (d) { return y(d.value); })
            .attr("width", xSubgroup.bandwidth())
            .attr("height", function (d) { return height - y(d.value); })
            .attr("fill", function (d) { return color(d.key); })

            // mouseover and mouseout animation
            .on("mouseover", function (d) {
                d3.select(this).style("fill", d3.rgb(color(d.key)).darker(2))
            })
            .on("mouseout", function (d) {
                d3.select(this).style("fill", function (d) { return color(d.key); })
            })





        //axis labels
        svg.append('text')
            .attr('x', - (height / 2))
            .attr('y', width - 650)
            .attr('transform', 'rotate(-90)')
            .attr('text-anchor', 'middle')
            .style("font-size", "17px")
            .text('Average Distance');

        svg.append('text')
            .attr('x', 300)
            .attr('y', width - 240)
            .attr('transform', 'rotate()')
            .attr('text-anchor', 'middle')
            .style("font-size", "17px")
            .text('Start Time');

        // legend
        svg.append("circle").attr("cx", 200).attr("cy", 20).attr("r", 6).style("fill", "#98abc5")
        svg.append("circle").attr("cx", 300).attr("cy", 20).attr("r", 6).style("fill", "#8a89a6")
        svg.append("text").attr("x", 220).attr("y", 20).text("Present").style("font-size", "15px").attr("alignment-baseline", "middle")
        svg.append("text").attr("x", 320).attr("y", 20).text("Absent").style("font-size", "15px").attr("alignment-baseline", "middle")


        //text labels on bars -- all labels wrong!!

        svg.append("g")
            .selectAll("g")

            // Enter in data = loop group per group
            .data(data)
            .enter()
            .append("g")
            .attr("transform", function (d) { return "translate(" + x(d.startTime) + ",0)"; })

            .selectAll("text")
            .data(function (d) { return subgroups.map(function (key) { return { key: key, value: d[key] }; }); })
            .enter()
            .append("text")
            .text(function (d) { return y(d.value); })

            .attr("font-family", "sans-serif")
            .attr("font-size", "12px")
            .attr("fill", "black")
            .attr("text-anchor", "middle")

            .attr("x", function (d) { return xSubgroup(d.key); })
            .attr("y", function (d) { return y(d.value) + 10; })

    });

enter image description here

enter image description here

My reference website:

http://plnkr.co/edit/9lAiAXwet1bCOYL58lWN?p=preview&preview

https://bl.ocks.org/bricedev/0d95074b6d83a77dc3ad

Upvotes: 0

Views: 71

Answers (1)

readyplayer77
readyplayer77

Reputation: 2159

Your issue is that when you're appending the text, you inadvertently called the y function, which is used to get the y-location on where to insert the text. The numbers you're getting are actually y-location values, which seems completely random.

.text(function (d) { return y(d.value); }) // here is the issue

Change it to

.text(function (d) { return d.value; })

and it should work!

Upvotes: 2

Related Questions