> For the complete documentation index, see [llms.txt](https://maksimdan.gitbook.io/javascript/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://maksimdan.gitbook.io/javascript/d3js/bar_chart.md).

# Bar Chart

## Appending SVG Tags Programmatically

```javascript
var svg = d3.select("body").append("svg")
    .attr("id", "chart")
    .attr("width", 800)
    .attr("height", 450)
```

* Methodology:
  * html body selector -> appending DOM type -> defining attributes

## Bar Chart, Basic Layout

```javascript
var data = [132,71,337,93,78,43,20,16,30,8,17,21];

var svg = d3.select("body").append("svg")
    .attr("id", "chart")
    .attr("width", 800)
    .attr("height", 450)

svg.selectAll(".bar") // attribute class
    .data(data) // data source
    .enter() // bind data 
        .append("rect") // append a rectangle for each element in data
        .attr("class", "bar") // future attributes
        .attr("x", 0) // x position
        .attr("y", function(d, i) {
            return 20 * i;
        }) // y position stacked reletive to i
        .attr("width", function(d, i) {
            return d;
        }) // scale width of bar occording to data
        .attr("height", 19)
```

![](http://i.imgur.com/NX42UWL.png)

## Bar Chart: Scaling

* One way to do this mathematically:

```javascript
var data = [132,71,337,93,78,43,20,16,30,8,17,21];

var width = 800;
var height = 450;

var svg = d3.select("body").append("svg")
    .attr("id", "chart")
    .attr("width", width)
    .attr("height", height)

svg.selectAll(".bar") // attribute class
    .data(data) // data source
    .enter() // bind data 
        .append("rect") // append a rectangle for each element in data
        .attr("class", "bar") // future attributes
        .attr("x", 0) // x position
        .attr("y", function(d, i) {
            return i * (width / data.length);
        }) // y position stacked reletive to i
        .attr("width", function(d, i) {
            return d;
        }) // scale width of bar occording to data
        .attr("height", function(d, i) {
            return (width / data.length)  -1; 
        }) // scale height reletive to the height available (450)
```

* But d3 make it easy for us!

```javascript
var data = [132,71,337,93,78,43,20,16,30,8,17,21];

var width = 800;
var height = 450;

// scale everything reletive to the maximum value, as well as the space available to us
var x = d3.scale.linear()
    .domain([0, d3.max(data)])
    .range([0, width])

// since height is static, we compare to the amount of data, and we scale to the space available
var y = d3.scale.linear()
    .domain([0, data.length])
    .range([0, height])


var svg = d3.select("body").append("svg")
    .attr("id", "chart")
    .attr("width", width)
    .attr("height", height)

svg.selectAll(".bar") // attribute class
    .data(data) // data source
    .enter() // bind data 
        .append("rect") // append a rectangle for each element in data
        .attr("class", "bar") // future attributes
        .attr("x", 0) // x position
        .attr("y", function(d, i) {
            return y(i)
        }) // y position stacked reletive to i
        .attr("width", function(d, i) {
            return x(d);
        }) // scale width of bar occording to data
        .attr("height", function(d, i) {
            return y(1) - 1;
        }) // scale height reletive to the height available (450)
```

![](http://i.imgur.com/GpJ5pmV.png)

## Bar Chart: CSS Styling

```css
.bar {
    fill: lightgreen;
    shape-rendering: crispEdges; /*  remove aliasing */
}
```

![](http://i.imgur.com/qfo2fab.png)

* Adding additional classes

```markup
// replace with
.classed("bar", true)
.classed("foo", true)
```

## Bar Chart: Adding Text

```javascript
svg.selectAll("bar-label") // new class creattion
    .data(data)
    .enter()
        .append("text") // text element to class
        .classed("bar-label", true)
        .attr("x", function(d, i) {
            return x(d);
        })// scale to end of bars
        .attr("y", function(d, i) {
            return y(i);
        }) // y position of text should scale just like the bars
        .attr("dy", function(d, i){
            return y(1) / 1.5;
        }) // elegent way of adding some padding to the y position 1.5 is a smart number that insures it centers within the bar
        .attr("dx", -4) // nudge text width to bar 4 pixels
        .text(function(d, i) {
            return d;
        });
```

```css
.bar-label {
    fill: white;
    font: 18px;
    text-anchor: end; /* sets text to left end of bar */
}
```

![](http://i.imgur.com/5yoLLcL.png)

## Bar Chart: Adding Flexibility with Chart Function

* The goal of this next section is to try and make a convenient way to plot our data, and make our code a little bit more reusable.
* To do so, we encapsulate it within a function that accept an object containing a data key value pair.

```javascript
function barPlot(params){
    this.selectAll(".bar") // attribute class
    .data(params.data) // data source
    .enter() // bind data 
        .append("rect") // append a rectangle for each element in data
        .classed("bar", true)
        .classed("foo", true)
        .attr("x", 0) // x position
        .attr("y", function(d, i) {
            return y(i)
        }) // y position stacked reletive to i
        .attr("width", function(d, i) {
            return x(d);
        }) // scale width of bar occording to data
        .attr("height", function(d, i) {
            return y(1) - 1;
        }) // scale height reletive to the height available (450)


    this.selectAll("bar-label") // new class creattion
    .data(params.data)
    .enter()
        .append("text") // text element to class
        .classed("bar-label", true)
        .attr("x", function(d, i) {
            return x(d);
        })// scale to end of bars
        .attr("y", function(d, i) {
            return y(i);
        }) // y position of text should scale just like the bars
        .attr("dy", function(d, i){
            return y(1) / 1.5;
        }) // elegent way of adding some padding to the y position 1.5 is a smart number that insures it centers within the bar
        .attr("dx", -4) // nudge text width to bar 4 pixels
        .text(function(d, i) {
            return d;
        });
}

// .call passes the this keyword to documents DOM svg, as opposed to the global window.
barPlot.call(svg, {
    data: data

});
```

## Bar Chart: Grouping Elements

* To organize things a bit more, we can group all of our elements together
* Here is our final product
* I've also cleaned up somethings

```markup
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Learning D3</title>
    <link rel="stylesheet" href="main.css">
    <script  type="text/javascript" src="d3.min.js"></script>
</head>
<body>
<!--Place all DOM elements here -->
<div id="svgWrap">

</div>
<script>
//Write your code here

var data = [132,71,337,93,78,43,20,16,30,8,17,21];

var width = 800;
var height = 450;

// scale everything reletive to the maximum value, as well as the space available to us
var x = d3.scale.linear()
    .domain([0, d3.max(data)])
    .range([0, width])

// since height is static, we compare to the amount of data, and we scale to the space available
var y = d3.scale.linear()
    .domain([0, data.length])
    .range([0, height])


var svg = d3.select("#svgWrap").append("svg")
    .attr("id", "chart")
    .attr("width", width)
    .attr("height", height)

// grouping svg elements
var char = svg.append("g")
    .classed("display", true)

function barPlot(params){
    this.selectAll(".bar") // attribute class
    .data(params.data) // data source
    .enter() // bind data 
        .append("rect") // append a rectangle for each element in data
        .classed("bar", true)
        .classed("foo", true)
        .attr("x", 0) // x position
        .attr("y", function(d, i) {
            return y(i)
        }) // y position stacked reletive to i
        .attr("width", function(d, i) {
            return x(d);
        }) // scale width of bar occording to data
        .attr("height", function(d, i) {
            return y(1) - 1;
        }) // scale height reletive to the height available (450)


    this.selectAll("bar-label") // new class creattion
    .data(params.data)
    .enter()
        .append("text") // text element to class
        .classed("bar-label", true)
        .attr("x", function(d, i) {
            return x(d);
        })// scale to end of bars
        .attr("y", function(d, i) {
            return y(i);
        }) // y position of text should scale just like the bars
        .attr("dy", function(d, i){
            return y(1) / 1.5;
        }) // elegent way of adding some padding to the y position 1.5 is a smart number that insures it centers within the bar
        .attr("dx", -4) // nudge text width to bar 4 pixels
        .text(function(d, i) {
            return d;
        });
}

barPlot.call(svg, {
    data: data

});


</script>    
</body>
</html>
```

```css
body,html{
    margin: 0;
    padding: 0;
    font-family: "Arial", sans-serif;
    font-size: 0.95em;
    text-align: center;
}
#svgWrap{
    background-color: #F5F2EB;
    width: 850px;
    height: 500px;
    margin: auto;
}

.bar {
    fill: lightgreen;
    shape-rendering: crispEdges; /*  remove aliasing */
}

.bar-label {
    fill: white;
    font: 18px;
    text-anchor: end; /* sets text to left end of bar */
}

#chart {
    margin: 15px;
}
```

![](http://i.imgur.com/wwcmPS0.png)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://maksimdan.gitbook.io/javascript/d3js/bar_chart.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
