我正在修改以下堆积的折线图示例:https://bl.ocks.org/d3indepth/e4efd402b4d9fdb2088ccdf3135745c3
我要添加一个时间x轴,但是我在这段代码中苦苦挣扎:
var areaGenerator = d3.area()
.x(function(d, i) {
// return i * 100;
return i * 253.5;
})
.y0(function(d) {
return y(d[0]);
})
.y1(function(d) {
return y(d[1]);
});
原始示例的.x
访问器为i * 100
,这似乎是一个随机值。当我添加X轴时,堆积的折线图无法与日期刻度正确对齐。我可以通过返回i * 253.5
来强制其排成一行,但这并不理想。我不太了解此区域功能的工作原理-希望能获得任何帮助。
let height = 600;
let width = 800;
const yMax = 4000;
//var hEach = 40;
let margin = {top: 20, right: 15, bottom: 25, left: 25};
width = width - margin.left - margin.right;
height = height - margin.top - margin.bottom;
var svg = d3.select('body').append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
let formatDate = d3.timeFormat("%b-%Y")
let parseTime = d3.timeParse("%Y-%m-%d");
let data = [
{
"host_count": 2553,
"container_count": 875,
"hour": "2019-01-31",
"apm_host_count": 0,
"agent_host_count": 2208,
"gcp_host_count": 0,
"aws_host_count": 345
},
{
"host_count": 1553,
"container_count": 675,
"hour": "2019-02-01",
"apm_host_count": 0,
"agent_host_count": 1208,
"gcp_host_count": 0,
"aws_host_count": 445
},
{
"host_count": 716,
"container_count": 6234,
"hour": "2019-02-02",
"apm_host_count": 0,
"agent_host_count": 479,
"gcp_host_count": 0,
"aws_host_count": 237
},
{
"host_count": 516,
"container_count": 4234,
"hour": "2019-02-03",
"apm_host_count": 0,
"agent_host_count": 679,
"gcp_host_count": 0,
"aws_host_count": 137
}
];
// format the data
data.forEach(function(d) {
d.hour = parseTime(d.hour);
});
// set the ranges
var x = d3.scaleTime().range([0, width]);
x.domain(d3.extent(data, function(d) { return d.hour; }));
var xAxis = d3.axisBottom(x).ticks(11).tickFormat(d3.timeFormat("%y-%b-%d")).tickValues(data.map(d=>d.hour));
var y = d3.scaleLinear()
.domain([0, yMax])
.range([height, 0]);
var areaGenerator = d3.area()
.x(function(d, i) {
console.log(d);
return i * 100;
})
.y0(function(d) {
return y(d[0]);
})
.y1(function(d) {
return y(d[1]);
});
var colors = ['#FBB65B', '#513551', '#de3163']
var stack = d3.stack()
.keys(['agent_host_count', 'aws_host_count', 'container_count']);
var stackedSeries = stack(data);
d3.select('g')
.selectAll('path')
.data(stackedSeries)
.enter()
.append('path')
.style('fill', function(d, i) {
return colors[i];
})
.attr('d', areaGenerator)
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
<!doctype html>
<html lang="en">
<head>
<title>Usage</title>
</head>
<body>
<div id="svg"></div>
<script src="https://d3js.org/d3.v5.min.js"></script>
</body>
</html>
答案 0 :(得分:1)
在d3中使用轴时,实际上需要使用轴变量来计算比例因子。进行此计算的函数由scale*()
方法返回。在您的代码中,x轴具有以下功能:
var x = d3.scaleTime().range([0, width]);
这样,变量x
现在包含一个将为您进行插值的函数。这就是您的areaGenerator
函数的样子:
var areaGenerator = d3.area()
.x(function(d, i) {
return x(d.data.hour);
})
.y0(function(d) {
return y(d[0]);
})
.y1(function(d) {
return y(d[1]);
});
您唯一需要记住的是,在计算值时,需要使用轴所基于的相同变量。即您的x轴是时间轴,因此您需要使用时间变量(d.data.hour
)计算插值。
对于示例中100来自何处,您基本上是正确的。在该块中,值100或多或少是任意的。之所以选择它,是因为该图表在该比例下看起来相当不错。通过选择100,每个“刻度”之间的间隔为100像素,并且由于没有要判断的x轴,因此实际上只要使用每个数据点都可以更改,则实际上无关紧要。