最终,我只是想在一个简单的多线图中绘制 Node.js 内存使用情况随时间变化的情况。也许已经有一个包可以做到这一点,但我没有看到。 Node.js/V8 内存使用有 3 个组成部分,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。
这是代码中值对象的屏幕截图:
最佳答案
您的代码的问题在于您的 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
),所以最后一行不会留在轴的顶部。
关于javascript - D3 多线图显示 2 条线而不是 3 条线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45406986/