D3.js 如何在dc.js piechart切片中添加图标而不是文本

D3.js 如何在dc.js piechart切片中添加图标而不是文本,d3.js,dc.js,crossfilter,D3.js,Dc.js,Crossfilter,我已经在dc.js工作了一年了。最近,我的任务是实现饼图,如下所示: 我想用适当的图像替换饼图切片中的文本标签 我看到它在纯d3.js中实现。有人能帮我把实现翻译成dc.js吗 我拿起相机,加了几个我发现的气象卫星 (当然,这些图标只是一个例子,我无权在商业上使用它们) 图标存储在单独的元素中。要呈现图标,只需选择其根元素并将其内容复制到您在图表中创建的另一个: g.append(“g”) .attr(“transform”,d=>`平移(${arc.centroid(d)})比例(0.25

我已经在dc.js工作了一年了。最近,我的任务是实现饼图,如下所示:

我想用适当的图像替换饼图切片中的文本标签

我看到它在纯d3.js中实现。有人能帮我把实现翻译成dc.js吗

我拿起相机,加了几个我发现的气象卫星

(当然,这些图标只是一个例子,我无权在商业上使用它们)

图标存储在单独的
元素中。要呈现图标,只需选择其根
元素并将其内容复制到您在图表中创建的另一个

g.append(“g”)
.attr(“transform”,d=>`平移(${arc.centroid(d)})比例(0.25)`)
.append('g')
.attr('transform','translate(-256,-256)//原始图标为256 x 256
.html(d=>d3.select(`meteo icon-${…d…}>g`的某些属性).html()
该代码仅用于演示目的,您需要根据需要对其进行修改

请参见以下代码段中的结果:

var-width=550,
高度=550,
半径=250,
颜色=d3.scale.ordinal()
.range(['#336699'、'#336699'、'#ACD1E9'、'#ACD1E9'、'#ACD1E9']);
var图像_宽度=40,
图像高度=40;
变量数据=[
{
标签:“测试”,
图像:“http://placeimg.com/40/40/any",
价值:50
},
{   
标签:“,
图像:“http://placeimg.com/42/42/any",
价值:50
},
{   
标签:“乔纳森”,
图像:“http://placeimg.com/44/44/any",
价值:50
},
{   
标签:“洛伦佐”,
图像:“http://placeimg.com/46/46/any",
价值:50
},
{   
标签:“希拉里”,
图像:“http://placeimg.com/38/38/any",
价值:50
}
]
var pie=d3.layout.pie()
.价值(功能(d){
返回d值;
})
var arc=d3.svg.arc()
.外层(250)
.内半径(100)
var svg=d3。选择('body')。追加('svg'))
.attr('width',width)
.attr('height',height)
.append('g')
.attr('transform'、'translate(+(宽度-半径)+'、'+(高度-半径)+');
var g=svg.selectAll(“.arc”)
.数据(pie(piedata))
.enter().append(“g”)
.attr(“类”、“弧”);
g、 附加(“路径”)
.attr(“d”,弧)
.style(“填充”,函数(d,i){返回颜色(i);});
g、 附加(“g”)
.attr(“transform”,d=>`平移(${arc.centroid(d)})比例(0.25)`)
.append('g')
.attr('transform','translate(-256,-256'))
.html(()=>d3.select(`meteo icon-${Math.random()<0.5?1:2}>g`).html()
.selectAll('路径')
.样式(“填充”、“橙色”);
路径{
冲程:#fff;
填充规则:偶数奇数;
}
正文{
字体系列:Arial,无衬线;
字体大小:12px;
}
.meteo图标{
显示:无;
}

首先,我为一个不完整的例子道歉,但我没有时间了,我认为这说明了原则

  • 我同意@MichaelRovinsky关于SVG图标比图像更好的观点,但我找不到适合本例的SVG图标CDN,我认为原理完全相同,因为您也可以将SVG嵌入为
    image

  • 为此,使用placeimg.com会导致奇怪的结果,因为相同的URL在读取两次时会产生不同的结果,因此,例如,两个切片可能以相同的图像结束,并且在图表重画时图像会发生变化

  • 幸运的是,这两个都不是定制dc.js的重点

    向dc.js饼图切片添加内容 如果dc.js使用svg
    g
    group元素来放入文本,则会出现这种情况。然后我们可以加上它,位置就正确了

    相反,我们必须添加
    图像
    元素,并从饼图标签读取相应的数据以获得位置:

      chart.on('pretransition', chart => {
        let labelg = chart.select('g.pie-label-group');
        let data = labelg.selectAll('text.pie-label').data();
        console.log('data', data);
    
    然后我们可以在同一层/g中添加
    image
    元素:

        let pieImage = labelg.selectAll('image.pie-image');
        let arcs = chart._buildArcs();
        pieImage.data(data)
          .join(
            enter => enter.append('image')
                        .attr('class', 'pie-image')
                        .attr('x', -19) 
                        .attr('y', -19))
           .attr('href', d => images[d.data.key === 'Others' ? 'Others' : d.data.key.slice(4)])
           .attr('transform', d => chart._labelPosition(d, arcs));
      });
    
    请注意,只需要设置一次(按enter键)的属性位于联接调用内部,而每次重画(按更新键)时需要设置的属性位于联接调用外部

    x
    y
    是图像大小的负一半,用于使图像居中

    我使用了一个对象来存储URL,但是你可以使用任何东西

    限度
    与饼图的任何自定义一样,这并不能很好地解释动画。图像将在动画完成之前移动。如果你介意的话,我想几年前我写了一个答案,正确地处理了这个问题。我可能可以把它挖出来,但它相当复杂,我觉得不值得。

    图像不是一个好的选择。您可以使用SVG图标(这里是SVG图标集的一个示例:)-只需从图标集中选择一个合适的
    ,而不是
    ,谢谢@MichaelRovinsky,我会尝试一下……但如果您不介意,可以与我分享我可以使用的一小段代码。提前感谢您的详细解释,我非常感谢您的详细解释,但是我正在寻找与dc.js相关的实现,这就是为什么我分享了一些纯d3.js fiddle解决方案,以帮助人们将实现该解决方案的特定代码段翻译为dc.js代码。我不是在寻找整个实现,而是如何使用dc在piechart切片上放置图像或svg图标。jsI不熟悉您提到的库,但如果有其他适合您的解决方案,请使用它。如果我的答案足够好,我会感谢你把它标记为正确。谢谢你的努力和时间。希望其他了解dc.js的人能从你的答案中选择它。
        let pieImage = labelg.selectAll('image.pie-image');
        let arcs = chart._buildArcs();
        pieImage.data(data)
          .join(
            enter => enter.append('image')
                        .attr('class', 'pie-image')
                        .attr('x', -19) 
                        .attr('y', -19))
           .attr('href', d => images[d.data.key === 'Others' ? 'Others' : d.data.key.slice(4)])
           .attr('transform', d => chart._labelPosition(d, arcs));
      });