gpt4 book ai didi

javascript - 如何在带有 scaleTime 的条形图中使用 x 和宽度?

转载 作者:行者123 更新时间:2023-11-29 16:39:09 25 4
gpt4 key购买 nike

我这里有一个代码笔 - https://codepen.io/anon/pen/xpaYYw?editors=0010

这是一个简单的测试图,但日期会像这样格式化。

我在 x 轴上有日期,在 y 轴上有数量

如何使用 x 刻度来设置条形的宽度和 x 位置。

    layers.selectAll('rect')
.data(data)
.enter()
.append('rect')

.attr('height', function(d, i) {
return height - y(d.one);
})

.attr('y', function(d, i) {
return y(d.one);
})

.attr('width', function(d, i) {
return 50;
})

.attr('x', function(d, i) {
return 80*i;
})

.style('fill', (d, i) => {
return colors[i];
});

最佳答案

你的问题与编程、JavaScript 或 D3 无关...问题是一个基本的数据可视化概念(这就是为什么我在你的问题中添加了 标签):

您尝试做的是不正确的!您应该使用带有时间刻度的条形图。时间尺度用于时间序列(其中我们使用点,或由线连接的点)。

如果您在 x 轴上使用带有时间的条形图,您将面临问题:

  1. 定位栏:栏的左边距将始终位于您设置的日期。整个酒吧将在该日期之后
  2. 设置条形的宽度:在真实的条形图中,x 轴使用分类变量,宽度没有意义。但在时间尺度中,宽度代表时间

但是,为了便于解释,让我们创建这个带有时间刻度的条形图(尽管事实上这是一个错误的选择)...以下是操作方法:

首先,在时间中设置条形的“宽度”。比方说,每个条形有 10 天的宽度:

.attr("width", function(d){
return x(d3.timeDay.offset(d.date, 10)) - x(d.date)
})

然后,将条形图的 x 位置设置为当前日期减去其宽度的一半(即在我们的示例中减去 5 天):

.attr('x', function(d, i) {
return x(d3.timeDay.offset(d.date, -5));
})

最后,不要忘记在时间尺度上创建一个“填充”:

var x = d3.scaleTime()
.domain([d3.min(data, function(d) {
return d3.timeDay.offset(d.date, -10);
}), d3.max(data, function(d) {
return d3.timeDay.offset(d.date, 10);
})])
.range([0, width]);

这是您的代码,其中包含这些更改:

var keys = [];
var legendKeys = [];

var maxVal = [];

var w = 800;
var h = 450;

var margin = {
top: 30,
bottom: 40,
left: 50,
right: 20,
};

var width = w - margin.left - margin.right;
var height = h - margin.top - margin.bottom;

var colors = ['#FF9A00', '#FFEBB6', '#FFC400', '#B4EDA0', '#FF4436'];

var data = [{
"one": 4306,
"two": 2465,
"three": 2299,
"four": 988,
"five": 554,
"six": 1841,
"date": "2015-05-31T00:00:00"
}, {
"one": 4378,
"two": 2457,
"three": 2348,
"four": 1021,
"five": 498,
"six": 1921,
"date": "2015-06-30T00:00:00"
}, {
"one": 3404,
"two": 2348,
"three": 1655,
"four": 809,
"five": 473,
"six": 1056,
"date": "2015-07-31T00:00:00"
},

];

data.forEach(function(d) {
d.date = new Date(d.date)
})

for (var i = 0; i < data.length; i++) {
for (var key in data[i]) {
if (!data.hasOwnProperty(key) && key !== "date")
maxVal.push(data[i][key]);
}
}

var x = d3.scaleTime()
.domain([d3.min(data, function(d) {
return d3.timeDay.offset(d.date, -10);
}), d3.max(data, function(d) {
return d3.timeDay.offset(d.date, 10);
})])
.range([0, width]);

var y = d3.scaleLinear()
.domain([0, d3.max(maxVal, function(d) {
return d;
})])
.range([height, 0]);

var svg = d3.select('body').append('svg')
.attr('class', 'chart')
.attr('width', w)
.attr('height', h);

var chart = svg.append('g')
.classed('graph', true)
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var layersArea = chart.append('g')
.attr('class', 'layers');


var layers = layersArea.append('g')
.attr('class', 'layer');

layers.selectAll('rect')
.data(data)
.enter()
.append('rect')

.attr('height', function(d, i) {
return height - y(d.one);
})

.attr('y', function(d, i) {
return y(d.one);
})

// .attr('width', function(d, i) {
// return 50;
// })

.attr("width", function(d) {
return x(d3.timeDay.offset(d.date, 10)) - x(d.date)
})

.attr('x', function(d, i) {
return x(d3.timeDay.offset(d.date, -5));
})

.style('fill', (d, i) => {
return colors[i];
});

chart.append('g')
.classed('x axis', true)
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x)
.tickFormat(d3.timeFormat("%Y-%m-%d")).tickValues(data.map(function(d) {
return new Date(d.date)
})));

chart.append('g')
.classed('y axis', true)
.call(d3.axisLeft(y)
.ticks(10));
<script src="https://d3js.org/d3.v4.min.js"></script>

关于javascript - 如何在带有 scaleTime 的条形图中使用 x 和宽度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48278994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com