Javascript Highcharts多深度3d饼图

Javascript Highcharts多深度3d饼图,javascript,svg,highcharts,Javascript,Svg,Highcharts,因此,我希望创建一个3d饼图(在Highcharts中),其中每个切片的深度由点的值决定。这个问题应该能让你很好地理解我的意图 目前Highcharts只支持系列级别的深度参数,因此我的第一个想法是制作多个系列,如下所示: 1: Highcharts.chart('container'{ 图表:{ 键入“pie”, 选项3D:{ 启用:对, 阿尔法:60 } }, 标题:{ 文本:“Highsoft每周水果配送内容” }, 副标题:{ 文字:“Highcharts中的3D甜甜圈” }, 打印选

因此,我希望创建一个3d饼图(在Highcharts中),其中每个切片的深度由点的值决定。这个问题应该能让你很好地理解我的意图

目前Highcharts只支持系列级别的深度参数,因此我的第一个想法是制作多个系列,如下所示:

1:
Highcharts.chart('container'{
图表:{
键入“pie”,
选项3D:{
启用:对,
阿尔法:60
}
},
标题:{
文本:“Highsoft每周水果配送内容”
},
副标题:{
文字:“Highcharts中的3D甜甜圈”
},
打印选项:{
馅饼:{
内部尺寸:125,
深度:60
}
},
系列:[{
名称:'已交付金额',
数据:[
{名称:'a',y:1,val:0.59,颜色:'#25683d'},
{名称:'b',y:1,val:1.25,颜色:'#222f58'},
{名称:'c',y:2,val:0.73,颜色:'#bebe89'},
],
深度:45,
startAngle:0,
端角:180
}, {
数据:[
{名称:'d',y:2,val:-0.69,颜色:'#900'},
{名称:'e',y:2,val:0.57,颜色:'#a0'}
],
深度:60,
startAngle:180,
端角:360
}]
});

您可以使用Highcharts
wrap
和extend
translate
方法:

var each = Highcharts.each,
    round = Math.round,
    cos = Math.cos,
    sin = Math.sin,
    deg2rad = Math.deg2rad;

Highcharts.wrap(Highcharts.seriesTypes.pie.prototype, 'translate', function(proceed) {
    proceed.apply(this, [].slice.call(arguments, 1));

    // Do not do this if the chart is not 3D
    if (!this.chart.is3d()) {
        return;
    }

    var series = this,
        chart = series.chart,
        options = chart.options,
        seriesOptions = series.options,
        depth = seriesOptions.depth || 0,
        options3d = options.chart.options3d,
        alpha = options3d.alpha,
        beta = options3d.beta,
        z = seriesOptions.stacking ? (seriesOptions.stack || 0) * depth : series._i * depth;

    z += depth / 2;

    if (seriesOptions.grouping !== false) {
        z = 0;
    }

    each(series.data, function(point) {

        var shapeArgs = point.shapeArgs,
            angle;

        point.shapeType = 'arc3d';

        var ran = point.options.h;

        shapeArgs.z = z;
        shapeArgs.depth = depth * 0.75 + ran;
        shapeArgs.alpha = alpha;
        shapeArgs.beta = beta;
        shapeArgs.center = series.center;
        shapeArgs.ran = ran;

        angle = (shapeArgs.end + shapeArgs.start) / 2;

        point.slicedTranslation = {
            translateX: round(cos(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad)),
            translateY: round(sin(angle) * seriesOptions.slicedOffset * cos(alpha * deg2rad))
        };
    });
});

(function(H) {
    H.wrap(Highcharts.SVGRenderer.prototype, 'arc3dPath', function(proceed) {
        // Run original proceed method
        var ret = proceed.apply(this, [].slice.call(arguments, 1));
        ret.zTop = (ret.zOut + 0.5) / 100;
        return ret;
    });
}(Highcharts));
此外,在
load
事件中,您需要反转图表:

        events: {
            load: function() {
                var each = Highcharts.each,
                    points = this.series[0].points;

                each(points, function(p, i) {
                    p.graphic.attr({
                        translateY: -p.shapeArgs.ran
                    });

                    p.graphic.side1.attr({
                        translateY: -p.shapeArgs.ran
                    });

                    p.graphic.side2.attr({
                        translateY: -p.shapeArgs.ran
                    });
                });
            }
        }
现场演示:


医生:

我注意到一件小事。。。deg2rad应该是Highcharts.deg2rad而不是Math.deg2rad。除此之外,完美!如果你能帮忙的话,再谢谢你一件事。。。我正在尝试为负值添加一个功能。我将我的映射函数(从真值到深度)保持为正,如果真值为负,我只需反转translateY参数以“向下”移动切片。然而,这导致需要将这些负片的中心“移回”屏幕,以便边缘对齐。有什么想法吗?嗨,laventnc,看起来设置固定的
translateY
值就足够了:如果其他人得到了帮助,为了动态设置固定的translateY值,我发现将其设置为最小负片和最小正片高度之间的差值会产生很好的效果