user3837019
user3837019

Reputation: 221

D3 creating X-axis

Hi I'm using the following code

var data = [4, 8, 15, 16, 23, 42];

var x = d3.scale.linear()
    .domain([0, d3.max(data)])
    .range([0, 420]);

d3.select(".chart")
  .selectAll("div")
    .data(data)
  .enter().append("div")
    .style("width", function(d) { return x(d) + "px"; })
    .text(function(d) { return d; });

From http://codepen.io/mbostock/pen/Jaemg and I'm trying to add x-axis with a logarithmic format.

What I'm trying to achieve is the below image but I keep hitting dead ends. Any clue or idea on how to achieve this. enter image description here Many thanks for your help.

Upvotes: 1

Views: 129

Answers (1)

Mark
Mark

Reputation: 108512

My first comment would be to shift to a proper svg based drawing instead of using div to create your bars. When starting a new plot, I tend to start my work off this classic example. You, though are going to want to use a log scale on your x-axis:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .bar {
    fill: steelblue;
  }
  
  .bar:hover {
    fill: brown;
  }
  
  .axis {
    font: 10px sans-serif;
  }
  
  .axis path,
  .axis line {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
  }
  
  .x.axis path {
    display: none;
  }
</style>

<body>
  <script src="//d3js.org/d3.v3.min.js"></script>
  <script>
    var data = [4, 8, 15, 16, 23, 42];
   
    var margin = {
        top: 20,
        right: 20,
        bottom: 30,
        left: 40
      },
      width = 500 - margin.left - margin.right,
      height = 200 - margin.top - margin.bottom;

    var x = d3.scale.log()
      .domain([0.01, 100])
      .range([0, width]);

    var y = d3.scale.ordinal()
      .rangeRoundBands([0, height], .1)
      .domain(d3.range(data.length))

    var xAxis = d3.svg.axis()
      .scale(x)
      .orient("top")
      .ticks(0, "1g")
      .tickFormat(function(d){
        if (d === 0.01) return "0"
        else if (d === 1 || d === 10 || d === 100) return d;
        else return "";
      });

    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 + ")");

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0,0)")
      .call(xAxis);

    svg.selectAll(".bar")
      .data(data)
      .enter().append("rect")
      .attr("class", "bar")
      .attr("x", 0)
      .attr("width", function(d){
        return x(d);
      })
      .attr("y", function(d, i) {
        return y(i);
      })
      .attr("height", function(d,i) {
        return y.rangeBand();
      });
      
  </script>

Upvotes: 2

Related Questions