Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/402.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript d3如何在饼图中将图像与切片一起转换_Javascript_D3.js - Fatal编程技术网

Javascript d3如何在饼图中将图像与切片一起转换

Javascript d3如何在饼图中将图像与切片一起转换,javascript,d3.js,Javascript,D3.js,我有一个项目,我画了一个甜甜圈/饼图。图表中的每个切片由一个组组成,该组通常有一个路径(切片)和一个图像 为了转换切片,我使用了常规更新模式来更新切片,并添加了两个attrTween方法来处理切片的转换 为了将图像添加到切片中,我首先将每个切片放入一个组中。然后我向每个组添加一个图像,并使用arc.centroid方法将图像定位在每个切片的中心。这在我第一次在图表中加载时非常有效。但当图表更新时,图像仍像以前一样位于组的中心 我已将d元素和arc.controid方法的输出与d元素一起记录在控制

我有一个项目,我画了一个甜甜圈/饼图。图表中的每个切片由一个组组成,该组通常有一个路径(切片)和一个图像

为了转换切片,我使用了常规更新模式来更新切片,并添加了两个attrTween方法来处理切片的转换

为了将图像添加到切片中,我首先将每个切片放入一个组中。然后我向每个组添加一个图像,并使用
arc.centroid
方法将图像定位在每个切片的中心。这在我第一次在图表中加载时非常有效。但当图表更新时,图像仍像以前一样位于组的中心

我已将
d
元素和
arc.controid
方法的输出与
d
元素一起记录在控制台中。您可以清楚地看到
d
元素的坐标没有改变,这就是图像没有得到更新的新位置的原因。但是我不明白为什么他们仍然得到这个d元素的旧版本,而不是新的更新版本

.append("svg:image")
    .attr("transform", (d, i) => {
      if (i === 1) {
        console.log(d);
        console.log(this.arc.centroid(d));
      }
      var x = this.arc.centroid(d)[0] - image_width / 2;
      var y = this.arc.centroid(d)[1] - image_height / 2;
      return "translate(" + x + "," + y + ")";
    })
这是我正在使用的代码片段。我已经尽力使这段话尽可能简短。但是,为了使此代码段能够处理此特定问题,需要包含所有元素:

var保证金=1;
这个宽度=250;
这个高度=250;
该指数=0;
this.radius=Math.min(this.width,this.height)/2-边距;
this.svg=d3
.select(“.canvas”)
.append(“svg”)
.attr(“宽度”,此为.width)
.attr(“高度”,此.height)
.附加(“g”)
艾特先生(
“转化”,
翻译(“+this.width/2+”,“+this.height/2+”)
);
this.pie=d3
.pie()
.sort(空)
.value(d=>d.value);
此.arc=d3
.arc()
.外层(100)
.内半径(50);
const setSlicesOnDoughnut=(数据)=>{
this.arcs=this.svg.selectAll(“path”).data(this.pie(data[this.index]);
这个是.arcs.join(
输入=>{
进入
.附加(“g”)
.append(“路径”)
.attr(“类”、“弧”)
.attr(“填充”、“206BF3”)
.attr(“笔划”,“2D3546”)
.style(“笔划宽度”、“2px”)
.每个功能(d){
这是。_电流=d;
})
.transition()
.持续时间(1000)
.attrTween(“d”,arcTweenEnter);
},
更新=>{
更新
.transition()
.持续时间(1000)
.attrTween(“d”,arcTweenUpdate);
},
退出=>{
exit.remove();
}
);
}
常量addImagesToSlices=()=>{
var图像_宽度=20;
var图像_高度=20;
this.svg.selectAll(“image”).remove();
这个是.svg
.全选(“g”)
.append(“svg:image”)
.attr(“变换”,(d,i)=>{
如果(i==1){
控制台日志(d);
console.log(这个弧形心(d));
}
var x=此弧形心(d)[0]-图像宽度/2;
var y=此弧形心(d)[1]-图像高度/2;
返回“translate”(“+x+”,“+y+”);
})
.attr(“类别”、“标志”)
.attr(“类”,函数(d){
返回`${d.data.key}-logo`;
})
.attr(“href”,d=>d.data.icon)
.attr(“宽度”,图像宽度)
.attr(“高度”,图像高度)
.attr(“不透明度”,0)
.transition()
.持续时间(1500)
.attr(“不透明度”,1);
}
风险值数据=[
[{
钥匙:“一个”,
价值:20,
图标:“http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png"
},
{
钥匙:“两个”,
数值:30,
图标:“http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png"
},
{
键:“三”,
数值:10,
图标:“http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png"
},
{
键:“四”,
价值:15,
图标:“http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png"
}
],
[{
钥匙:“一个”,
数值:30,
图标:“http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png"
},
{
钥匙:“两个”,
价值:15,
图标:“http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png"
},
{
键:“三”,
价值:20,
图标:“http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png"
},
{
键:“四”,
数值:10,
图标:“http://files.gamebanana.com/img/ico/sprays/4f68c8d10306a.png"
}
]
]
常数arcTweenEnter=(d)=>{
var i=d3.插值(d.端角,d.星形);
返回t=>{
d、 startAngle=i(t);
返回此.arc(d);
};
}
常数arcTweenUpdate=(d,i,n)=>{
var插值=d3.插值(n[i].\u电流,d);
n[i]。_电流=d;
返回t=>{
返回此.arc(插值(t));
};
}
设置许可证甜甜圈(数据);
addImagesToSlices();
const swap=document.querySelector(“.swap”);
swap.addEventListener(“单击”,()=>{
如果(this.index==0)this.index=1;
否则,该指数=0;
设置许可证甜甜圈(数据);
addImagesToSlices();
});
交换

问题在于您从未更新绑定到
g
的数据。让我们看看如何输入和更新楔块:

this.arcs = this.svg.selectAll("path").data(this.pie(data[this.index]));

this.arcs.join(

  enter => {
    enter
      .append("g")
      .append("path")
      ...

  },

  update => {
    update
      .transition()
      ...
  },
选择所有路径并将数据绑定到它们(
selectAll(“路径”)
)。在enter键上附加一个
g
,这意味着
g
和子
路径
一样获得绑定数据。但是,在更新时,由于您只选择了路径,因此您只能将新数据绑定到路径。父级
g
保留原始绑定基准

相反,让我们用selectAll选择父级
g
,并稍微调整一下更新函数以说明这一点:

// select parent g elements instead of paths:
this.arcs = this.svg.selectAll("g").data(this.pie(data[this.index]));

this.arcs.join(

  enter => {
    enter
      .append("g")
      .append("path")
      ...

  },

  update => {
    update
      .select("path") // select the child  path.
      .transition()
      ...
  },
现在,当我们(重新)附加图像时,它们正在使用绑定到其父对象的最新数据
g

var保证金=1;
这个宽度=250;
这个高度=250;
该指数=0;
this.radius=Math.min(this.width,this.height)/2-边距;
this.svg=d3
.select(“.canvas”)
.append(“svg”)
.attr(“宽度”,此为.width)
.attr(“高度”,此.height)
.附加(“g”)
艾特先生(
“转化”,
“翻译(”+