0

I'm trying to get a bar chart running based on this example.

 <body>
    </body>
    <script>
        var width = 960, height = 500;
        var margin = {top: 20, right: 20, bottom: 30, left: 40};

        //data
        var data = [ {"x":"A","y":0.15}, {"x":"B","y":0.10}, {"x":"C","y":0.35} ];

        //x and y Scales
        var xScale = d3.scale.ordinal()
            .rangeRoundBands([0, width], .1);

        var yScale = d3.scale.linear()
            .range([height, 0]);

        //x and y Axes
        var xAxis = d3.svg.axis()
            .scale(xScale)
            .orient("bottom");

        var yAxis = d3.svg.axis()
            .scale(yScale)
            .orient("left")
            .ticks(10, "%");

        //create svg container
        var svg = d3.select("body")
            .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 + ")");        

        //create bars
        d3.selectAll(".bar")
            .data(data)
            .enter()
            .append("rect")
            .attr("class", "bar")
            .attr("x", function(d) { return xScale(d.letter); })
            .attr("width", xScale.rangeBand())
            .attr("y", function(d) { return yScale(d.frequency); })
            .attr("height", function(d) { return height - yScale(d.frequency); });

        //drawing the x axis on svg
        svg.append("g")
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(xAxis);

        //drawing the y axis on svg
        svg.append("g")
            .attr("class", "y axis")
            .call(yAxis)
            .append("text")
            .attr("transform", "rotate(-90)")
            .attr("y", 6)
            .attr("dy", ".71em")
            .style("text-anchor", "end")
            .text("Frequency");
    </script>

All I see is the Y axis and nothing else. What am I missing?

1 Answer 1

2

There are three problems with your code. First, you need to set the domains of your scales. In the example, the code to do that is

x.domain(data.map(function(d) { return d.letter; }));
y.domain([0, d3.max(data, function(d) { return d.frequency; })]);

which you need to adapt to your variable names and data:

xScale.domain(data.map(function(d) { return d.x; }));
yScale.domain([0, d3.max(data, function(d) { return d.y; })]);

Second, you need to use svg when selecting the .bar elements so that the new bars are appended to the SVG:

svg.selectAll(".bar")
   .data(data)
   .enter()
   // etc

Finally, you forgot to change the data elements when copying and pasting. Your code still refers to .letter and .frequency when it should be .x and .y:

.attr("x", function(d) { return xScale(d.x); })
.attr("width", xScale.rangeBand())
.attr("y", function(d) { return yScale(d.y); })
.attr("height", function(d) { return height - yScale(d.y); });

Complete demo here.

Sign up to request clarification or add additional context in comments.

4 Comments

thanks. I forked your demo here where I tried to add a transition. But it doesn't seem to work.
Rectangles have no cx or cy attributes. You need to update the attributes you're setting initially (and also the axes): jsfiddle.net/7Pm6f/2
thanks. I thought transition() needs to come between data() and enter() so that the transition effect happens but your code works to my surprise. :)
The enter selection merges into the update selection once you've added the elements -- this is what I'm using there.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.