我正在尝试使用d3创建一个热图。我已经创建了轴和比例,但我被困在如何绘制矩形。我使用内置的scale函数从矩形中获得x和y点。
attr('x', d => {
return timeScale(d.hour);
})
.attr('y', d => {
return dayScale(d.day);
})但问题在于计算每个矩形的宽度和高度。我不知道如何计算它。到目前为止,我使用的是
.attr('width', gridSize)
.attr('height', gridSize)设置高度和宽度,但它不能正常工作。我知道另一种方法是使用:
.attr('x', d => (((d.hour - 1) * gridSize) + padding))
.attr('y', d => (((d.day - 1) * gridSize) + padding))
.attr('class', 'hour bordered')
.attr('width', gridSize)
.attr('height', gridSize)
.style('fill', colors[0])但是想要避免这种情况。
到目前为止,您可以找到我编写/复制的代码here
var margin = {
top: 80,
right: 30,
bottom: 10,
left: 30
};
//Width and height
var width = 960 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
var padding = 49;
gridSize = Math.floor((width - (padding * 2)) / 24) // size of individual gridItem i.e the square which is drawn
/*
To calculate the gridSize we take width and subtract padding * 2, why times 2 because padding is on both side of the square (the gridItem). Then we divide
it by 24
*/
buckets = 12;
legendElementWidth = gridSize * 2
colors = ["#FFCB4A", "#D7C74A", "#C5C54A", "#B3C34A", "#A0C149", "#8EBF49", "#7CBE49", "#6ABC49", "#58BA49", "#45B848", "#33B648", "#21B448"]
days = ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]
times = ["1a", "2a", "3a", "4a", "5a", "6a", "7a", "8a", "9a", "10a", "11a", "12a", "1p", "2p", "3p", "4p", "5p", "6p", "7p", "8p", "9p", "10p", "11p", "12p"]
colorScale = d3.scaleQuantile().domain([0, buckets - 1, d3.max(dataset, d => d.value)]).range(colors); // no idea what is buckets - 1 doing here :(
var svg = d3.select('.card')
.append('svg')
.attr('height', height + margin.top + margin.bottom)
.attr('width', width + margin.left + margin.right)
.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`)
var dayScale = d3.scaleLinear().domain([7, 1]).range([height, 0]);
var dayAxis = d3.axisLeft().ticks(7).scale(dayScale)
svg.append('g').attr('class', 'xAxis').call(dayAxis)
var timeScale = d3.scaleLinear().domain([1, 24]).range([0, width])
var timeAxis = d3.axisTop().scale(timeScale).ticks(24)
svg.append('g').attr('class', 'yAxis').call(timeAxis)
svg.selectAll('.squares')
.data(dataset)
.enter()
.append('rect')
.attr('x', d => {
return timeScale(d.hour);
})
.attr('y', d => {
return dayScale(d.day);
})
.attr('width', gridSize)
.attr('height', gridSize)
.style('fill', d => colorScale(d.value))
dataset = [{
day: 1,
hour: 1,
value: 0
},
{
day: 1,
hour: 2,
value: 0
},
{
day: 1,
hour: 3,
value: 0
},
{
day: 1,
hour: 4,
value: 1
},
{
day: 1,
hour: 5,
value: 0
},
{
day: 1,
hour: 6,
value: 1
},
{
day: 1,
hour: 7,
value: 2
},
{
day: 1,
hour: 8,
value: 2
},
{
day: 1,
hour: 9,
value: 3
},
{
day: 1,
hour: 10,
value: 5
},
{
day: 1,
hour: 11,
value: 14
},
{
day: 1,
hour: 12,
value: 8
},
{
day: 1,
hour: 13,
value: 16
},
{
day: 1,
hour: 14,
value: 20
},
{
day: 1,
hour: 15,
value: 7
},
{
day: 1,
hour: 16,
value: 11
},
{
day: 1,
hour: 17,
value: 10
},
{
day: 1,
hour: 18,
value: 4
},
{
day: 1,
hour: 19,
value: 7
},
{
day: 1,
hour: 20,
value: 4
},
{
day: 1,
hour: 21,
value: 1
},
{
day: 1,
hour: 22,
value: 2
},
{
day: 1,
hour: 23,
value: 0
},
{
day: 1,
hour: 24,
value: 1
},
{
day: 2,
hour: 1,
value: 0
},
{
day: 2,
hour: 2,
value: 0
},
{
day: 2,
hour: 3,
value: 0
},
{
day: 2,
hour: 4,
value: 1
},
{
day: 2,
hour: 5,
value: 0
},
{
day: 2,
hour: 6,
value: 2
},
{
day: 2,
hour: 7,
value: 4
},
{
day: 2,
hour: 8,
value: 6
},
{
day: 2,
hour: 9,
value: 2
},
{
day: 2,
hour: 10,
value: 12
},
{
day: 2,
hour: 11,
value: 15
},
{
day: 2,
hour: 12,
value: 18
},
{
day: 2,
hour: 13,
value: 11
},
{
day: 2,
hour: 14,
value: 24
},
{
day: 2,
hour: 15,
value: 6
},
{
day: 2,
hour: 16,
value: 10
},
{
day: 2,
hour: 17,
value: 14
},
{
day: 2,
hour: 18,
value: 3
},
{
day: 2,
hour: 19,
value: 1
},
{
day: 2,
hour: 20,
value: 2
},
{
day: 2,
hour: 21,
value: 0
},
{
day: 2,
hour: 22,
value: 0
},
{
day: 2,
hour: 23,
value: 1
},
{
day: 2,
hour: 24,
value: 0
},
{
day: 3,
hour: 1,
value: 0
},
{
day: 3,
hour: 2,
value: 0
},
{
day: 3,
hour: 3,
value: 0
},
{
day: 3,
hour: 4,
value: 0
},
{
day: 3,
hour: 5,
value: 0
},
{
day: 3,
hour: 6,
value: 0
},
{
day: 3,
hour: 7,
value: 1
},
{
day: 3,
hour: 8,
value: 1
},
{
day: 3,
hour: 9,
value: 3
},
{
day: 3,
hour: 10,
value: 6
},
{
day: 3,
hour: 11,
value: 11
},
{
day: 3,
hour: 12,
value: 15
},
{
day: 3,
hour: 13,
value: 10
},
{
day: 3,
hour: 14,
value: 6
},
{
day: 3,
hour: 15,
value: 2
},
{
day: 3,
hour: 16,
value: 7
},
{
day: 3,
hour: 17,
value: 9
},
{
day: 3,
hour: 18,
value: 13
},
{
day: 3,
hour: 19,
value: 11
},
{
day: 3,
hour: 20,
value: 8
},
{
day: 3,
hour: 21,
value: 4
},
{
day: 3,
hour: 22,
value: 1
},
{
day: 3,
hour: 23,
value: 0
},
{
day: 3,
hour: 24,
value: 0
},
{
day: 4,
hour: 1,
value: 1
},
{
day: 4,
hour: 2,
value: 0
},
{
day: 4,
hour: 3,
value: 0
},
{
day: 4,
hour: 4,
value: 0
},
{
day: 4,
hour: 5,
value: 0
},
{
day: 4,
hour: 6,
value: 1
},
{
day: 4,
hour: 7,
value: 2
},
{
day: 4,
hour: 8,
value: 4
},
{
day: 4,
hour: 9,
value: 7
},
{
day: 4,
hour: 10,
value: 4
},
{
day: 4,
hour: 11,
value: 2
},
{
day: 4,
hour: 12,
value: 1
},
{
day: 4,
hour: 13,
value: 5
},
{
day: 4,
hour: 14,
value: 8
},
{
day: 4,
hour: 15,
value: 10
},
{
day: 4,
hour: 16,
value: 14
},
{
day: 4,
hour: 17,
value: 8
},
{
day: 4,
hour: 18,
value: 4
},
{
day: 4,
hour: 19,
value: 3
},
{
day: 4,
hour: 20,
value: 1
},
{
day: 4,
hour: 21,
value: 0
},
{
day: 4,
hour: 22,
value: 2
},
{
day: 4,
hour: 23,
value: 0
},
{
day: 4,
hour: 24,
value: 0
},
{
day: 5,
hour: 1,
value: 0
},
{
day: 5,
hour: 2,
value: 0
},
{
day: 5,
hour: 3,
value: 0
},
{
day: 5,
hour: 4,
value: 0
},
{
day: 5,
hour: 5,
value: 0
},
{
day: 5,
hour: 6,
value: 0
},
{
day: 5,
hour: 7,
value: 0
},
{
day: 5,
hour: 8,
value: 0
},
{
day: 5,
hour: 9,
value: 3
},
{
day: 5,
hour: 10,
value: 1
},
{
day: 5,
hour: 11,
value: 5
},
{
day: 5,
hour: 12,
value: 10
},
{
day: 5,
hour: 13,
value: 14
},
{
day: 5,
hour: 14,
value: 17
},
{
day: 5,
hour: 15,
value: 23
},
{
day: 5,
hour: 16,
value: 10
},
{
day: 5,
hour: 17,
value: 8
},
{
day: 5,
hour: 18,
value: 5
},
{
day: 5,
hour: 19,
value: 3
},
{
day: 5,
hour: 20,
value: 1
},
{
day: 5,
hour: 21,
value: 0
},
{
day: 5,
hour: 22,
value: 0
},
{
day: 5,
hour: 23,
value: 0
},
{
day: 5,
hour: 24,
value: 0
},
{
day: 6,
hour: 1,
value: 0
},
{
day: 6,
hour: 2,
value: 0
},
{
day: 6,
hour: 3,
value: 0
},
{
day: 6,
hour: 4,
value: 0
},
{
day: 6,
hour: 5,
value: 0
},
{
day: 6,
hour: 6,
value: 0
},
{
day: 6,
hour: 7,
value: 0
},
{
day: 6,
hour: 8,
value: 0
},
{
day: 6,
hour: 9,
value: 0
},
{
day: 6,
hour: 10,
value: 1
},
{
day: 6,
hour: 11,
value: 3
},
{
day: 6,
hour: 12,
value: 2
},
{
day: 6,
hour: 13,
value: 1
},
{
day: 6,
hour: 14,
value: 0
},
{
day: 6,
hour: 15,
value: 2
},
{
day: 6,
hour: 16,
value: 1
},
{
day: 6,
hour: 17,
value: 0
},
{
day: 6,
hour: 18,
value: 0
},
{
day: 6,
hour: 19,
value: 0
},
{
day: 6,
hour: 20,
value: 0
},
{
day: 6,
hour: 21,
value: 0
},
{
day: 6,
hour: 22,
value: 0
},
{
day: 6,
hour: 23,
value: 0
},
{
day: 6,
hour: 24,
value: 0
},
{
day: 7,
hour: 1,
value: 0
},
{
day: 7,
hour: 2,
value: 0
},
{
day: 7,
hour: 3,
value: 0
},
{
day: 7,
hour: 4,
value: 0
},
{
day: 7,
hour: 5,
value: 0
},
{
day: 7,
hour: 6,
value: 0
},
{
day: 7,
hour: 7,
value: 0
},
{
day: 7,
hour: 8,
value: 0
},
{
day: 7,
hour: 9,
value: 0
},
{
day: 7,
hour: 10,
value: 1
},
{
day: 7,
hour: 11,
value: 2
},
{
day: 7,
hour: 12,
value: 4
},
{
day: 7,
hour: 13,
value: 1
},
{
day: 7,
hour: 14,
value: 0
},
{
day: 7,
hour: 15,
value: 0
},
{
day: 7,
hour: 16,
value: 1
},
{
day: 7,
hour: 17,
value: 0
},
{
day: 7,
hour: 18,
value: 0
},
{
day: 7,
hour: 19,
value: 1
},
{
day: 7,
hour: 20,
value: 0
},
{
day: 7,
hour: 21,
value: 0
},
{
day: 7,
hour: 22,
value: 0
},
{
day: 7,
hour: 23,
value: 0
},
{
day: 7,
hour: 24,
value: 0
},
]发布于 2018-07-25 04:27:53
如果您使用d3.scaleBand(),那么您将能够在scale本身中设置填充,然后访问scale.bandwidth以获取条形图的宽度和高度。
由于规模是一个‘序数’规模,您需要提供域中的每个类别(例如天数)。
有关示例,请参阅链接:
https://codepen.io/tomshanley/pen/ejWzYZ?editors=0010#0
代码的相关部分包括:
var dayScale = d3.scaleBand()
.domain(d3.range(7,0,-1))
.range([height, 0])
.padding(0.4);
var dayAxis = d3.axisLeft().ticks(7).scale(dayScale)
svg.append('g').attr('class', 'xAxis').call(dayAxis)
var timeScale = d3.scaleBand()
.domain(d3.range(1,25,1))
.range([0, width])
.padding(0.1)
var timeAxis = d3.axisTop().scale(timeScale).ticks(24)
svg.append('g').attr('class', 'yAxis').call(timeAxis)
svg.selectAll('.squares')
.data(dataset)
.enter()
.append('rect')
.attr('x', d => {
return timeScale(d.hour);
})
.attr('y', d => {
return dayScale(d.day);
})
.attr('width', timeScale.bandwidth())
.attr('height', dayScale.bandwidth())
.style('fill', d => colorScale(d.value))https://stackoverflow.com/questions/51485415
复制相似问题