<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Scaled Scatter plot with Axes</title>
    <script type="text/javascript" src="https://d3js.org/d3.v4.min.js"></script>
    <style type="text/css">
        .axis path,
        .axis line {
            stroke: teal;
            shape-rendering: crispEdges;
        }

        .axis text {
            font-family: Optima, Futura, sans-serif;
            font-weight: bold;
            font-size: 12px;
            fill: teal;
        }
    </style>
</head>
<body>
<script type="text/javascript">
    var h = 200;
    var w = 700;

    var padding = 30;
    //    var dataset = [
    //        [10, 20],
    //        [480, 90],
    //        [250, 50],
    //        [100, 33],
    //        [330, 95],
    //        [410, 12],
    //        [475, 44],
    //        [25, 67],
    //        [85, 21],
    //        [220, 88]
    //    ];

    var dataset = [];
    var numDataPoints = 50;
    var xRange = Math.random() * 1000;
    var yRange = Math.random() * 1000;
    for (var i = 0; i < numDataPoints; i++) {
        var newNumber1 = Math.floor(Math.random() * xRange);
        var newNumber2 = Math.floor(Math.random() * yRange);
        dataset.push([newNumber1, newNumber2]);
    }

    //    var dataset = [];                         //Initialize empty array
    //    for (var i = 0; i < 25; i++) {            //Loop 25 times
    //        var newNumber = Math.floor(Math.random() * 30);   //New random number (0-30)
    //        dataset.push(newNumber);              //Add new number to array
    //    }

    var svg = d3.select("body")
        .append("svg")
        .attr("height", h)
        .attr("width", w);

    var xScales = d3.scaleLinear()
        .domain([0, d3.max(dataset, function (d) {
            return d[0];
        })])
        .range([padding, w - padding * 2]);

    var yScales = d3.scaleLinear()
        .domain([0, d3.max(dataset, function (d) {
            return d[1];
        })])
        .range([h - padding, padding]);

    var rScale = d3.scaleLinear()
        .domain([0, d3.max(dataset, function (d) {
            return d[1];
        })])
        .range([2, 5]);


    var aScale = d3.scaleSqrt()      // <--New!
        .domain([0, d3.max(dataset, function (d) {
            return d[1];
        })])
        .range([0, 10]);  // <--New!

    var xAxis = d3.axisBottom()
        .scale(xScales)
        .ticks(8);
    // .tickValues([0, 100, 250, 600]);

    var yAxis = d3.axisLeft(yScales)
        .ticks(5);


    //Generate guide lines
    svg.selectAll("line")
        .data(dataset)
        .enter()
        .append("line")
        .attr("x1", function (d) {
            return xScales(d[0]);
        })
        .attr("x2", function (d) {
            return xScales(d[0]);
        })
        .attr("y1", h - padding)
        .attr("y2", function (d) {
            return yScales(d[1]);
        })
        .attr("stroke", "#ddd")
        .attr("stroke-width", 1);

    var circles = svg.selectAll("circle")
        .data(dataset).enter()
        .append("circle")
        .attr("r", function (d) {
            return aScale(d[1]);
        })
        .attr("cx", function (d) {
            return xScales(d[0]);
        })
        .attr("cy", function (d, i) {
            return yScales(d[1]);
        })
        .attr("fill", "yellow")
        .attr("stroke", "teal")
        .attr("stroke-width", function (d) {
            return d / 2.0;
        });

    //    var labels = svg.selectAll("text")
    //        .data(dataset).enter()
    //        .append("text")
    //        .text(function (d) {
    //            return d[0] + ", " + d[1];
    //        })
    //        .attr("x", function (d) {
    //            return xScales(d[0]);
    //        })
    //        .attr("y", function (d) {
    //            return yScales(d[1]);
    //        })
    //        .attr("font-family", "sans-serif")
    //        .attr("font-size", "11px")
    //        .attr("fill", "orange");

    svg.append("g")
        .attr("class", "axis")
        .attr("transform", "translate(0," + (h - padding) + ")")
        .call(xAxis);


    svg.append("g")
        .attr("class", "axis")
        .attr("transform", "translate(" + padding + ",0)")
        .call(yAxis);
</script>
</body>
</html>
# Introducing Axes

- Visual features unlike `scale` .
```javascript
d3.axisTop // Ticks on top
d3.axisBottom
d3.axisLeft
d3.axisRight // Ticks on right
```

- Take `scale` as a parameter 

```javascript

var xAxis = d3.axisBottom()
              .scale(xScale);

```

- Put inside a group, assign a class ( for CSS ), and position using transform's translate.

```javascript

svg.append("g")
    .attr("class", "axis")
    .attr("transform", "translate(0," + (h - padding) + ")")
    .call(xAxis);

```

D3’s `call()` function takes the incoming selection, as received from the prior link in the chain, and hands that selection off to any function. 

- Use CSS to style; note svg attributes differ from CSS ones

```css

.axis path,
.axis line {
    stroke: teal;
    shape-rendering: crispEdges;
}

.axis text {
    font-family: Optima, Futura, sans-serif;
    font-weight: bold;
    font-size: 14px;
    fill: teal;
}

```

- Check for ticks.
```javascript

var xAxis = d3.axisBottom()
                  .scale(xScale)
                  .ticks(5);


var xAxis = d3.axisBottom()
                  .scale(xScale)
                  .tickValues([0, 100, 250, 600]);

var formatAsPercentage = d3.format(".1%");

xAxis.tickFormat(formatAsPercentage);


```

