我正在尝试构建一个组合图,即垂直堆栈条和折线图。我已经建立了图表,但我想要在条形图顶部的每个条形图的值。我在单条顶部找到了某些文本代码,但没有找到堆叠条的明确答案。我已经写下了一些可用的代码,并将其注释为 // 我尝试在每个堆栈顶部添加文本的代码 //。但这似乎不起作用。
d3GroupBarChart(datas){
this.showData = datas
let textArray = [];
datas.forEach(element => {
element.stack.forEach(stack => {
textArray.push(stack)
});
});
if (datas === null || datas.length == 0) {
$(".sieir-chart").empty()
$('.sieir-chart').append(`<div class="no-card-data" >
<h5>No Data Available </h5>
</div>`)
return
}
$('.sieir-chart').html('')
var margin = { top: 20, right: 80, bottom: 100, left: 80 },
width = $('.group-bar-chart').width() - margin.left - margin.right,
height = 410 - margin.top - margin.bottom;
var svg: any = d3.select(".sieir-chart")
.append("svg")
.attr("viewBox", `0 0 ${$('.group-bar-chart').width()} 410`)
.attr("preserveAspectRatio", "xMinYMin meet")
var g = svg.append("g")
.attr("height", height)
.attr("transform",
"translate(" + (margin.left) + "," + (20) + ")");
var x: any = d3.scaleBand()
.range([0, width])
.domain(datas.map(function (d) { return d.group; }))
.padding(0.2);
var yMax = Math.max.apply(Math, datas.map(function (o) { return o.maxBarValue; }))
// Add Y axis
var y = d3.scaleLinear()
.domain([0, yMax])
.range([height, 0])
.nice();
var self = this;
var formatyAxis = d3.format('.0f');
g.append("g")
.style('font-weight', 'bold')
.call(d3.axisLeft(y).tickFormat(function (d: any) {
if (d % 1 === 0) {
return d.toLocaleString()
}
else {
return ''
}
}).ticks(5));
var y1Max = Math.max.apply(Math, datas.map(function (o) { return o.percentage; }))
var y1: any = d3.scaleLinear().range([height, 0]).domain([0, y1Max]);
var yAxisRight: any = d3.axisRight(y1).ticks(5)
// //this will make the y axis to the right
g.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (width) + " ,0)")
.style('font-weight', 'bold')
.call(yAxisRight);
// // text label for the y axis
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 0 - (margin.left - 100))
.attr("x", 0 - (height / 2))
.attr("dy", "1em")
.style("text-anchor", "middle")
.style("font-family", "poppins_regular")
.text("Logged User Count");
// text label for the y1 axis
svg.append("text")
.attr("transform", "rotate(-90)")
.attr("y1", 0 - (margin.right - 50))
.attr("x", 0 - (height / 2))
.attr("dy", width + 130)
.style("text-anchor", "middle")
.style("font-family", "poppins_regular")
.text("Duration in min");
g.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
.selectAll(".tick text")
.attr("transform", "translate(-5,7)rotate(-15)")
.style("text-anchor", "middle")
.style("font-size", "11px")
.style('font-weight', 'bold')
.call(this.wrap, x.bandwidth())
var subgroups = ["Total Headcount","Onboarded resource count"];
var groups = d3.map(datas, function (d) { return (d['group']) }).keys();
// Another scale for subgroup position?
var xSubgroup = d3.scaleBand()
.domain(subgroups)
.range([0, x.bandwidth()])
.padding(0.05)
// color palette = one color per subgroup
var color = d3.scaleOrdinal()
.domain(subgroups)
.range(['#006287', '#F68721'])
var self = this;
datas.forEach(data => {
// console.log("data",data);
g.selectAll("mybar")
// Enter in data = loop group per group
.data(datas)
.enter()
.append("g")
.attr("class","bars")
.attr("transform", function (d) { return "translate(" + x(d.group) + ",0)"; })
.selectAll("rect")
.data(function (d) { return subgroups.map(function (key) { return { key: key,
value: d[key] }; }); })
.enter().append("rect")
.attr("x", function (d) { return xSubgroup(d.key); })
.attr("y", function (d) { return y(d.value); })
.attr("width", xSubgroup.bandwidth())
.attr("height", function (d) { return height - y(d.value); })
.attr("fill", function (d) { return color(d.key); })
.append("svg:title")
.text(function (d) {
return `${d['key']}:` + d.value;
})
//code i tried for text on top of each stack
g.selectAll(".text")
.data(data.stack)
.enter().append("text")
.attr("class", "barstext")
.attr("x", function (d) { console.log("d", d); return x(d.name); })
.attr("y", function (d) { return y(d.value); })
.text(function (d) { console.log("text", d); return (d.value); })
// // line chart
var averageline = d3.line()
.x(function (d, i) { return x(d['group']) + x.bandwidth() / 2; })
.y(function (d) { return y1(d['percentage']); })
.curve(d3.curveMonotoneX);
var path = g.append("path")
.attr("class", "line")
.style("fill", "none")
.style("stroke", "#58D68D")
.style("stroke-width", 2)
.attr("d", averageline(datas));
g.selectAll("myCircles")
.data(datas)
.enter()
.append("circle")
.attr("class", "dot")
.style("fill", "white")
.style("stroke", "#58D68D")
.style("stroke-width", 2)
.style('cursor', 'pointer')
.attr("cx", function (d, i) { return x(d['group']) + x.bandwidth() / 2; })
.attr("cy", function (d) { return y1(d['percentage']); })
.attr("r", 3)
.append("svg:title")
.text(function (d) {
return "Percentage: " + d.percentage;
})
})
}
虚拟数据
[
{
"group": "Digital Process Industries",
"Total Headcount": 12,
"Onboarded resource count": 1,
"percentage": 13,
"maxBarValue": 12,
"stack": [
{
"name": "Total Headcount",
"value": 12
},
{
"name": "Onboarded resource count",
"value": 1
}
]
},
{
"group": "Digital Discrete Industries",
"Total Headcount": 6,
"Onboarded resource count": 6,
"percentage": 33,
"maxBarValue": 6,
"stack": [
{
"name": "Total Headcount",
"value": 6
},
{
"name": "Onboarded resource count",
"value": 6
}
]
}]
您与当前的解决方案非常接近。要使其正常工作,您需要做两件主要的事情:
datas.forEeach
),则无需在数据绑定中重新绑定到组偏移量。您应该绑定到单个数据元素(因此绑定到[data]
)。有关代码的工作版本,请参阅此 jsfiddle。我EDITED --
在我更改的所有行之前添加了注释,并解释了我所做的事情。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句