在 C3/D3 中修改圆环图切片

Modify Donut Chart Slices in C3/D3

我使用 c3.js 创建了一个简单的圆环图。这是 FIDDLE.

如果将鼠标悬停在一片甜甜圈上,它会突出来。我想知道是否可以让切片默认突出而不悬停。

例如,我希望切片 A、切片 B 和 C 默认突出显示 我该怎么做?

这是我的代码

var currentSlice;

var chart = c3.generate({
    data: {
        x: 'x',
        columns: [
            ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'],
            ['A', 30, 200, 100, 400, 150, 250],
            ['B', 130, 100, 140, 200, 150, 50],
            ['C', 50, 100, 130, 240, 200, 150],
            ['D', 130, 100, 140, 200, 150, 50],
            ['E', 130, 150, 200, 300, 200, 100]
        ],
        type: 'donut',
        onclick: function (e) {

        },
        onmouseover: function (d, i) {
            if(currentSlice !== void 0) {
                'currentSlice'.attr("transform","scale(1)")
            }

            currentSlice = d3.select(i).attr("transform", "scale(1.1)");


        },
        onmouseout: function (d, i) {

        }
    },
    axis: {
        x: {
            type: 'timeseries',
            tick: {
                format: '%Y-%m-%d',
                centered: true,
                position: 'inner-right'
            }
        }
    },
    bindto: '#dash',
    bar: {
        width: {
            ratio: 0.5 // this makes bar width 50% of length between ticks
        }

    },
    pie: {
        expand: true,
    },
    tooltip: {
        grouped: false,
        contents: function (data, defaultTitleFormat, defaultValueFormat, color) {
            //  console.log("Containt");
            // console.log(data, defaultTitleFormat, defaultValueFormat, color);
            return "<p style='border:1px solid red;'>" + data[0].value + "</p>";

        }
    }
});

图表呈现后,您可以使用 setTimeout() 缩放特定切片。这是一种方法:

setTimeout( function() {
  d3.selectAll('.c3-arc-A, .c3-arc-B, .c3-arc-C').attr("transform", "scale(1.2)");       
}, 5);

在您的 c3.generate() 电话之后拨打此电话。

c3js 有两个选项,但都需要使用 'setTimeout' 进行一些修改,以强制我们的默认缩放发生 渲染和动画发生之后。

  1. onrendered 函数可用于在用于初始化图表的 c3config 对象中进行设置。此函数在触发重绘之后触发,但 视觉渲染发生在 DOM 之前。但是,有一个 hack 可以使用 setTimeout,因为它会创建一个单独的调用堆栈,该调用堆栈将在 之后执行 当前调用堆栈,在 c3 中恰好包括重绘图形。 (explanation of setTimeout to force logic to run after current callstack executes)

  2. load 函数公开了一个 done 回调,在 元素渲染到 DOM 之后触发 但是 动画结束之前。因此,如果将初始比例变换设置为完成,如果加载触发的动画正在使用比例变换(加载饼图似乎是这样做的),那么动画的最后一个关键帧将把修改后的比例覆盖回 scale(1).但是,我们可以类似地使用 setTimeout 到 运行 我们的代码 after 当前调用堆栈(包括动画)执行。

在探索这个过程中,我创建了一个通用形式的 rby 答案,并且我提供了两个替代路径来通过 c3 中公开的 onrendereddone 函数设置默认比例。 (Fiddle):

var selected = ['A', 'B', 'C'];
var _ARC = '.c3-arc';
var _SCALING = '1.1';

function getCurrentlySelected() {
  var _PREFIX = _ARC + '-';
  return d3.selectAll(_PREFIX + selected.join(', ' + _PREFIX));
}

在 c3config 对象中并且 onrendered 通过初始化:

var chart = c3.generate({
    bindto: '#chart',
    data: { ... },
    onrendered: function() {
        setTimeout(function() {
          if (selected.length > 0) {
            getCurrentlySelected().attr('transform', 'scale(' + _SCALING + ')');
          }
        }); // Notice we don't need a delay, just taking advantage to force our logic to happen after current callstack is executed
    }
});

也可以在初始化后将 loaddone 一起使用:

chart.load({
  columns: [
    ['A', 30, 200, 100, 400, 150, 250],
    ['B', 130, 100, 140, 200, 150, 50],
    ['C', 50, 100, 130, 240, 200, 150],
    ['D', 130, 100, 140, 200, 150, 50],
    ['E', 130, 150, 200, 300, 200, 100]
  ],
  done: function() {
    setTimeout(function() {
      if (selected.length > 0) {
        getCurrentlySelected().attr('transform', 'scale(' + _SCALING + ')');
      }
    }) // Notice we don't need a delay, just taking advantage to force our logic to happen after current callstack is executed
  }
});