如何在水平堆叠条形图中显示条形值



我是D3的新手,开发了一个水平堆叠条形图,但在条形图的右角显示条形值时遇到了问题。

var group = ["field2", "field3"];
var mainDiv = "#charts";
var mainDivName = "charts";
var axisBottom;
var axisLeft;
var dealsData = [{
field1: "company-1",
field2: 500.0,
field3: 400.0,
},
{
field1: "company-2",
field2: 200.0,
field3: 700.0,
},
{
field1: "company-3",
field2: 113.2,
field3: 850.0,
},
{
field1: "company-4",
field2: 140.4,
field3: 83.0,
},
{
field1: "company-5",
field2: 75.5,
field3: 27.5,
},
{
field1: "company-6",
field2: 140.0,
field3: 440.0,
},
{
field1: "company-6",
field2: 79.5,
field3: 107.5,
},
];
var layers = d3.stack().keys(group).offset(d3.stackOffsetDiverging)(
dealsData
);
var svg = d3.select("svg"),
margin = {
top: 20,
right: 30,
bottom: 50,
left: 80,
},
width = +svg.attr("width"),
height = +svg.attr("height");
var x = d3.scaleLinear().rangeRound([margin.left, width - margin.right]);
x.domain([d3.min(layers, stackMin), d3.max(layers, stackMax)]);
var y = d3
.scaleBand()
.rangeRound([height - margin.bottom, margin.top])
.padding(0.5);
y.domain(
dealsData.map(function(d) {
return d.field1;
})
);
function stackMin(layers) {
return d3.min(layers, function(d) {
return d[0];
});
}
function stackMax(layers) {
return d3.max(layers, function(d) {
return d[1];
});
}
this.axisBottom = d3.axisBottom(x).tickSize(-430);
var colors = ["#00FF00", "#FF0000"];
var eleX = svg
.append("g")
.attr("transform", "translate(0," + (height - margin.bottom) + ")")
.call(this.axisBottom);
eleX
.append("text")
.attr("x", width / 2)
.attr("y", margin.bottom * 1)
.attr("dx", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
.text(" x- axis");
eleX
.selectAll("line")
.style("stroke-width", "0.6")
.style("opacity", "0.25")
.style("stroke", "#adadad");
eleX
.selectAll("path")
.style("stroke-width", "1")
.style("opacity", "0")
.style("stroke", "#adadad");
var bw = y.bandwidth;
console.log('bw', bw);
console.log("bandwidth::", bw);
var ele = svg
.append("g")
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y));
ele
.selectAll("text")
.attr("text-anchor", "start")
.attr("dx", "15px")
.attr("dy", y.bandwidth)
.style("font", "Source Sans Pro Regular")
.style("fill", "#6C6F78");
ele
.selectAll("rect")
.attr("text-anchor", "start")
.attr("dx", "288px")
.attr("dy", "-15px");
ele
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", 0 - height / 2)
.attr("y", 60 - margin.left)
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "middle")
.text(" y-axis");
ele.selectAll("line").style("stroke-width", "1").style("opacity", "1");
//.style('stroke-dasharray', '2,2');
ele.selectAll("path").attr("opacity", "0");
var maing = svg.append("g").selectAll("g").data(layers);
var g = maing
.enter()
.append("g")
.attr("fill", function(d, i) {
return colors[i];
});
var bars = g
.selectAll("rect")
.data(function(d) {
d.forEach(function(d1) {
d1.key = d.key;
return d1;
});
return d;
})
.enter()
.append("rect")
.attr("data", function(d) {
var data = {};
data["key"] = d.key;
data["value"] = d.data[d.key];
data["name"] = d.data.field1;
var total = 0;
group.map(function(d1) {
total = total + d.data[d1];
});
data["total"] = total;
console.log("tooltip", data);
return JSON.stringify(data);
})
.attr("width", function(d) {
return x(d[1]) - x(d[0]);
})
.attr("x", function(d) {
return x(d[0]);
})
.attr("y", function(d) {
return y(d.data.field1);
})
.attr("height", y.bandwidth)
.attr("rx", 2)
.attr("ry", 2);
bars.append("text")
.attr("class", "label")
.attr("x", function(d) {
return x(d.data.field2) + 3;
})
.text(function(d) {
console.log("bars data : " + d.data.field2 + "/" + d.data.field3)
return d.data.field2 + "/" + d.data.field3;
});
<div id="charts">
<svg width="710" height="500"></svg>
</div>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3- 
tip.min.js"></script>

假设公司1有数据500.0400.0,那么我们需要在栏的末尾显示500/400。未显示的条形图值,如何在条形图的右角显示相应的渲染条形图值。

不能将text附加到rect元素,它们不应该有子元素。相反,您可以只绘制另一个g节点,并使用最后一组条形图中的数据。数据包含您需要的一切-他们知道最高条的x值,所以他们知道偏移量,而且他们的d.data属性中也有数据:

var group = ["field2", "field3"];
var mainDiv = "#charts";
var mainDivName = "charts";
var axisBottom;
var axisLeft;
var dealsData = [{
field1: "company-1",
field2: 500.0,
field3: 400.0,
},
{
field1: "company-2",
field2: 200.0,
field3: 700.0,
},
{
field1: "company-3",
field2: 113.2,
field3: 850.0,
},
{
field1: "company-4",
field2: 140.4,
field3: 83.0,
},
{
field1: "company-5",
field2: 75.5,
field3: 27.5,
},
{
field1: "company-6",
field2: 140.0,
field3: 440.0,
},
{
field1: "company-6",
field2: 79.5,
field3: 107.5,
},
];
var layers = d3.stack().keys(group).offset(d3.stackOffsetDiverging)(
dealsData
);
var svg = d3.select("svg"),
margin = {
top: 20,
right: 30,
bottom: 50,
left: 80,
},
width = +svg.attr("width"),
height = +svg.attr("height");
var x = d3.scaleLinear().rangeRound([margin.left, width - margin.right]);
x.domain([d3.min(layers, stackMin), d3.max(layers, stackMax)]);
var y = d3
.scaleBand()
.rangeRound([height - margin.bottom, margin.top])
.padding(0.5);
y.domain(
dealsData.map(function(d) {
return d.field1;
})
);
function stackMin(layers) {
return d3.min(layers, function(d) {
return d[0];
});
}
function stackMax(layers) {
return d3.max(layers, function(d) {
return d[1];
});
}
this.axisBottom = d3.axisBottom(x).tickSize(-430);
var colors = ["#00FF00", "#FF0000"];
var eleX = svg
.append("g")
.attr("transform", "translate(0," + (height - margin.bottom) + ")")
.call(this.axisBottom);
eleX
.append("text")
.attr("x", width / 2)
.attr("y", margin.bottom * 1)
.attr("dx", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
.text(" x- axis");
eleX
.selectAll("line")
.style("stroke-width", "0.6")
.style("opacity", "0.25")
.style("stroke", "#adadad");
eleX
.selectAll("path")
.style("stroke-width", "1")
.style("opacity", "0")
.style("stroke", "#adadad");
var bw = y.bandwidth;
console.log('bw', bw);
console.log("bandwidth::", bw);
var ele = svg
.append("g")
.attr("transform", "translate(" + margin.left + ",0)")
.call(d3.axisLeft(y));
ele
.selectAll("text")
.attr("text-anchor", "start")
.attr("dx", "15px")
.attr("dy", y.bandwidth)
.style("font", "Source Sans Pro Regular")
.style("fill", "#6C6F78");
ele
.selectAll("rect")
.attr("text-anchor", "start")
.attr("dx", "288px")
.attr("dy", "-15px");
ele
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", 0 - height / 2)
.attr("y", 60 - margin.left)
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "middle")
.text(" y-axis");
ele.selectAll("line").style("stroke-width", "1").style("opacity", "1");
//.style('stroke-dasharray', '2,2');
ele.selectAll("path").attr("opacity", "0");
var maing = svg.append("g").selectAll("g").data(layers);
var g = maing
.enter()
.append("g")
.attr("fill", function(d, i) {
return colors[i];
});
var bars = g
.selectAll("rect")
.data(function(d) {
d.forEach(function(d1) {
d1.key = d.key;
return d1;
});
return d;
})
.enter()
.append("rect")
.attr("data", function(d) {
var data = {};
data["key"] = d.key;
data["value"] = d.data[d.key];
data["name"] = d.data.field1;
var total = 0;
group.map(function(d1) {
total = total + d.data[d1];
});
data["total"] = total;
console.log("tooltip", data);
return JSON.stringify(data);
})
.attr("width", function(d) {
return x(d[1]) - x(d[0]);
})
.attr("x", function(d) {
return x(d[0]);
})
.attr("y", function(d) {
return y(d.data.field1);
})
.attr("height", y.bandwidth)
.attr("rx", 2)
.attr("ry", 2);
svg.append("g")
.attr("class", "labels")
.selectAll("text")
.data(layers[layers.length - 1]) // this has all the information we need
.enter()
.append("text")
.attr("x", function(d) {
return x(d[1]) + 10;
})
.attr("y", function(d) {
return y(d.data.field1) + y.bandwidth() / 2;
})
.attr("dominant-baseline", "central")
.text(function(d) {
return d.data.field1 + " / " + d.data.field2;
});
<div id="charts">
<svg width="710" height="500"></svg>
</div>
<script src="https://code.jquery.com/jquery-latest.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3- 
tip.min.js"></script>

请注意,在错误的位置绘制条形图或似乎绘制了两次条形图都会出现一些问题。这是你的图表中预先存在的问题,现在更清楚了,因为这意味着还画了一个额外的标签。

最新更新