Javascript d3.js如何计算悬停时的杆百分比

Javascript d3.js如何计算悬停时的杆百分比,javascript,d3.js,Javascript,D3.js,我有一个d3图表,我想在悬停时显示一个工具提示,显示条形图部分的标签以及该部分占总条形图的百分比。我最初的想法是计算悬停部分的高度,并计算出该部分的总杆的百分比。我通过将此添加到我的mouseover事件(当您悬停时,我当前正在记录该事件)来实现此目的: 这是正确的工作,但我不知道从这里去哪里。我似乎找不到一种方法来获得整个酒吧的高度(考虑到所有部分),以便我可以创建我的方程式 我该怎么做,还是有更好的方法来获取百分比 风险值数据=[ {月份:“一月”,玩具:16591,游戏:1047,书籍

我有一个d3图表,我想在悬停时显示一个工具提示,显示条形图部分的标签以及该部分占总条形图的百分比。我最初的想法是计算悬停部分的高度,并计算出该部分的总杆的百分比。我通过将此添加到我的
mouseover
事件(当您悬停时,我当前正在记录该事件)来实现此目的:

这是正确的工作,但我不知道从这里去哪里。我似乎找不到一种方法来获得整个酒吧的高度(考虑到所有部分),以便我可以创建我的方程式

我该怎么做,还是有更好的方法来获取百分比


风险值数据=[
{月份:“一月”,玩具:16591,游戏:1047,书籍:0,工艺品:5757},
{月份:“二月”,玩具:42337,游戏:129,书籍:835,工艺品:0},
{月份:“三月”,玩具:3385,游戏:1053,书籍:6260,工艺品:10},
{月份:“四月”,玩具:353,游戏:3724,书籍:4038,工艺品:0}
];
var series=d3.stack()
.钥匙([“玩具”、“游戏”、“书籍”、“工艺品”])
.偏移(d3.堆栈偏移发散)
(数据);
var svg=d3。选择(“svg”),
边距={顶部:20,右侧:30,底部:30,左侧:60},
宽度=+svg.attr(“宽度”),
高度=+svg.attr(“高度”);
var x=d3.scaleBand()
.domain(data.map(函数(d){return d.month;}))
.rangeRound([margin.left,width-margin.right])
.填充(0.1);
变量y=d3.scaleLinear()
.domain([d3.min(series,stackMin),d3.max(series,stackMax)])
.rangeRound([高度-边距.底部,边距.顶部]);
Varz=d3.scaleOrdinal(d3.schemeCategory10);
var colors=['#000'、'#000'、'#000'、'#000'];
svg.append(“g”)
.全选(“g”)
.数据(系列)
.enter().append(“g”)
.attr(“fill”,函数(d){返回z(d.key);})
.selectAll(“rect”)
.data(函数(d){return d;})
.enter().append(“rect”)
.attr(“宽度”,x.带宽)
.attr(“x”,函数(d){返回x(d.data.month);})
.attr(“y”,函数(d){返回y(d[1]);})
.attr(“height”,函数(d){返回y(d[0])-y(d[1]);})
.on(“鼠标悬停”,功能(d){
console.log(d3.select(this.style)(“height”);
var xPos=parseFloat(d3.select(this.attr(“x”));
var yPos=parseFloat(d3.select(this.attr)(“y”);
var height=parseFloat(d3.select(this.attr)(“height”))
d3.选择(此).attr(“笔划”,“蓝色”).attr(“笔划宽度”,0.8);
svg.append(“文本”)
.attr(“x”,xPos)
.attr(“y”,yPos+高度/2)
.attr(“类”、“工具提示”)
//.文本(数学地板(d.y_pct.toFixed(2)*100)+%的“+d.type);
})
svg.append(“g”)
.attr(“变换”、“平移(0)、+y(0)+”)
.call(d3.axisBottom(x));
svg.append(“g”)
.attr(“变换”、“平移”(+margin.left+”,0))
.调用(d3.左(y));
函数stackMin(系列){
返回d3.min(序列,函数(d){返回d[0];});
}
函数stackMax(系列){
返回d3.max(序列,函数(d){返回d[1];});
}

每个矩形的基准包括
数据
属性中该列中的所有条:

基准还包括矩形本身的顶部和底部(起点和终点)值:
d[0]
d[1]

利用这个,我们可以计算出一个百分比:

.on("mouseover", function(d) { 
   var rectHeight = d[1] - d[0]; // The top and bottom vales of the rectangle.
   var columnHeight = d3.sum(d3.keys(d.data),function(k) {
      return +d.data[k]; // The sum of all bar rectangle heights in that column.
  });
  var percentHeight = rectHeight/columnHeight*100;
上面的rect height和column height的单位不是SVG单位,而是数据集的单位,因为我们直接访问数据而不进行缩放

d3.sum将忽略NaN或未定义的值,一元加号运算符将强制字符串为数字,如果不可能,它将返回NaN。当然,如果您有一个month或x属性是一个数字,则需要将其从总和中删除

通过这种方式,我们可以得到如下结果:


风险值数据=[
{月份:“一月”,玩具:16591,游戏:1047,书籍:0,工艺品:5757},
{月份:“二月”,玩具:42337,游戏:129,书籍:835,工艺品:0},
{月份:“三月”,玩具:3385,游戏:1053,书籍:6260,工艺品:10},
{月份:“四月”,玩具:353,游戏:3724,书籍:4038,工艺品:0}
];
var series=d3.stack()
.钥匙([“玩具”、“游戏”、“书籍”、“工艺品”])
.偏移(d3.堆栈偏移发散)
(数据);
var svg=d3。选择(“svg”),
边距={顶部:20,右侧:30,底部:30,左侧:60},
宽度=+svg.attr(“宽度”),
高度=+svg.attr(“高度”);
var x=d3.scaleBand()
.domain(data.map(函数(d){return d.month;}))
.rangeRound([margin.left,width-margin.right])
.填充(0.1);
变量y=d3.scaleLinear()
.domain([d3.min(series,stackMin),d3.max(series,stackMax)])
.rangeRound([高度-边距.底部,边距.顶部]);
Varz=d3.scaleOrdinal(d3.schemeCategory10);
var colors=['#000'、'#000'、'#000'、'#000'];
svg.append(“g”)
.全选(“g”)
.数据(系列)
.enter().append(“g”)
.attr(“fill”,函数(d){返回z(d.key);})
.selectAll(“rect”)
.data(函数(d){return d;})
.enter().append(“rect”)
.attr(“宽度”,x.带宽)
.attr(“x”,函数(d){返回x(d.data.month);})
.attr(“y”,函数(d){返回y(d[1]);})
.attr(“height”,函数(d){返回y(d[0])-y(d[1]);})
.on(“鼠标悬停”,功能(d){
var rectHeight=d[1]-d[0];
var columnHeight=d3.sum(d3.keys(d.data),函数(k){
返回+d.数据[k];
});
console.log(数学圆整(rectHeight/columnHeight*100)+“%”;
})
svg.append(“g”)
.attr(“变换”、“平移(0)、+y(0)+”)
.call(d3.axisBottom(x));
svg.append(“g”)
.attr(“变换”、“平移”(+margin.left+”,0))
.调用(d3.左(y));
函数stackMin(系列){
返回d3.min(序列,函数(d){返回d[0];});
}
函数stackMax(系列){
返回d3.max(序列,函数(d){返回d[1];});
}
.on("mouseover", function(d) { 
   var rectHeight = d[1] - d[0]; // The top and bottom vales of the rectangle.
   var columnHeight = d3.sum(d3.keys(d.data),function(k) {
      return +d.data[k]; // The sum of all bar rectangle heights in that column.
  });
  var percentHeight = rectHeight/columnHeight*100;