Я пытаюсь сделать простой линейный граф с d и угловой директивой. Область svg отображается на странице, но часть строки выполняет рендеринг со страницы.
Я использую d3 v4
Я масштабировал данные x и y. Мой console.log показывает, что значения x и y должны вписываться в ширину и высоту svg. Я некоторое время занимаюсь исследованиями и не могу найти какое-либо решение, которое работает.
Вот угловой код:
graphics.directive('lineVis', function(){
return{
restrict: 'E',
scope: {
val: '=',
grouped: '='
},
link: function(scope, element, attrs){
var margin = 25,
width = 960,
height = 500;
data = [{_id:16998.0, total: 1854},{_id:16999.0, total: 2157},{_id:17000.0, total: 2389},{_id:17001.0, total: 2187},{_id:17002.0, total: 1973},{_id:17003.0, total: 1050}];
console.log(data.length);
var x = d3.scaleLinear()
.range([margin, width-margin])
.domain(d3.extent(data, function(d) {return d._id;}));
//[d3.min(data, function(d){return d._id}), d3.max(data, function(d){return d._id})])
var y = d3.scaleLinear()
.range([margin, height-margin])
.domain([0, d3.max(data, function(d){
return d.total;
})]);
var line = d3.line()
.x(function(d){
console.log('Y: '+ y(d.total) + ' X: ' + x(d._id));
return (d._id);
})
.y(function(d){
return y(d.total);
})
var svg = d3.select(element[0])
.append('svg')
.attr('width', width+margin)
.attr('height', height+margin);
svg.selectAll('*').remove() //remove all previous elements
svg.append('path')
.attr('class', 'line')
.attr('stroke', '#777')
.attr('d', line(data));
}
}
});
И css:
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
Я знаю, что html работает, потому что svg и строка рендеринга, линия - это просто отображение экрана.
Спасибо вам за помощь!
Вы забыли добавить g
элемент в svg, переведенный в значения поля. Посмотрите пример Майка https://gist.github.com/mbostock/3019563.
Чтобы предотвратить дублирование кода, вычтите поля с ширины/высоты и определите результат как ширину/высоту. Теперь вам не нужно постоянно говорить "край".
//in case you want different values per side
var margin = {top: 25, right: 25, bottom: 25, left: 25};
var width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var svg = d3.select(element[0])
.append('svg')
.attr('width', width+margin)
.attr('height', height+margin);
.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
Спасибо, Эрик! Я согласен, что это делает код более удобным для чтения и более гибким. (а также фактически добавить поля)
Я также не учитывал масштаб x на d3.line():
var line = d3.line()
.x(function(d){
console.log('Y: '+ y(d.total) + ' X: ' + x(d._id));
return x(d._id); // <-- added x call
})
.y(function(d){
return y(d.total);
})
Теперь линия отобразится! однако теперь он перевернут... детские шаги
РЕДАКТИРОВАТЬ:
когда я говорю инвертированный, я имею в виду, что линейный график начинается в правом верхнем углу
РЕШЕНИЕ:
switch.domain для масштабирования y:
var y = d3.scaleLinear()
.range([0, height])
.domain([d3.max(data, function(d){
return d.total;
}), 0]);
Надеюсь, это поможет кому-то еще!