我正在嘗試構建一個組合圖,即垂直堆疊條和折線圖。我已經建立了圖表,但我想要在條形圖頂部的每個條形圖的值。我在單條頂部找到了某些文本代碼,但沒有找到堆疊條的明確答案。我已經寫下了一些可用的代碼,并將其注釋為 // 我嘗試在每個堆疊頂部添加文本的代碼 //。但這似乎不起作用。

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 >
<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
}
]
}]
uj5u.com熱心網友回復:
您與當前的解決方案非常接近。要使其正常作業,您需要做兩件主要的事情:
- 如果您已經在回圈資料 (
datas.forEeach),則無需在資料系結中重新系結到組偏移量。您應該系結到單個資料元素(因此系結到[data])。 - 將您從資料元素創建的組設定為變數,并將條形的矩形和標簽的文本附加到該組而不是 svg。這樣做的原因是它已經為組偏移了(通過轉換呼叫),所以你只需要擔心子組 x 的比例。
有關代碼的作業版本,請參閱此 jsfiddle。我EDITED --在我更改的所有行之前添加了注釋,并解釋了我所做的事情。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/326028.html
標籤:javascript 查询 d3.js
下一篇:在D3分組條形圖中自定義網格線
