2013-06-21 3 views
8

d3.js에 차트가 텍스트로 레이블되어야하는 서수 x 축이있는 막 대형 차트를 작성합니다. 누구든지 서수 규모가 x 막대기를 해당 막대 위치에 "매핑"하는 방법을 설명 할 수 있습니까? 특히, 막대 차트의 해당 막대에 텍스트 값의 배열이있는 x 눈금 레이블을 지정하려면. D3.js에 서수 스케일이있는 텍스트 레이블이있는 x 축 생성

현재 나는 다음과 같은 도메인을 설정 해요 :

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) 

그러나, 1-19의 값은 텍스트 레이블 후에 보이고있다. 이 바이올린에서 보는 바와 같이

:

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

관련 바이올린 소스 코드 :

//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; 
       }); 

답변

15

명시 적으로 d3.svg.axis().tickValues(*array*)를 사용하여 서수 축 눈금 값을 설정할 수 있습니다.

하지만 위험한 키와 값을 구분하기 때문에 이렇게하는 것은 이상한 방법입니다. 즉, 수동으로 비늘을 정렬하고 데이터가 올바르게 일치하는지 확인해야합니다. 단일 객체에 키와 값을 그룹화 한 다음 형식을 사용하면 축 도메인을 매핑하는 데 도움이됩니다.

 axis.domain(array.map(function (d) { return d.value; })) 

축 도메인을 매핑하는 데 도움이됩니다.

d3 way으로 볼 때 데이터와 피들을 다시 작성했습니다. (또한 재미만을 위해서, 즉 여백을 개선하고 축 정렬을 수정 한 다른 점을 참고하십시오.)

+0

그렇다면 값 레이블 쌍을 링크 대신 d3의 단일 객체에 통합하는 것은 무엇입니까? 그것은 객체에 레이블을 붙이고 객체에 값을 매 깁니다. 귀하의 답변에 고마워하지만, 나는 여분의 공간으로 가서 무대 뒤에서 일어나는 일을 정확히 알고 싶어서 우연히 만나는 프로그래밍이 아닙니다. – arete

+1

당신이'.attr ("x", function (d, i) {return xScale (i);})'을 할 때 당신이 한 세트의 데이터로 명시 적으로 도메인을 정의하고 또 다른 세트를 전달하기 때문입니다. API 참조에서 [관련 줄] (https://github.com/mbostock/d3/wiki/Ordinal-Scales#wiki-ordinal_domain)은 다음과 같이 말합니다. "도메인이 명시 적으로 설정되면 값은 전달되지 않았지만 명시 적으로 도메인의 일부가 추가됩니다. " 이를 위해 원래 코드에서 rect 앞에 x 축을 호출하면 명시 적 배열 만 호출된다는 것을 알 수 있습니다. – nsonnad