【问题标题】:How can i add an image inside nvd3 piechart slices?如何在 nvd3 饼图切片中添加图像?
【发布时间】:2013-12-06 16:05:27
【问题描述】:

我想在 nvd3 饼图切片中添加一个图标。 我想要这个:

有什么帮助吗?

编辑:

饼图的html代码为:

<g class="nv-pieWrap">
<g class="nvd3 nv-wrap nv-pie nv-chart-9221" transform="translate(0,0)">
<g>
<g class="nv-pie" transform="translate(270,145.5)">
<g class="nv-slice" fill="#3b5998" stroke="#3b5998"><path d="M7.127208979246237e-15,-116.4A116.4,116.4 0 0,1 115.55131294501349,-14.030469581719618L72.21957059063342,-8.769043488574761A72.75,72.75 0 0,0 4.454505612028897e-15,-72.75Z"></path></g>
<g class="nv-slice" fill="#326ada" stroke="#326ada"><path d="M115.55131294501349,-14.030469581719618A116.4,116.4 0 1,1 -1.2476559499083328e-13,-116.4L-7.79784968692708e-14,-72.75A72.75,72.75 0 1,0 72.21957059063342,-8.769043488574761Z"></path></g>

</g>
<g class="nv-pieLabels" transform="translate(270,145.5)"></g></g></g></g>

看完这篇How can i add an image in nvd3 piechart legend?

我在我的数据中添加了一个 image_path,并在 js 中添加了这段代码

        var slices = wrap.select('.nv-pie').selectAll('.nv-slice')
                  .data(pie);


     var ae = slices.enter().append('g')
                  .attr('class', 'nv-slice')
                  .on('mouseover', function(d,i){
                    d3.select(this).classed('hover', true);
                    dispatch.elementMouseover({
                        label: getX(d.data),
                        value: getY(d.data),
                        point: d.data,
                        pointIndex: i,
                        pos: [d3.event.pageX, d3.event.pageY],
                        id: id
                    });
                  })
                  .on('mouseout', function(d,i){
                    d3.select(this).classed('hover', false);
                    dispatch.elementMouseout({
                        label: getX(d.data),
                        value: getY(d.data),
                        point: d.data,
                        index: i,
                        id: id
                    });
                  })
                  .on('click', function(d,i) {
                    dispatch.elementClick({
                        label: getX(d.data),
                        value: getY(d.data),
                        point: d.data,
                        index: i,
                        pos: d3.event,
                        id: id
                    });
                    d3.event.stopPropagation();
                  })
                  .on('dblclick', function(d,i) {
                    dispatch.elementDblClick({
                        label: getX(d.data),
                        value: getY(d.data),
                        point: d.data,
                        index: i,
                        pos: d3.event,
                        id: id
                    });
                    d3.event.stopPropagation();
                  });
 /////////////I ADDED THIS APPEND
         ae.append('image')
          .attr('xlink:href', function(d) { return d.image_path} )
          .attr('height',16)
          .attr('width',16)
          .attr('y', '-10')
          .attr('x', '8');
    ///////////////////////////////

 slices
            .attr('fill', function(d,i) { return color(d, i); })
            .attr('stroke', function(d,i) { return color(d, i); });

        var paths = ae.append('path')
            .each(function(d) { this._current = d; });
            //.attr('d', arc);

【问题讨论】:

  • NVD3 并不允许您进行那种级别的自定义,因此对于这样一个简单的事情,在纯 D3 中进行几乎肯定会更容易。您基本上必须在适当的位置附加一个 image 元素。有几个示例说明如何使用文本执行此操作 - 您需要更改的只是元素的类型及其属性。
  • 如果您检查元素并发布结果,我们可以查看是否有可以让您访问这些元素的类或 ID。有了这些,您应该能够附加图像并使用边界框将其居中。
  • @Elijah:这种方法行不通,因为你不能占据边界框的中心——例如对于上图中较大的切片,它将位于整个图表的中心。

标签: javascript d3.js nvd3.js


【解决方案1】:

如果您想破解 nv.d3.js 代码以实现此目的,只需几个步骤即可。

定义数据集中每个元素的图片路径:

var testdata = [
{
  key: "<img src="+"./imgs/facebook.jpg"+">",
  y: 1,
  image_path: "./imgs/facebook.jpg"
},
{
  key: "<img src="+"./imgs/twitter.jpg"+">",
  y: 2,
  image_path: "./imgs/twitter.jpg"
}];

然后用类似这样的东西更新nv.models.pie 代码...

为图片添加锚点:

pieLabels.enter().append("g").classed("nv-label",true)

  ...

  group.append('text')
      .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned
      .style('fill', '#000')

  // Set up the anchor for the image
  group.append('image')
    .attr('height', 20)
    .attr('width', 20)
    .attr('y', '-10')
    .attr('x', '-10');

隐藏文本标签并显示图像:

// Don't insert the label text.  We're using images.
// pieLabels.select(".nv-label text")
//       .style('text-anchor', labelSunbeamLayout ? ((d.startAngle + d.endAngle) / 2 < Math.PI ? 'start' : 'end') : 'middle') //center the text on it's origin or begin/end if orthogonal aligned
//       .text(function(d, i) {
//         var percent = (d.endAngle - d.startAngle) / (2 * Math.PI);
//         var labelTypes = {
//           "key" : getX(d.data),
//           "value": getY(d.data),
//           "percent": d3.format('%')(percent)
//         };
//         return (d.value && percent > labelThreshold) ? labelTypes[labelType] : '';
//       });

// Show the image if the slice is large enough
pieLabels.select(".nv-label image")
  .attr('xlink:href', function(d, i) {
    var percent = (d.endAngle - d.startAngle) / (2 * Math.PI);
    return (d.data.image_path && percent > labelThreshold) ? d.data.image_path : '';
  });

您可能需要根据需要稍微调整数字。

【讨论】:

    猜你喜欢
    • 2018-04-08
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-15
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多