下拉更改后在多个 Highcharts 上调整大小不起作用

Posted

技术标签:

【中文标题】下拉更改后在多个 Highcharts 上调整大小不起作用【英文标题】:Resize on multiple Highcharts not working after dropdown change 【发布时间】:2020-11-06 15:03:49 【问题描述】:

我想在我的页面上调整多个 Highcharts 的大小,并且可以通过单击按钮来实现。

我的一个图表(最后一个)有一个与之关联的下拉菜单。当我更改下拉列表中的值以更新最后一个图表,然后单击按钮回流时,我得到Uncaught TypeError: Cannot read property 'reflow' of undefined 错误。

如果我不通过下拉菜单更新图表,我可以调整(重排)图表的大小。但是一旦我点击下拉列表中的值,回流就会中断并给我一个错误。

我的代码:

html

<div id="container" style="width: 400px; height: 300px; margin: 1em; border: 1px solid gray"></div>
<div id="container2" style="width: 400px; height: 300px; margin: 1em; border: 1px solid gray"></div>
<div id="drop" style="width: 400px; height: 300px; margin: 1em; border: 1px solid gray"></div>
<select id="mydropdown" multiple></select>
<button id="set-div-size" class="autocompare">REFLOW!</button>

我的 javascript

const obj = 
        '10-10-2020': [
            cat: 'cat',
            abc: 1,
            xyz: 5,
            pqr: 6,
            jkl: 1,
            mno: 9
        ,
        
            cat: 'dog',
            abc: 3,
            xyz: 4,
            pqr: 1,
            jkl: 6,
            mno: 1
        ,
        
            cat: 'rat',
            abc: 7,
            xyz: 2,
            pqr: 9,
            jkl: 3,
            mno: 0
        ,
        ],
        '10-07-2020': [
            cat: 'cat',
            abc: 1,
            xyz: 5,
            pqr: 6,
            jkl: 1,
            mno: 9
        ,
        
            cat: 'dog',
            abc: 3,
            xyz: 4,
            pqr: 1,
            jkl: 6,
            mno: 1
        ,
        
            cat: 'rat',
            abc: 7,
            xyz: 2,
            pqr: 9,
            jkl: 3,
            mno: 0
        ,
        ],
        '10-09-2020': [
            cat: 'cat',
            abc: 1,
            xyz: 5,
            pqr: 6,
            jkl: 1,
            mno: 9
        ,
        
            cat: 'dog',
            abc: 3,
            xyz: 4,
            pqr: 1,
            jkl: 6,
            mno: 1
        ,
        
            cat: 'rat',
            abc: 7,
            xyz: 2,
            pqr: 9,
            jkl: 3,
            mno: 0
        ,
        ],
    ;

    const colors = ['#000', 'red', 'blue'];
    let arr = ['abc', 'xyz', 'pqr', 'jkl', 'mno'];

    const data = (sd) => Object.entries(obj).map(([k, g]) => 
        var cos = 
            ['name']: k,
            ['data']: g.map(entry => entry[sd]),
            ['stack']: sd,
            ['color']: colors[i++ % colors.length],
        

        return cos;
    );


    let i = 0;
    let x = data('abc');


    let chartOptions = 
        chart: 
            type: 'column'
        ,

        xAxis: 
            categories: ['One', 'Two', 'Three', 'Four', 'Five']
        ,

        plotOptions: 
            column: 
                stacking: 'normal'
            
        ,

        series: x
    

    arr.forEach(c => 
        $(`#mydropdown`).append(`<option value='$c'>$c</option>`);
    );
    $(`select#mydropdown option[value='abc']`).prop('selected', 'selected');


    let drop = new Highcharts.chart('drop', chartOptions);

    let opts;
    $(`#mydropdown`).on('change', function() 
        chartOptions.series = [],
        opts = [];
        $('option:selected', this).each(function() 
            i = 0;
            chartOptions.series = [...chartOptions.series, ...data($(this).val())];
            opts.push(this.value);
        );
        let drop = new Highcharts.chart('drop', chartOptions);
        console.log(Highcharts.charts); 
    );

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var chart = Highcharts.chart('container', 

    xAxis: 
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    ,

    series: [
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
    ]

);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var chart2 = Highcharts.chart('container2', 

    xAxis: 
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
        'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
    ,

    series: [
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
    ]

);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
let charts_arr =['chart', 'chart2', 'drop']
var wide = false;
$('#set-div-size').click(function () 
    $('#container').width(wide ? 400 : 500);
    $('#container2').width(wide ? 400 : 500);
    $('#drop').width(wide ? 400 : 500);
    wide = !wide;
    Highcharts.charts.forEach(d=>
        d.reflow();
        console.log(Highcharts.charts); 
    );
);

我有一个工作小提琴:my_fiddle

从下拉列表更新最后一个图表后尝试调整大小时出现错误:

【问题讨论】:

【参考方案1】:

您在控制台中得到的错误已经足够清楚了。确实,在这个 foreach 中:

Highcharts.charts.forEach(d => 
    d.reflow();

d 变量可能有未定义的值。说你需要跳过所有这些值:

Highcharts.charts.forEach(d => 
     if (d != undefined)
         d.reflow();

const obj = 
        '10-10-2020': [
            cat: 'cat',
            abc: 1,
            xyz: 5,
            pqr: 6,
            jkl: 1,
            mno: 9
        ,
            
                cat: 'dog',
                abc: 3,
                xyz: 4,
                pqr: 1,
                jkl: 6,
                mno: 1
            ,
            
                cat: 'rat',
                abc: 7,
                xyz: 2,
                pqr: 9,
                jkl: 3,
                mno: 0
            ,
        ],
        '10-07-2020': [
            cat: 'cat',
            abc: 1,
            xyz: 5,
            pqr: 6,
            jkl: 1,
            mno: 9
        ,
            
                cat: 'dog',
                abc: 3,
                xyz: 4,
                pqr: 1,
                jkl: 6,
                mno: 1
            ,
            
                cat: 'rat',
                abc: 7,
                xyz: 2,
                pqr: 9,
                jkl: 3,
                mno: 0
            ,
        ],
        '10-09-2020': [
            cat: 'cat',
            abc: 1,
            xyz: 5,
            pqr: 6,
            jkl: 1,
            mno: 9
        ,
            
                cat: 'dog',
                abc: 3,
                xyz: 4,
                pqr: 1,
                jkl: 6,
                mno: 1
            ,
            
                cat: 'rat',
                abc: 7,
                xyz: 2,
                pqr: 9,
                jkl: 3,
                mno: 0
            ,
        ],
    ;

    const colors = ['#000', 'red', 'blue'];
    let arr = ['abc', 'xyz', 'pqr', 'jkl', 'mno'];

    const data = (sd) => Object.entries(obj).map(([k, g]) => 
        var cos = 
                ['name']: k,
            ['data']: g.map(entry => entry[sd]),
    ['stack']: sd,
            ['color']: colors[i++ % colors.length],


return cos;
);


let i = 0;
let x = data('abc');


let chartOptions = 
    chart: 
        type: 'column'
    ,

    xAxis: 
        categories: ['One', 'Two', 'Three', 'Four', 'Five']
    ,

    plotOptions: 
        column: 
            stacking: 'normal'
        
    ,

    series: x


arr.forEach(c => 
    $(`#mydropdown`).append(`<option value='$c'>$c</option>`);
);
$(`select#mydropdown option[value='abc']`).prop('selected', 'selected');


let drop = new Highcharts.chart('drop', chartOptions);

let opts;
$(`#mydropdown`).on('change', function() 
    chartOptions.series = [],
            opts = [];
    $('option:selected', this).each(function() 
        i = 0;
        chartOptions.series = [...chartOptions.series, ...data($(this).val())];
        opts.push(this.value);
    );
    let drop = new Highcharts.chart('drop', chartOptions);
    console.log(Highcharts.charts);
);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var chart = Highcharts.chart('container', 

    xAxis: 
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
        ]
    ,

    series: [
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
    ]

);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var chart2 = Highcharts.chart('container2', 

    xAxis: 
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
            'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'
        ]
    ,

    series: [
        data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
    ]

);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
let charts_arr = ['chart', 'chart2', 'drop']
var wide = false;
$('#set-div-size').click(function() 
    $('#container').width(wide ? 400 : 500);
    $('#container2').width(wide ? 400 : 500);
    $('#drop').width(wide ? 400 : 500);
    wide = !wide;
    Highcharts.charts.forEach(d => 
        if (d != undefined)
            d.reflow();
    console.log(Highcharts.charts);
);
);
#container 
    min-width: 310px;
    max-width: 800px;
    height: 400px;
    margin: 0 auto
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>


<div id="container" style="width: 400px; height: 300px; margin: 1em; border: 1px solid gray"></div>
<div id="container2" style="width: 400px; height: 300px; margin: 1em; border: 1px solid gray"></div>
<div id="drop" style="width: 400px; height: 300px; margin: 1em; border: 1px solid gray"></div>
<select id="mydropdown" multiple></select>
<button id="set-div-size" class="autocompare">REFLOW</button>

【讨论】:

以上是关于下拉更改后在多个 Highcharts 上调整大小不起作用的主要内容,如果未能解决你的问题,请参考以下文章

在调整窗口大小之前,响应式 Highcharts 无法正确调整大小

Google翻译下拉窗口不会在较小的屏幕上重新调整大小

在 gridster 小部件中调整 highcharts 的负载大小

在下拉菜单中响应地隐藏和显示子元素

highcharts 用jquery设置animate 调整长宽的动画效果后 大小怎么自适应

Highcharts创建多个图表。想要只对第一个进行更改