xAxis 刻度的 D3 组标签
D3 Group label for xAxis ticks
我有一个类似的数据集:
[
{
date: '2019-01-01',
value: 100,
group: 1
},
{
date: '2019-01-02',
value: 200,
group: 1
},
{
date: '2019-01-03',
value: 200,
group: 2
},
{
date: '2019-01-04',
value: 200,
group: 3
},
{
date: '2019-01-05',
value: 100,
group: 3
},
{
date: '2019-01-06',
value: 250,
group: 3
}
]
我用 yAxis - value
和 xAxis - date
.
创建了一个线性图表
如何通过 group
字段值为 xAxis 实现附加标签,就像我在图片上显示的那样?
这个问题可能对您有帮助:
但是如果你只需要显示标签而不是按组显示颜色,那么你真正需要做的就是计算每个组中值的数量:
// first, group the data
var groupedData = d3.nest()
.key(function(d) { return d.group; })
.rollup(function(v) { return v.length; })
.entries(data)
// then, get cumulative length of each group
var groupedData = groupedData.map((d, i) => {
const prev = nestedData[(i - 1)]
const cumsum = prev ? d.value + prev.cumsum : d.value
d.cumsum = cumsum
return d
})
此代码将数据转换成如下形式:
[
{
"key": 1,
"values": 2,
"cumsum": 2
},
{
"key": 2,
"values": 1,
"cumsum": 3
},
{
"key": 3,
"values": 3,
"cumsum": 6
}
]
现在您需要做的就是将组附加到图表标签下方
const svg = //your svg selector here
const g = svg.append("g")
.attr("class", "group-labels")
.attr("x", 0)
.attr("y", height + 30) //adjust this so that the group labels are below your labels
g.selectAll(".group-label")
.data(groupedData)
.enter()
.append("text")
.attr("class", "group-label")
.attr("x", function(d, i) { return xScale.bandwidth() * d.cumsum - xScale.bandwidth() * d.value / 2 })
.attr("y", 0)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "hanging")
如果您使用 scaleTime
创建这个,您需要在日期中添加时间,例如 scaleLinear
和 scaleBand
,scaleTime
需要准确的值来固定正确的坐标,但有些人忘了日期也需要时间。
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<svg id="test" width="500" height="400"></svg>
</body>
</html>
<script>
var data = [
{
date: '2019-01-01',
value: 100,
group: 1
},
{
date: '2019-01-02',
value: 200,
group: 1
},
{
date: '2019-01-03',
value: 200,
group: 2
},
{
date: '2019-01-04',
value: 200,
group: 3
},
{
date: '2019-01-05',
value: 100,
group: 3
},
{
date: '2019-01-06',
value: 250,
group: 3
}
]
// first, group the data
var groupedData = d3.nest()
.key(function(d) { return d.group; })
.rollup(function(v) { return {
count: v.length,
lastDate: v[v.length-1].date + ' 12:00:00'
}; })
.entries(data)
//console.log(groupedData)
// then, get cumulative length of each group
var groupedData = groupedData.map((d, i) => {
const prev = groupedData[(i - 1)]
const cumsum = prev ? d.value.count + prev.cumsum : d.value.count
d.cumsum = cumsum
return d
})
const svg = d3.select('svg')
var width = 500
var xscaleTime = d3.scaleTime()
.domain([new Date('2019-01-01'), new Date('2019-01-06')])
.range([0,500]).nice()
var bandwidth = (xscaleTime(new Date(groupedData[1].value.lastDate))
- xscaleTime(new Date(groupedData[0].value.lastDate)))
var padding = 20
const b = svg.append("g")
const t = b.append("g").call( d3.axisBottom().scale(xscaleTime))
const g = b.append("g")
.attr("class", "group-labels")
.attr("y", 30) //adjust this so that the group labels are below your labels
g.selectAll(".group-label")
.data(groupedData)
.enter()
.append("text")
.attr("class", "group-label")
.attr("x", function(d, i) {
return xscaleTime(new Date (d.value.lastDate)) - bandwidth *((d.value.count-1)/2)
})
.attr("y", 50)
.attr("text-anchor", "middle")
.text(function(d,i){
return 'is Group ' + d.key
})
</script>
根据@Cathy 的回答,(请阅读她为你指出的好例子的回答)我为你编辑了一些,你可以通过编辑数据(获取最后日期和第一个日期)来制作她提供的示例组)并与 this
一起玩
我有一个类似的数据集:
[
{
date: '2019-01-01',
value: 100,
group: 1
},
{
date: '2019-01-02',
value: 200,
group: 1
},
{
date: '2019-01-03',
value: 200,
group: 2
},
{
date: '2019-01-04',
value: 200,
group: 3
},
{
date: '2019-01-05',
value: 100,
group: 3
},
{
date: '2019-01-06',
value: 250,
group: 3
}
]
我用 yAxis - value
和 xAxis - date
.
如何通过 group
字段值为 xAxis 实现附加标签,就像我在图片上显示的那样?
这个问题可能对您有帮助:
但是如果你只需要显示标签而不是按组显示颜色,那么你真正需要做的就是计算每个组中值的数量:
// first, group the data
var groupedData = d3.nest()
.key(function(d) { return d.group; })
.rollup(function(v) { return v.length; })
.entries(data)
// then, get cumulative length of each group
var groupedData = groupedData.map((d, i) => {
const prev = nestedData[(i - 1)]
const cumsum = prev ? d.value + prev.cumsum : d.value
d.cumsum = cumsum
return d
})
此代码将数据转换成如下形式:
[
{
"key": 1,
"values": 2,
"cumsum": 2
},
{
"key": 2,
"values": 1,
"cumsum": 3
},
{
"key": 3,
"values": 3,
"cumsum": 6
}
]
现在您需要做的就是将组附加到图表标签下方
const svg = //your svg selector here
const g = svg.append("g")
.attr("class", "group-labels")
.attr("x", 0)
.attr("y", height + 30) //adjust this so that the group labels are below your labels
g.selectAll(".group-label")
.data(groupedData)
.enter()
.append("text")
.attr("class", "group-label")
.attr("x", function(d, i) { return xScale.bandwidth() * d.cumsum - xScale.bandwidth() * d.value / 2 })
.attr("y", 0)
.attr("text-anchor", "middle")
.attr("dominant-baseline", "hanging")
如果您使用 scaleTime
创建这个,您需要在日期中添加时间,例如 scaleLinear
和 scaleBand
,scaleTime
需要准确的值来固定正确的坐标,但有些人忘了日期也需要时间。
<!DOCTYPE html>
<html>
<head>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.min.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<svg id="test" width="500" height="400"></svg>
</body>
</html>
<script>
var data = [
{
date: '2019-01-01',
value: 100,
group: 1
},
{
date: '2019-01-02',
value: 200,
group: 1
},
{
date: '2019-01-03',
value: 200,
group: 2
},
{
date: '2019-01-04',
value: 200,
group: 3
},
{
date: '2019-01-05',
value: 100,
group: 3
},
{
date: '2019-01-06',
value: 250,
group: 3
}
]
// first, group the data
var groupedData = d3.nest()
.key(function(d) { return d.group; })
.rollup(function(v) { return {
count: v.length,
lastDate: v[v.length-1].date + ' 12:00:00'
}; })
.entries(data)
//console.log(groupedData)
// then, get cumulative length of each group
var groupedData = groupedData.map((d, i) => {
const prev = groupedData[(i - 1)]
const cumsum = prev ? d.value.count + prev.cumsum : d.value.count
d.cumsum = cumsum
return d
})
const svg = d3.select('svg')
var width = 500
var xscaleTime = d3.scaleTime()
.domain([new Date('2019-01-01'), new Date('2019-01-06')])
.range([0,500]).nice()
var bandwidth = (xscaleTime(new Date(groupedData[1].value.lastDate))
- xscaleTime(new Date(groupedData[0].value.lastDate)))
var padding = 20
const b = svg.append("g")
const t = b.append("g").call( d3.axisBottom().scale(xscaleTime))
const g = b.append("g")
.attr("class", "group-labels")
.attr("y", 30) //adjust this so that the group labels are below your labels
g.selectAll(".group-label")
.data(groupedData)
.enter()
.append("text")
.attr("class", "group-label")
.attr("x", function(d, i) {
return xscaleTime(new Date (d.value.lastDate)) - bandwidth *((d.value.count-1)/2)
})
.attr("y", 50)
.attr("text-anchor", "middle")
.text(function(d,i){
return 'is Group ' + d.key
})
</script>
根据@Cathy 的回答,(请阅读她为你指出的好例子的回答)我为你编辑了一些,你可以通过编辑数据(获取最后日期和第一个日期)来制作她提供的示例组)并与 this
一起玩