D3 многострочный график отображает 2 линии, а не 3
В конечном счете, я просто пытаюсь построить узел.использование памяти js с течением времени, в простом многострочном графике. Может быть, есть пакет, который уже делает это, но я его не вижу. В узле есть 3 компонента.использование памяти js/V8, heapUsed
, heapTotal
, и rss
, я хотел бы построить их со временем.
Чтобы сделать многострочный график С D3, я следую примеру здесь: https://code.tutsplus.com/tutorials/building-a-multi-line-chart-using-d3js--cms-22935
Полный код из пример здесь: https://github.com/jay3dec/MultiLineChart_D3/blob/master/index.html
Вот мой код:
<!DOCTYPE html>
<html lang='en'>
<head>
<link href='http://getbootstrap.com/dist/css/bootstrap.min.css' rel='stylesheet'>
<link href='http://getbootstrap.com/examples/justified-nav/justified-nav.css' rel='stylesheet'>
<script src='http://d3js.org/d3.v3.min.js' charset='utf-8'></script>
<style>
.axis path {
fill: none;
stroke: #777;
shape-rendering: crispEdges;
}
.axis text {
font-family: Lato;
font-size: 13px;
}
</style>
</head>
<body>
<div class='container'>
<div class='jumbotron'>
<svg id='visualisation' width='1000' height='500'></svg>
<script>
var heapTotal = [
{x: Date.now() - 500, y: 100},
{x: Date.now(), y: 125},
{x: Date.now() + 500, y: 150},
];
var heapUsed = [
{x: Date.now() - 500, y: 110},
{x: Date.now(), y: 111},
{x: Date.now() + 500, y: 112},
];
var rss = [
{x: Date.now() - 500, y: 44},
{x: Date.now(), y: 44},
{x: Date.now() + 500, y: 44},
];
const values = heapTotal.concat(heapUsed).concat(rss).reduce(function (prev, curr) {
console.log('curr => ', curr);
return {
xMin: Math.min(prev.xMin, curr.x),
xMax: Math.max(prev.xMax, curr.x),
yMin: Math.min(prev.yMin, curr.y),
yMax: Math.max(prev.yMax, curr.y),
}
}, {
xMin: Number.MAX_SAFE_INTEGER,
xMax: -1,
yMin: Number.MAX_SAFE_INTEGER,
yMax: -1
});
console.log('values => ', values);
var vis = d3.select('#visualisation'),
WIDTH = 1200,
HEIGHT = 800,
MARGINS = {
top: 20,
right: 20,
bottom: 20,
left: 50
},
xScale = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([values.xMin, values.xMax]),
yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([values.yMin, values.yMax]),
xAxis = d3.svg.axis()
.scale(xScale),
yAxis = d3.svg.axis()
.scale(yScale)
.orient('left');
vis.append('svg:g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + (HEIGHT - MARGINS.bottom) + ')')
.call(xAxis);
vis.append('svg:g')
.attr('class', 'y axis')
.attr('transform', 'translate(' + (MARGINS.left) + ',0)')
.call(yAxis);
var lineGen = d3.svg.line()
.x(function (d) {
return xScale(d.x);
})
.y(function (d) {
return yScale(d.y);
})
.interpolate('basis');
vis.append('svg:path')
.attr('d', lineGen(heapUsed))
.attr('stroke', 'green')
.attr('stroke-width', 2)
.attr('fill', 'none');
vis.append('svg:path')
.attr('d', lineGen(heapTotal))
.attr('stroke', 'blue')
.attr('stroke-width', 2)
.attr('fill', 'none');
vis.append('svg:path')
.attr('d', lineGen(rss))
.attr('stroke', 'red')
.attr('stroke-width', 2)
.attr('fill', 'none');
</script>
</div>
</div>
</body>
</html>
Но по какой-то причине он строит только 2 строки, а не 3:
У кого-нибудь есть идеи, почему?
Похоже, что 3-я линия просто не видна, учитывая размеры-ака, ось y не опускается до 44.
Вот скриншот объекта values из кода:
1 ответ:
Проблема с вашим кодом заключается в том, что ваш выбор SVG (с именем
vis
) указывает на этот элемент SVG...<svg id='visualisation' width='1000' height='500'></svg>
... который имеет высоту 500px.
Однако ваш вертикальный масштаб (yScale) использует переменнуюHEIGHT
, которая является800
.Поэтому ось правильная, но она идет за нижнюю границу SVG (вы можете ясно видеть, что осматриваете элемент), а также вашу третью линию, которая окрашивается, но она не видна, потому что она в настоящее время лежит вне пределов SVG.
Решение : используйте переменные
HEIGHT
иWIDTH
для задания высоты и ширины вашего SVG:vis.attr("width", WIDTH) .attr("height", HEIGHT)
Альтернативно, если высота, которую вы хотите, на самом деле является встроенной высотой этого SVG (то есть
500
), измените свою переменнуюHEIGHT
соответственно.Вот ваш обновленный код, теперь вы можете увидеть последнюю строку:
var heapTotal = [{ x: Date.now() - 500, y: 100 }, { x: Date.now(), y: 125 }, { x: Date.now() + 500, y: 150 }, ]; var heapUsed = [{ x: Date.now() - 500, y: 110 }, { x: Date.now(), y: 111 }, { x: Date.now() + 500, y: 112 }, ]; var rss = [{ x: Date.now() - 500, y: 44 }, { x: Date.now(), y: 44 }, { x: Date.now() + 500, y: 44 }, ]; const values = heapTotal.concat(heapUsed).concat(rss).reduce(function(prev, curr) { return { xMin: Math.min(prev.xMin, curr.x), xMax: Math.max(prev.xMax, curr.x), yMin: Math.min(prev.yMin, curr.y), yMax: Math.max(prev.yMax, curr.y), } }, { xMin: Number.MAX_SAFE_INTEGER, xMax: -1, yMin: Number.MAX_SAFE_INTEGER, yMax: -1 }); var vis = d3.select('#visualisation'), WIDTH = 1200, HEIGHT = 800, MARGINS = { top: 20, right: 20, bottom: 20, left: 50 }, xScale = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([values.xMin, values.xMax]), yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([0.95*values.yMin, values.yMax]), xAxis = d3.svg.axis() .scale(xScale), yAxis = d3.svg.axis() .scale(yScale) .orient('left'); vis.attr("width", WIDTH) .attr("height", HEIGHT) vis.append('svg:g') .attr('class', 'x axis') .attr('transform', 'translate(0,' + (HEIGHT - MARGINS.bottom) + ')') .call(xAxis); vis.append('svg:g') .attr('class', 'y axis') .attr('transform', 'translate(' + (MARGINS.left) + ',0)') .call(yAxis); var lineGen = d3.svg.line() .x(function(d) { return xScale(d.x); }) .y(function(d) { return yScale(d.y); }) .interpolate('basis'); vis.append('svg:path') .attr('d', lineGen(heapUsed)) .attr('stroke', 'green') .attr('stroke-width', 2) .attr('fill', 'none'); vis.append('svg:path') .attr('d', lineGen(heapTotal)) .attr('stroke', 'blue') .attr('stroke-width', 2) .attr('fill', 'none'); vis.append('svg:path') .attr('d', lineGen(rss)) .attr('stroke', 'red') .attr('stroke-width', 2) .attr('fill', 'none');
.axis path { fill: none; stroke: #777; shape-rendering: crispEdges; } .axis text { font-family: Lato; font-size: 13px; }
<script src="https://d3js.org/d3.v3.min.js"></script> <svg id='visualisation'></svg>
PS: Я немного уменьшил нижний конец вашей шкалы (
0.95*values.yMin
), поэтому последняя строка не остается на вершине оси.