2016-03-21 3 views
0

Я хотел построить линейный график, который представляет данные, собранные за пару месяцев. Я придумал код ниже. Проблема в том, что я не думаю, что строка правильно отображает данные (или это не то, как я этого хотел). вы видите, что линия path не доходит до отметки «4 мес», которая заставляет пользователей полагать, что данные заканчиваются примерно на 3 с половиной месяца.выстроить точки данных графика на тики по оси x

Я хотел бы, чтобы все вершины (не уверен, что правильный термин, на мой взгляд, можно назвать визуализированной точкой данных), чтобы правильно соответствовать тикам. поэтому первая точка данных должна быть в верхней части «1 mo», а вторая точка данных должна совпадать с «2 mo» и т. д. ... И это очень важно, последняя точка данных должна быть в конце график и месяц 4 также должны быть в конце оси. прямо сейчас линия не проходит всю ширину svg.

var data = [ 
 
    {"quarter" : "1mo", "votes" : 400}, 
 
    {"quarter" : "2mo", "votes": 200}, 
 
    {"quarter": "3mo", "votes" : 1000}, 
 
    {"quarter" : "4mo", "votes" : 0} 
 
] 
 

 
var width = 500; 
 
var height = 300; 
 
//supposed to get the domain ([0, 1000]) 
 
var yscale = d3.scale.linear().domain([0, d3.max(data, function(d) {return d.votes})]) 
 
yscale.range([height, 0]) 
 

 
console.log(yscale(900)) //291 
 

 
var xscale = d3.scale.ordinal() 
 
.domain(data.map(function(d) {return d.quarter})) 
 
.rangeRoundBands([0,width]) 
 

 
var xAxis = d3.svg.axis().scale(xscale).orient("bottom") 
 

 

 
var line = d3.svg.line() 
 
.x(function(d){return xscale(d.quarter) }) 
 
.y(function(d) {return yscale(d.votes) }) 
 
// .interpolate("basis") 
 

 
var svg = d3.select("body") 
 
.append("svg") 
 
.attr({ 
 
    "width" : (width + 20), 
 
    "height": height + 20 
 
}) 
 

 
svg.append("g") 
 
.append("path") 
 
.attr("d", line(data)) 
 
.attr({ 
 
    "fill" : "none", 
 
    "stroke" : "limegreen", 
 
    "stroke-width" : "3px" 
 
}) 
 

 
svg.append("g") 
 
.call(xAxis) 
 
.attr({ 
 
    "transform" : "translate(0," + (height) + ")" 
 
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>

ответ

0

Вы должны переместить каждую из вершин в центре rangeBand:

var line = d3.svg.line() 
    .x(function(d){return xscale(d.quarter) + xscale.rangeBand()/2 }) 
    .y(function(d) {return yscale(d.votes) }); 

Вы можете прочитать больше о порядковых шкал here.

Если вы хотите рентгеновские тиков, начиная с 0, вы можете использовать rangePoints вместо rangeRoundBands:

var xscale = d3.scale.ordinal() 
    .domain(data.map(function(d) {return d.quarter})) 
    .rangePoints([0,width]); 

Вот рабочая скрипку: https://jsfiddle.net/6d7wqeyh/

Вы можете видеть, что значения получают обрезается. Но я думаю, что вы поняли эту идею.

+0

Отличный ответ. Я вижу, что данные выровнены. Теперь вы можете помочь мне с другой частью вопроса, где ширина линии должна занимать ширину svg. прямо сейчас граф строк выглядит так, как будто он находится в середине графика. Он должен выглядеть так, как будто он занимает весь график. не должно быть никакого пробела слева от графика до начала графика. и то же самое о конце. –

+0

Какую строку вы имеете в виду? Это ось x? – AKS

+0

Я хочу, чтобы путь занимал то же самое, что и ось х. Это помогает прояснить ситуацию? и тики все равно должны совпадать с точками данных. –

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