2013-06-21 4 views
8

Ich baue ein Balkendiagramm in d3.js mit einer Ordinalachse, deren Ticks das Diagramm mit Text beschriften sollen. Könnte jemand erklären, wie die Ordinalskala x Ticks zu den entsprechenden Balkenpositionen "mappt"? Insbesondere, wenn ich die x-Tick-Beschriftungen mit einem Array von Textwerten für die entsprechenden Balken in einem Balkendiagramm festlegen möchte.Erstellen einer textbeschrifteten x-Achse mit einer Ordinalskala in D3.js

Derzeit habe die Einrichtung ich die Domain wie die folgenden:

var labels = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t"]; 
    var xScale = d3.scale.ordinal() 
       .domain(labels) 

jedoch Werte von 1-19 nach den Beschriftungen zeigen.

Wie in dieser Geige gesehen:

http://jsfiddle.net/chartguy/FbqjD/

Assoziierte Fiddle Source Code:

//Width and height 
      var margin = {top: 20, right: 20, bottom: 30, left: 40};   
      var width = 600 - margin.left - margin.right; 
      var height= 500-margin.top -margin.bottom; 
      var w = width; 
      var h = height; 


      var dataset = [ 5, 10, 13, 19, 21, 25, 22, 18, 15, 13, 
          11, 12, 15, 20, 18, 17, 16, 18, 23, 25 ]; 

      var labels = ["a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t"]; 
      var xScale = d3.scale.ordinal() 
      .domain(labels) 
          .rangeRoundBands([margin.left, width], 0.05); 
      var xAxis = d3.svg.axis().scale(xScale).orient("bottom"); 


      var yScale = d3.scale.linear() 
          .domain([0, d3.max(dataset)]) 
          .range([h,0]); 


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

      //Create bars 
      svg.selectAll("rect") 
       .data(dataset) 
       .enter() 
       .append("rect") 
       .attr("x", function(d, i) { 
        return xScale(i); 
       }) 
       .attr("y", function(d) { 
        return yScale(d); 
       }) 
       .attr("width", xScale.rangeBand()) 
       .attr("height", function(d) { 
        return h - yScale(d); 
       }) 
       .attr("fill", function(d) { 
        return "rgb(0, 0, 0)"; 
       }); 

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

      //Create labels 
      svg.selectAll("text") 
       .data(dataset) 
       .enter() 
       .append("text") 
       .text(function(d) { 
        return d; 
       }) 
       .attr("x", function(d, i) { 
        return xScale(i) + xScale.rangeBand()/2; 
       }) 
       .attr("y", function(d) { 
        return h - yScale(d) + 14; 
       }); 

Antwort

15

Sie können die Zecke Werte eines Ordnungs Achse gesetzt explizit d3.svg.axis().tickValues(*array*) verwenden.

Aber das ist ein seltsamer Weg, da es Ihre Schlüssel und Werte gefährlich trennt, was bedeutet, dass Sie sorgfältig darauf achten müssen, die Waage manuell auszurichten und sicherzustellen, dass Ihre Daten korrekt übereinstimmen. Es hilft, die Schlüssel und Werte in einem einzelnen Objekt zu gruppieren und dann das folgende Format zu verwenden:

um Ihre Achsendomänen abzubilden.

Ich habe Ihre Daten überarbeitet und geige, es in dem zu tun, was ich als mehr d3 way. (Beachten Sie auch, dass ich einige andere Änderungen nur zum Spaß gemacht habe, nämlich die Ränder verbessert und die Achsausrichtung bereinigt usw.)

+0

Also, was bedeutet es, die Werte-Label-Paare in ein einzelnes Objekt in d3 zu integrieren, anstatt zu verknüpfen Es kennzeichnet ein Objekt und Werte für ein Objekt. Ich weiß deine Antwort zu schätzen, aber ich möchte etwas mehr tun und genau wissen, was hinter den Kulissen passiert, also programmiere ich nicht nur zufällig. – arete

+1

Das liegt daran, dass Sie die Domäne explizit mit einem Satz von Daten definieren und dann einen anderen Satz an sie übergeben, wenn Sie '.attr (" x ", Funktion (d, i) {return xScale (i);})'. Die [relevante Zeile] (https://github.com/mbstock/d3/wiki/Ordinal-Scales#wiki-ordinal_domain) aus der API-Referenz sagt: "Wenn die Domäne explizit festgelegt wird, werden Werte an die Waage übergeben, die nicht angegeben wurden explizit wird ein Teil der Domain hinzugefügt. " Zu diesem Zweck könnten Sie bemerken, dass in Ihrem ursprünglichen Code, der die x-Achse vor den Rezepten aufruft, nur Ihr explizites Array aufgerufen wird. – nsonnad