2015-11-17 3 views
0

Я только что начал изучать d3.js на прошлой неделе, и я пытаюсь создать участок разброса. Я ожидаю t1, t2, t3, t4, t5 по оси y. И x-anxis - от 1 до максимального значения качества. Но после запуска кода ниже, похоже, что положение точек неверно. Два из них даже вне диапазона y aix. Я не могу понять, почему. Может ли кто-нибудь помочь исправить код и объяснить почему? Заранее спасибо!положение точек в рассеянном участке d3.js

<!DOCTYPE html> 
<html> 
    <head> 
    <meta charset="utf-8"> 
    <title>Dot Plot</title> 
    <style> 
    .axis path, 
    .axis line{ 
     fill: none; 
     stroke: #000; 
     shape-rendering: crishpEdges; 
     }  
    .circles { opacity: .7; } 
    </style> 
    </head> 
    <body> 
    <h1 style = "text-align:center;">Dot Plot Example</h1>  
    </body> 

    <body> 

    <script src="http://d3js.org/d3.v3.min.js"></script> 
    <script> 
    var data = [ 
    {"custid": 1, "Type": "t1","quality": 7}, 
    {"custid": 2, "Type": "t2", "quality": 2}, 
    {"custid": 3, "Type": "t3", "quality": 3}, 
    {"custid": 4, "Type": "t4", "quality": 7}, 
    {"custid": 5, "Type": "t5", "quality": 2} 
    ]; 

     data.forEach(function(d){ 
     d.quality = +d.quality; 
     d.Type = d.Type; 
     return console.log(data); 
    }) 

    var margin = {t:30, r:20, b:40, l:40 }, 
     w = 600 - margin.l - margin.r, 
     h = 500 - margin.t - margin.b; 

    var color = d3.scale.category20c(); 

    var x = d3.scale.linear() 
     .range([0, w]) 
     .domain([0,d3.max(data, function(d){return d.quality})]); 

    var y = d3.scale.ordinal() 
     .range([h,0]) 
     .domain(data.map(function(d){return d.Type;}));  

    var xAxis = d3.svg.axis() 
     .scale(x) 
     .orient("bottom") 
     .ticks(8); 

    var yAxis = d3.svg.axis() 
     .scale(y) 
     .orient("left") 
     .ticks(6); 

    var svg = d3.select("body") 
     .append("svg") 
     .attr("width", w + margin.l + margin.r) 
     .attr("height", h + margin.t + margin.b) 
     .style("margin-left", "auto") 
     .style("margin-right", "auto") 
     .style("display", "block") 
     .append("g") 
     .attr("transform", "translate(" + margin.l + "," + margin.t + ")");  

    svg.selectAll("circle") 
     .data(data) 
     .enter() 
     .append("circle") 
     .attr("class", "circles") 
     .attr({ 
     cx: function(d) { return x(d.quality); }, 
     cy: function(d) { return y(d.Type); }, 
     r: 8 
     }) 
     .style("fill", function(d){return color(d.Type);}); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(" + margin.l + "," + (h - 20 + margin.t) + ")") 
     .call(xAxis); 

    svg.append("g") 
     .attr("class", "y axis") 
     .attr("transform", "translate(" + margin.l + "," + margin.t + ")") 
     .call(yAxis); 
    </script> 
    </body> 
</html> 
+1

Каким образом позиции не правильные? Что вы ожидаете вместо этого? –

ответ

1

Есть две проблемы. Во-первых, порядковый масштаб, когда вы его используете, предполагает сопоставление 1: 1 между элементами домена и диапазона. То есть для каждого элемента массива, заданного .range(), должен быть соответствующий элемент в массиве, заданный .domain(). В вашем случае у вас есть 5 значений домена, но только 2 значения диапазона. В таких случаях, вы должны использовать .rangeRoundPoints(), который разделит интервал автоматически, в зависимости от количества значений в домене:

var y = d3.scale.ordinal() 
    .rangeRoundPoints([h,0]) 
    .domain(data.map(function(d){return d.Type;})); 

Во-вторых, вы переводите контейнеры для осей по краю, но дон 't включить это для точек. Вам просто нужно

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

svg.append("g") 
    .attr("class", "y axis") 
    .call(yAxis); 

Полный пример here.

+0

Большое спасибо! Как перемещать тик t1 немного вверх по оси y, так как он находится на оси x. – yxz122930

+0

Вы можете изменить диапазон шкалы: https://jsfiddle.net/vny7p798/1/ –

Смежные вопросы