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

我是 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];

    });

}

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



达令说
浏览 78回答 1
1回答

莫回无

不可能将 a 附加text到rect元素上,它们不应该有子元素。您可以只绘制另一个g节点,并使用最后一组条形图中的数据。数据包含您需要的一切 - 他们知道最高柱的值,因此他们知道偏移量,并且他们的属性x中也有数据:d.datavar group = ["field2", "field3"];var mainDiv = "#charts";var mainDivName = "charts";var axisBottom;var axisLeft;var dealsData = [{&nbsp; &nbsp; &nbsp; &nbsp; field1: "company-1",&nbsp; &nbsp; &nbsp; &nbsp; field2: 500.0,&nbsp; &nbsp; &nbsp; &nbsp; field3: 400.0,&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; field1: "company-2",&nbsp; &nbsp; &nbsp; &nbsp; field2: 200.0,&nbsp; &nbsp; &nbsp; &nbsp; field3: 700.0,&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; field1: "company-3",&nbsp; &nbsp; &nbsp; &nbsp; field2: 113.2,&nbsp; &nbsp; &nbsp; &nbsp; field3: 850.0,&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; field1: "company-4",&nbsp; &nbsp; &nbsp; &nbsp; field2: 140.4,&nbsp; &nbsp; &nbsp; &nbsp; field3: 83.0,&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; field1: "company-5",&nbsp; &nbsp; &nbsp; &nbsp; field2: 75.5,&nbsp; &nbsp; &nbsp; &nbsp; field3: 27.5,&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; field1: "company-6",&nbsp; &nbsp; &nbsp; &nbsp; field2: 140.0,&nbsp; &nbsp; &nbsp; &nbsp; field3: 440.0,&nbsp; &nbsp; },&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; field1: "company-6",&nbsp; &nbsp; &nbsp; &nbsp; field2: 79.5,&nbsp; &nbsp; &nbsp; &nbsp; field3: 107.5,&nbsp; &nbsp; },];var layers = d3.stack().keys(group).offset(d3.stackOffsetDiverging)(&nbsp; &nbsp; dealsData);var svg = d3.select("svg"),&nbsp; &nbsp; margin = {&nbsp; &nbsp; &nbsp; &nbsp; top: 20,&nbsp; &nbsp; &nbsp; &nbsp; right: 30,&nbsp; &nbsp; &nbsp; &nbsp; bottom: 50,&nbsp; &nbsp; &nbsp; &nbsp; left: 80,&nbsp; &nbsp; },&nbsp; &nbsp; width = +svg.attr("width"),&nbsp; &nbsp; 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&nbsp; &nbsp; .scaleBand()&nbsp; &nbsp; .rangeRound([height - margin.bottom, margin.top])&nbsp; &nbsp; .padding(0.5);y.domain(&nbsp; &nbsp; dealsData.map(function(d) {&nbsp; &nbsp; &nbsp; &nbsp; return d.field1;&nbsp; &nbsp; }));function stackMin(layers) {&nbsp; &nbsp; return d3.min(layers, function(d) {&nbsp; &nbsp; &nbsp; &nbsp; return d[0];&nbsp; &nbsp; });}function stackMax(layers) {&nbsp; &nbsp; return d3.max(layers, function(d) {&nbsp; &nbsp; &nbsp; &nbsp; return d[1];&nbsp; &nbsp; });}this.axisBottom = d3.axisBottom(x).tickSize(-430);var colors = ["#00FF00", "#FF0000"];var eleX = svg&nbsp; &nbsp; .append("g")&nbsp; &nbsp; .attr("transform", "translate(0," + (height - margin.bottom) + ")")&nbsp; &nbsp; .call(this.axisBottom);eleX&nbsp; &nbsp; .append("text")&nbsp; &nbsp; .attr("x", width / 2)&nbsp; &nbsp; .attr("y", margin.bottom * 1)&nbsp; &nbsp; .attr("dx", "0.32em")&nbsp; &nbsp; .attr("fill", "#000")&nbsp; &nbsp; .attr("font-weight", "bold")&nbsp; &nbsp; .attr("text-anchor", "start")&nbsp; &nbsp; .text(" x- axis");eleX&nbsp; &nbsp; .selectAll("line")&nbsp; &nbsp; .style("stroke-width", "0.6")&nbsp; &nbsp; .style("opacity", "0.25")&nbsp; &nbsp; .style("stroke", "#adadad");eleX&nbsp; &nbsp; .selectAll("path")&nbsp; &nbsp; .style("stroke-width", "1")&nbsp; &nbsp; .style("opacity", "0")&nbsp; &nbsp; .style("stroke", "#adadad");var bw = y.bandwidth;console.log('bw', bw);console.log("bandwidth::", bw);var ele = svg&nbsp; &nbsp; .append("g")&nbsp; &nbsp; .attr("transform", "translate(" + margin.left + ",0)")&nbsp; &nbsp; .call(d3.axisLeft(y));ele&nbsp; &nbsp; .selectAll("text")&nbsp; &nbsp; .attr("text-anchor", "start")&nbsp; &nbsp; .attr("dx", "15px")&nbsp; &nbsp; .attr("dy", y.bandwidth)&nbsp; &nbsp; .style("font", "Source Sans Pro Regular")&nbsp; &nbsp; .style("fill", "#6C6F78");ele&nbsp; &nbsp; .selectAll("rect")&nbsp; &nbsp; .attr("text-anchor", "start")&nbsp; &nbsp; .attr("dx", "288px")&nbsp; &nbsp; .attr("dy", "-15px");ele&nbsp; &nbsp; .append("text")&nbsp; &nbsp; .attr("transform", "rotate(-90)")&nbsp; &nbsp; .attr("x", 0 - height / 2)&nbsp; &nbsp; .attr("y", 60 - margin.left)&nbsp; &nbsp; .attr("dy", "0.32em")&nbsp; &nbsp; .attr("fill", "#000")&nbsp; &nbsp; .attr("font-weight", "bold")&nbsp; &nbsp; .attr("text-anchor", "middle")&nbsp; &nbsp; .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&nbsp; &nbsp; .enter()&nbsp; &nbsp; .append("g")&nbsp; &nbsp; .attr("fill", function(d, i) {&nbsp; &nbsp; &nbsp; &nbsp; return colors[i];&nbsp; &nbsp; });var bars = g&nbsp; &nbsp; .selectAll("rect")&nbsp; &nbsp; .data(function(d) {&nbsp; &nbsp; &nbsp; &nbsp; d.forEach(function(d1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; d1.key = d.key;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return d1;&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; return d;&nbsp; &nbsp; })&nbsp; &nbsp; .enter()&nbsp; &nbsp; .append("rect")&nbsp; &nbsp; .attr("data", function(d) {&nbsp; &nbsp; &nbsp; &nbsp; var data = {};&nbsp; &nbsp; &nbsp; &nbsp; data["key"] = d.key;&nbsp; &nbsp; &nbsp; &nbsp; data["value"] = d.data[d.key];&nbsp; &nbsp; &nbsp; &nbsp; data["name"] = d.data.field1;&nbsp; &nbsp; &nbsp; &nbsp; var total = 0;&nbsp; &nbsp; &nbsp; &nbsp; group.map(function(d1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; total = total + d.data[d1];&nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; data["total"] = total;&nbsp; &nbsp; &nbsp; &nbsp; console.log("tooltip", data);&nbsp; &nbsp; &nbsp; &nbsp; return JSON.stringify(data);&nbsp; &nbsp; })&nbsp; &nbsp; .attr("width", function(d) {&nbsp; &nbsp; &nbsp; &nbsp; return x(d[1]) - x(d[0]);&nbsp; &nbsp; })&nbsp; &nbsp; .attr("x", function(d) {&nbsp; &nbsp; &nbsp; &nbsp; return x(d[0]);&nbsp; &nbsp; })&nbsp; &nbsp; .attr("y", function(d) {&nbsp; &nbsp; &nbsp; &nbsp; return y(d.data.field1);&nbsp; &nbsp; })&nbsp; &nbsp; .attr("height", y.bandwidth)&nbsp; &nbsp; .attr("rx", 2)&nbsp; &nbsp; .attr("ry", 2);svg.append("g")&nbsp; .attr("class", "labels")&nbsp; .selectAll("text")&nbsp; .data(layers[layers.length - 1]) // this has all the information we need&nbsp; .enter()&nbsp; .append("text")&nbsp; .attr("x", function(d) {&nbsp; &nbsp; &nbsp; return x(d[1]) + 10;&nbsp; })&nbsp; .attr("y", function(d) {&nbsp; &nbsp; &nbsp; return y(d.data.field1) + y.bandwidth() / 2;&nbsp; })&nbsp; .attr("dominant-baseline", "central")&nbsp; .text(function(d) {&nbsp; &nbsp; return d.data.field1 + " / " + d.data.field2;&nbsp; });<div id="charts">&nbsp; <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-&nbsp;tip.min.js"></script>请注意,存在一些问题,即条形被绘制在错误的位置或看起来被绘制了两次。这是您的图表中预先存在的问题,现在更加清晰,因为这意味着还绘制了额外的标签。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript