Javascript 访问d3 v4堆叠条形图的数据属性

Javascript 访问d3 v4堆叠条形图的数据属性,javascript,json,d3.js,dataset,bar-chart,Javascript,Json,D3.js,Dataset,Bar Chart,我一直在使用D3V4创建一个堆叠条形图,但带有JSON文件输入。此问题是过去问题的延续: 我的数据数组由许多对象组成(每个对象都是一个医院,具有诸如男性、女性和类别的计数等值) 基于此,我如何访问数据数组的各个属性并相应地填充它?这意味着当我将鼠标悬停在某个条上时,性别类型、计数、百分比和类别都会发生变化 **编辑:为了更好地理解我的数据结构,我改变了我的帖子。此外,我不认为提供的链接不能解决我的问题,我有。我确实用了那种方法,但它不起作用 **EDIT2:添加了更多我的JavaScript代码

我一直在使用D3V4创建一个堆叠条形图,但带有JSON文件输入。此问题是过去问题的延续:

我的数据数组由许多对象组成(每个对象都是一个医院,具有诸如男性、女性和类别的计数等值)

基于此,我如何访问数据数组的各个属性并相应地填充它?这意味着当我将鼠标悬停在某个条上时,性别类型、计数、百分比和类别都会发生变化

**编辑:为了更好地理解我的数据结构,我改变了我的帖子。此外,我不认为提供的链接不能解决我的问题,我有。我确实用了那种方法,但它不起作用

**EDIT2:添加了更多我的JavaScript代码

数据结构采用JSON格式(对象数组),如下所示:

[{
  "hospitalName": "hospital1",
  "Diseases of the Circulatory System": 1,
  "Diseases of the Digestive System": 1,
  "Diseases of the Nervous System & Sense Organs": 2,
  "Diseases of the Respiratory System": 1,
  "Infectious and Parasitic Diseases": 278,
  "Injury and Poisoning": 9,
  "Mental Disorders": 4,
  "Neoplasms": 4,
  "No Diagnosis Code in Medical Record": 10,
  "Perinatal Period Conditions": 1,              
  "Females": 223,  
  "Males": 88,    
  "Unknown": 0,
  "count": 311
 },
 { 
   "hospitalName": "hospital2",
   "No Diagnosis Code in Medical Record": 1,
   "Females": 0,
   "Males": 1,
   "Unknown": 0,
   "count": 1
 },
 {
   "hospitalName": "hospital3",
   "Neoplasms": 5,
   "Females": 0,
   "Males": 2,
   "Unknown": 3,
   "count": 5
 }]
这是我当前的堆叠条形图

工具提示的输出如下所示:

*我的JavaScript代码:

   var svg = d3.select("svg"),
   margin = { top: 20, right: 20, bottom: 120, left: 40 },
   width = +svg.attr("width") - margin.left - margin.right,
   height = +svg.attr("height") - margin.top - margin.bottom,
   g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");

   var x = d3.scaleBand()
   .rangeRound([0, width])
   .paddingInner(0.15)
   .align(0.1);

   var y = d3.scaleLinear()
   .rangeRound([height, 0]);


   var z = d3.scaleOrdinal()
   .range(["#a95e65", "#5eaaa2", "#6b486b"]);


   d3.json("hospitals2.json", function(error, data) {

    if (error) throw error;

    var newData = {};

    data.forEach(element => {

    var name = element.hospitalName;
    var hospital = newData[name];

    if (!hospital) {
        hospital = { hospitalName: name, Females: 0, Males: 0, Unknown: 0, count: 0 };
        newData[name] = hospital;
    }

    hospital[element.category] = +element.count;
    hospital.Females += +element.Females;
    hospital.Males += +element.Males;
    hospital.Unknown += +element.Unknown;
    hospital.count += +element.count;

    });

    data = [];

    for (const key in newData) {
    if (newData.hasOwnProperty(key)) {
        data.push(newData[key]);
     }
   }

console.log(data);

var columns = d3.keys(data[0]);

var keys = columns.slice(1, 4);

console.log(keys);

data.sort(function(a, b) { return b.total - a.total; });
x.domain(data.map(function(d, i) { return i; }));
y.domain([0, d3.max(data, function(d) { return d.count; })]).nice();
z.domain(keys);

g.append("g")
    .selectAll("g")
    .data(d3.stack().keys(keys)(data))
    .enter().append("g")
    .attr("fill", function(d) { return z(d.key); })
    .selectAll("rect")
    .data(function(d) { return d; })
    .enter().append("rect")
    .attr("class", "bar")
    .attr("x", function(d, i) { return x(i); })
    .attr("y", function(d) { return y(d[1]); })
    .attr("height", function(d) { return y(d[0]) - y(d[1]); })
    .attr("width", x.bandwidth())
    .on("mousemove", function(d) {
        var xPosition = d3.mouse(this)[0] - 60;
        var yPosition = d3.mouse(this)[1] - 60;

        tooltip.attr("transform", "translate(" + xPosition + "," + yPosition + ")");

        tooltip.select(".count").html("Count: " + (d[1] - d[0]) + "<br>")
        tooltip.select(".percent").html("(" + (Math.round((d[1] - d[0]) / d.data.count * 100)) + "%" + ")")



    })
    .on("mouseover", function() {
        tooltip.style("display", "inline");

    })
    .on("mouseout", function() {
        tooltip.style("display", "none");

    });

g.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + height + ")")
    .call(d3.axisBottom(x).tickFormat(function(d, i) { return data[i].MTFID }))
    .selectAll("text")
    .attr("x", -11)
    .attr("y", 7)
    .attr("dy", ".35em")
    .attr("transform", "rotate(290)")
    .style("text-anchor", "end");

g.append("g")
    .attr("class", "y axis")
    .call(d3.axisLeft(y).ticks(null, "s"))
    //.call(d3.axisLeft(y).tickFormat(d => Math.round(d * 100 / d3.max(data, function(d) { return d.count })) + "%"))
    .append("text")
    .attr("x", 2)
    .attr("y", y(y.ticks().pop()) + 0.5)
    .attr("dy", "0.32em")
    .attr("fill", "#000")
    .attr("font-family", "Montserrat, sans-serif")
    .attr("font-size", "13px")
    .attr("text-anchor", "start")
    .text("Population");

var legend = g.append("g")
    .attr("class", "legend")
    .attr("text-anchor", "end")
    .selectAll("g")
    .data(keys.slice().reverse())
    .enter().append("g")
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });

legend.append("rect")
    .attr("x", width - 19)
    .attr("width", 19)
    .attr("height", 19)
    .attr("fill", z);

legend.append("text")
    .attr("x", width - 24)
    .attr("y", 9.5)
    .attr("dy", "0.32em")
    .text(function(d) { return d; });


var tooltip = svg.append("g")
    .attr("class", "tooltip")
    .style("display", "none");


tooltip.append("rect")
    .attr("width", 100)
    .attr("height", 105)
    .attr("fill", "#DCDCDC")

tooltip.append("text")
    .attr("class", "count")
    .attr("x", 50)
    .attr("dy", "1.2em")
    .style("text-anchor", "middle")


tooltip.append("text")
    .attr("class", "percent")
    .attr("x", 50)
    .attr("dy", "2em")
    .style("text-anchor", "middle")

tooltip.append("text")
    .attr("class", "category")


  });
var svg=d3.选择(“svg”),
边距={顶部:20,右侧:20,底部:120,左侧:40},
宽度=+svg.attr(“宽度”)-margin.left-margin.right,
高度=+svg.attr(“高度”)-margin.top-margin.bottom,
g=svg.append(“g”).attr(“transform”、“translate”(+margin.left+)、“+margin.top+”);
var x=d3.scaleBand()
.rangeRound([0,宽度])
.填充器(0.15)
.对齐(0.1);
变量y=d3.scaleLinear()
.rangeRound([高度,0]);
var z=d3.scaleOrdinal()
.范围([“a95e65”、“5eaaa2”、“6b486b”);
d3.json(“hospitals2.json”),函数(错误,数据){
如果(错误)抛出错误;
var newData={};
data.forEach(元素=>{
var name=element.hospitalName;
var医院=新数据[名称];
如果(!医院){
医院={医院名称:姓名,女性:0,男性:0,未知:0,计数:0};
newData[名称]=医院;
}
医院[element.category]=+element.count;
医院。女性+=+元素。女性;
医院。男性+=+元素。男性;
医院。未知+=+元素。未知;
hospital.count+=+element.count;
});
数据=[];
for(新数据中的常量键){
if(newData.hasOwnProperty(键)){
data.push(newData[key]);
}
}
控制台日志(数据);
var columns=d3.keys(数据[0]);
var key=columns.slice(1,4);
控制台日志(键);
sort(函数(a,b){返回b.total-a.total;});
x、 域(data.map(函数(d,i){returni;}));
y、 域([0,d3.max(数据,函数(d){return d.count;})]).nice();
z、 域(密钥);
g、 附加(“g”)
.全选(“g”)
.data(d3.stack().key(key)(数据))
.enter().append(“g”)
.attr(“fill”,函数(d){返回z(d.key);})
.selectAll(“rect”)
.data(函数(d){return d;})
.enter().append(“rect”)
.attr(“类”、“条”)
.attr(“x”,函数(d,i){返回x(i);})
.attr(“y”,函数(d){返回y(d[1]);})
.attr(“height”,函数(d){返回y(d[0])-y(d[1]);})
.attr(“宽度”,x.带宽())
.on(“mousemove”,函数(d){
var xPosition=d3.鼠标(this)[0]-60;
var yPosition=d3.鼠标(this)[1]-60;
attr(“transform”、“translate”(+xPosition+)、“+yPosition+”);
工具提示。选择(“.count”).html(“count:”+(d[1]-d[0])+“
”) 工具提示。选择(“.percent”).html(“+(Math.round((d[1]-d[0])/d.data.count*100))+”%“+”) }) .on(“鼠标悬停”,函数(){ 样式(“显示”、“内联”); }) .on(“mouseout”,函数(){ 样式(“显示”、“无”); }); g、 附加(“g”) .attr(“类”、“x轴”) .attr(“变换”、“平移(0)”、“高度+”) .call(d3.axisBottom(x).tickFormat(函数(d,i){返回数据[i].MTFID})) .selectAll(“文本”) .attr(“x”,-11) .attr(“y”,7) .attr(“dy”,“.35em”) .attr(“变换”、“旋转(290)”) .样式(“文本锚定”、“结束”); g、 附加(“g”) .attr(“类”、“y轴”) .call(d3.axisLeft(y).ticks(null,“s”)) //.call(d3.axisLeft(y).tickFormat(d=>Math.round(d*100/d3.max)(数据,函数(d){return d.count}))+“%”) .append(“文本”) .attr(“x”,2) .attr(“y”,y(y.ticks().pop())+0.5) .attr(“dy”,“0.32em”) .attr(“填充”、“千”) .attr(“字体系列”、“蒙特塞拉特,无衬线”) .attr(“字体大小”,“13px”) .attr(“文本锚定”、“开始”) .文本(“人口”); var图例=g.append(“g”) .attr(“类”、“图例”) .attr(“文本锚定”、“结束”) .全选(“g”) .data(key.slice().reverse()) .enter().append(“g”) .attr(“transform”,函数(d,i){return“translate(0,+i*20+”);}); 图例。追加(“rect”) .attr(“x”,宽度-19) .attr(“宽度”,19) .attr(“高度”,19) .attr(“填充”,z); 图例。追加(“文本”) .attr(“x”,宽度-24) .attr(“y”,9.5) .attr(“dy”,“0.32em”) .text(函数(d){return d;}); var tooltip=svg.append(“g”) .attr(“类”、“工具提示”) .样式(“显示”、“无”); 工具提示。追加(“rect”) .attr(“宽度”,100) .attr(“高度”,105) .attr(“填充”、“DCDC”) 工具提示。追加(“文本”) .attr(“类”、“计数”) .attr(“x”,50) .attr(“dy”,“1.2米”) .style(“文本锚定”、“中间”) 工具提示。追加(“文本”) .attr(“类别”、“百分比”) .attr(“x”,50) .attr(“dy”,“2em”) .style(“文本锚定”、“中间”) 工具提示。追加(“文本”) .attr(“类别”、“类别”) });
好的,我编辑了我的问题以便更好地理解。