首页 > 解决方案 > c3.js destroy() -- 未捕获的类型错误:无法读取 null 的属性“删除”

问题描述

我对 c3 中的 destory() 或 unload() 函数有一个非常奇怪的问题。

我正在生成一个带有按钮的图表,然后使用不同的按钮来清除它。它在前几次有效,但在第 3 次或第 4 次清除后,生成按钮失败。

控制台中的确切错误是:

Uncaught TypeError: Cannot read property 'remove' of null

每次按下按钮时,我都会记录对象,当它失败时,对象的元素会略有不同:

Chart {internal: ChartInternal, element: div#event_chart1.c3, axis: ƒ, category: ƒ, categories: ƒ, …}
chart.js:63 {page: "chart", data_to_pass: Array(3)}
chart.js:76 success
chart.js:123 running clear:
chart.js:124 Chart {internal: ChartInternal, element: div#event_chart1.c3, axis: ƒ, category: ƒ, categories: ƒ, …}
chart.js:63 {page: "chart", data_to_pass: Array(3)}
chart.js:76 success
chart.js:123 running clear:
chart.js:124 Chart {internal: ChartInternal, element: div#event_chart1.c3, axis: ƒ, category: ƒ, categories: ƒ, …}
chart.js:63 {page: "chart", data_to_pass: Array(3)}
chart.js:76 success
chart.js:123 running clear:
chart.js:124 Chart {internal: ChartInternal, element: div#event_chart1.c3, axis: ƒ, category: ƒ, categories: ƒ, …}
chart.js:123 running clear:
chart.js:124 Chart {internal: ChartInternal, element: div#event_chart1, axis: ƒ, category: ƒ, categories: ƒ, …}

问题是 FAILING 对象在元素末尾没有.c3。

知道为什么这个 .c3 可能会从#div 中删除吗?我尝试了很多事情:

1) html 中的'defer' 2) unload() 而不是 destroy() 3) 等待页面加载,以防我在奇怪的加载状态下捕获它

这些都不起作用,并且总是在第 3 次或第 4 次生成/销毁之后——我得到了未捕获的错误。


当我创建代码段的示例版本时,我想我发现了错误,但如果有任何评论,我将不胜感激。通过我的修复(显示在底部),它似乎避免了错误,但我需要对其进行更多压力测试。

我正在使用 chartNow 函数创建一个 c3 图表:

function chartNow(binding){
    data  = [['x', '2019-07-09 11:55:06.963147', '2019-07-09 11:55:26.231417', '2019-07-09 11:55:26.256508', '2019-07-09 11:55:26.997986', '2019-07-09 11:55:35.330754', '2019-07-09 11:55:37.823005', '2019-07-09 11:55:38.006228', '2019-07-09 11:55:38.007118', '2019-07-09 11:55:38.007676', '2019-07-09 11:55:38.009635', '2019-07-09 11:55:39.322970', '2019-07-09 11:55:39.353794', '2019-07-09 11:56:00.336917', '2019-07-09 11:56:02.048470', '2019-07-09 11:56:02.051476', '2019-07-09 11:56:02.053289', '2019-07-09 11:56:02.055655', '2019-07-09 11:56:02.946014', '2019-07-09 11:56:04.437201', '2019-07-09 11:56:11.224776', '2019-07-09 11:56:12.503428', '2019-07-09 11:56:14.935326', '2019-07-09 11:56:23.955265', '2019-07-09 11:56:51.814801', '2019-07-09 11:57:08.614399', '2019-07-09 11:57:08.615609', '2019-07-09 11:57:08.635378', '2019-07-09 11:57:22.584230', '2019-07-09 11:57:22.813634', '2019-07-09 11:57:22.825124', '2019-07-09 11:57:23.600795', '2019-07-09 11:57:28.251848', '2019-07-09 11:57:30.219475', '2019-07-09 11:57:32.645034', '2019-07-09 11:57:46.561560', '2019-07-09 11:57:46.587336', '2019-07-09 11:57:47.741166', '2019-07-09 11:57:54.721330', '2019-07-09 11:57:56.147783', '2019-07-09 11:58:07.558622', '2019-07-09 11:58:25.993912', '2019-07-09 11:58:26.459869', '2019-07-09 11:58:26.462412', '2019-07-09 11:58:26.462721', '2019-07-09 11:58:26.499475', '2019-07-09 11:58:29.655932', '2019-07-09 11:58:32.029455', '2019-07-09 11:58:32.659533', '2019-07-09 11:58:42.041864', '2019-07-09 11:58:47.980206', '2019-07-09 11:58:54.858078', '2019-07-09 11:58:55.009230', '2019-07-09 11:58:59.771560', '2019-07-09 11:59:00.008234', '2019-07-09 11:59:01.236563', '2019-07-09 11:59:03.914980', '2019-07-09 11:59:09.389858', '2019-07-09 11:59:13.365114', '2019-07-09 11:59:18.128968', '2019-07-09 11:59:20.311406', '2019-07-09 11:59:20.624771', '2019-07-09 11:59:20.832746', '2019-07-09 11:59:20.843927', '2019-07-09 11:59:22.553664', '2019-07-09 11:59:24.822959', '2019-07-09 11:59:25.109268', '2019-07-09 11:59:25.652581', '2019-07-09 11:59:25.817560', '2019-07-09 11:59:32.623836', '2019-07-09 11:59:32.993061', '2019-07-09 11:59:54.910075', '2019-07-09 11:59:55.045563', '2019-07-09 12:00:00.499371', '2019-07-09 12:00:02.227440', '2019-07-09 12:00:17.108786', '2019-07-09 12:00:17.220869', '2019-07-09 12:00:21.133127', '2019-07-09 12:00:25.830681', '2019-07-09 12:00:30.982202', '2019-07-09 12:00:31.396511', '2019-07-09 12:00:32.094295', '2019-07-09 12:00:34.529636', '2019-07-09 12:00:34.634604', '2019-07-09 12:00:35.729103', '2019-07-09 12:00:44.574691', '2019-07-09 12:00:45.889287', '2019-07-09 12:00:45.889749', '2019-07-09 12:00:45.894716', '2019-07-09 12:00:45.991416', '2019-07-09 12:00:59.614254', '2019-07-09 12:01:00.282916', '2019-07-09 12:01:09.209810', '2019-07-09 12:01:15.534272', '2019-07-09 12:01:15.614933', '2019-07-09 12:01:18.978446', '2019-07-09 12:01:19.131143', '2019-07-09 12:01:21.264697', '2019-07-09 12:01:21.370059', '2019-07-09 12:01:21.370957', '2019-07-09 12:01:21.606968', '2019-07-09 12:01:22.748201', '2019-07-09 12:01:28.040545', '2019-07-09 12:01:32.747888', '2019-07-09 12:01:37.834418', '2019-07-09 12:01:37.839499', '2019-07-09 12:01:38.455238', '2019-07-09 12:01:41.054722', '2019-07-09 12:01:41.300685', '2019-07-09 12:01:41.408064', '2019-07-09 12:01:45.387278', '2019-07-09 12:01:45.387779', '2019-07-09 12:01:48.581434', '2019-07-09 12:01:50.548743', '2019-07-09 12:01:57.871336', '2019-07-09 12:01:58.533657', '2019-07-09 12:01:58.539970', '2019-07-09 12:01:59.613314', '2019-07-09 12:02:02.140617', '2019-07-09 12:02:02.412264', '2019-07-09 12:02:02.416644', '2019-07-09 12:02:02.484752', '2019-07-09 12:02:02.979059', '2019-07-09 12:02:02.979873', '2019-07-09 12:02:03.990632', '2019-07-09 12:02:04.082309', '2019-07-09 12:02:05.667770', '2019-07-09 12:02:06.042878', '2019-07-09 12:02:08.205836', '2019-07-09 12:02:08.207076', '2019-07-09 12:02:08.439998', '2019-07-09 12:02:08.444250', '2019-07-09 12:02:12.316683', '2019-07-09 12:02:16.184511', '2019-07-09 12:02:17.659224', '2019-07-09 12:02:17.704688', '2019-07-09 12:02:17.715909', '2019-07-09 12:02:19.789272', '2019-07-09 12:02:23.033384', '2019-07-09 12:02:23.036579', '2019-07-09 12:02:24.995723', '2019-07-09 12:02:40.101766', '2019-07-09 12:02:40.189779', '2019-07-09 12:02:41.681998', '2019-07-09 12:02:41.763661', '2019-07-09 12:02:45.214314', '2019-07-09 12:02:46.243339', '2019-07-09 12:02:46.913034', '2019-07-09 12:02:55.001944', '2019-07-09 12:03:03.954598', '2019-07-09 12:03:04.040690', '2019-07-09 12:03:06.923127', '2019-07-09 12:03:06.977860', '2019-07-09 12:03:14.405034', '2019-07-09 12:03:17.386286', '2019-07-09 12:03:17.400210', '2019-07-09 12:03:21.151851', '2019-07-09 12:03:23.749450', '2019-07-09 12:03:24.234850', '2019-07-09 12:03:25.649471', '2019-07-09 12:03:40.185787', '2019-07-09 12:03:47.713922', '2019-07-09 12:03:52.040015', '2019-07-09 12:04:05.779515', '2019-07-09 12:04:05.780518', '2019-07-09 12:04:05.788889', '2019-07-09 12:04:06.527448', '2019-07-09 12:04:06.566004', '2019-07-09 12:04:08.700123', '2019-07-09 12:04:08.864055', '2019-07-09 12:04:10.313432', '2019-07-09 12:04:11.019463', '2019-07-09 12:04:19.139934', '2019-07-09 12:04:56.122848', '2019-07-09 12:04:56.274264', '2019-07-09 12:04:56.288833', '2019-07-09 12:04:56.314542', '2019-07-09 12:04:56.328217', '2019-07-09 12:04:56.985232'], ['mp', 1126.97714285714, 1126.9897435897399, 1127.00545454545, 1127.0186046511599, 1127.00185185185, 1126.98703703704, 1127.00384615385, 1126.98424657534, 1126.99807692308, 1126.98490566038, 1126.97222222222, 1126.95882352941, 1126.971875, 1126.9851063829801, 1127.00098039216, 1126.98333333333, 1126.96956521739, 1126.95365853659, 1126.9405660377402, 1126.95384615385, 1126.9670454545499, 1126.95384615385, 1126.96979166667, 1126.95625, 1126.96891891892, 1126.98333333333, 1126.99615384615, 1126.98333333333, 1126.9704545454501, 1126.95731707317, 1126.941, 1126.92843137255, 1126.9132352941199, 1126.92625, 1126.93913043478, 1126.952, 1126.93879310345, 1126.9518518518498, 1126.9393442623, 1126.952, 1126.96544117647, 1126.9782258064502, 1126.9914893617, 1127.00564516129, 1127.0185483871, 1126.99803921569, 1126.98524590164, 1126.99875, 1126.98559322034, 1127.00208333333, 1127.01603773585, 1127.03068181818, 1127.01666666667, 1126.99912280702, 1127.01206896552, 1127.0256756756798, 1127.01060606061, 1127.025, 1127.03796296296, 1127.05079365079, 1127.0633333333299, 1127.08055555556, 1127.09318181818, 1127.10615384615, 1127.0934782608701, 1127.1085526315799, 1127.09464285714, 1127.0803030303, 1127.06734693878, 1127.0491935483901, 1127.03623188406, 1127.02333333333, 1127.0362745098, 1127.02023809524, 1127.00256410256, 1127.01509433962, 1127.02763157895, 1127.01511627907, 1126.99833333333, 1127.01153846154, 1126.99895833333, 1126.98611111111, 1126.97352941176, 1126.9606557377, 1126.975, 1126.98875, 1127.00208333333, 1126.98936170213, 1127.00319148936, 1127.01637931034, 1127.029, 1127.042, 1127.05523255814, 1127.0686274509799, 1127.08125, 1127.09491525424, 1127.08203125, 1127.06951219512, 1127.05657894737, 1127.0717391304302, 1127.0585365853701, 1127.04565217391, 1127.0594339622598, 1127.07272727273, 1127.08604651163, 1127.07321428571, 1127.08645833333, 1127.10066666667, 1127.1154545454501, 1127.13035714286, 1127.1466666666702, 1127.1336363636399, 1127.12111111111, 1127.10833333333, 1127.09452054795, 1127.10777777778, 1127.095, 1127.08137254902, 1127.06779661017, 1127.0491935483901, 1127.0625, 1127.07575757576, 1127.08918918919, 1127.0755813953501, 1127.06111111111, 1127.07432432432, 1127.06176470588, 1127.07428571429, 1127.08720930233, 1127.10079365079, 1127.088, 1127.10079365079, 1127.11370967742, 1127.12745098039, 1127.14111111111, 1127.12796610169, 1127.14146341463, 1127.155, 1127.13695652174, 1127.15078125, 1127.13771929825, 1127.12413793103, 1127.11153846154, 1127.09888888889, 1127.08522727273, 1127.0987804878, 1127.08617021277, 1127.09871794872, 1127.1125, 1127.12555555556, 1127.11224489796, 1127.09905660377, 1127.08650793651, 1127.07363636364, 1127.06071428571, 1127.04782608696, 1127.06041666667, 1127.07444444444, 1127.08974358974, 1127.10342465753, 1127.11647727273, 1127.10272727273, 1127.08879310345, 1127.07619047619, 1127.0631147540998, 1127.04928571429, 1127.03625, 1127.0513274336301, 1127.06463414634, 1127.08, 1127.09361702128, 1127.08090909091, 1127.06666666667, 1127.05405405405, 1127.06699029126, 1127.0492957746499, 1127.0619469026499, 1127.04931506849], ['2019-07-09 11:55:06.963147', '2019-07-09 12:00:00.000000', '2019-07-09 12:04:56.985232'], [1126.0, 1126.25, 1126.5, 1126.75, 1127.0, 1127.25, 1127.5, 1127.75], 'US.3-Yr Note Auction -- 20190709 12:00:00 for 6E']

    x = data[0]
    mp = data[1]
    xrange = data[2]
    yrange = data[3]
    title = data[4]
    bind_str = ''
    bind_str += '#event_chart' + binding;
    charts[binding] = c3.generate({
        bindto: bind_str,
        title: {
        text: title
        },
        data: {
        x: 'x',
        xFormat: '%Y-%m-%d %H:%M:%S.%f',
        columns: [x, mp]
    },
        legend: {
        show: true,
        position: 'right'
    },
        grid: {
        y: {
            show: true
        }
    },
        padding: {
             right: 50,
             top: 30
    },
        zoom:{
        enabled: true
        },
        point: {
        show: true,
        r: 1
    },
        axis: {
            x: {
                type: 'timeseries',
                tick: {
                format: '%Y-%m-%d %H:%M:%S.%f',
                values: xrange
            },
            },
            y: {
            tick: {
               values: yrange
            }
        }
        }
    });
};

这是通过单击按钮调用的:

$('#submit').on('click', function() {

        clear_chart()
        chartNow(1)
})

并使用 clear_chart 函数清除:

function clear_chart(){
    for(i=1; i<6; i++) {
//        console.log(typeof charts[i])
        if (typeof charts[i] !== 'undefined'){
            console.log('running clear:')
            console.log(charts[i])
            charts[i].destroy()
        }
    }
}

我认为如果我执行 clear_chart 然后生成图表,则该错误与连续两次调用 destroy 函数有关。

为了解决这个问题,我创建了一个全局变量:

charts_cleared = false

在按钮内点击,我现在对其进行检查:

$('#submit').on('click', function() {

        if (charts_cleared == false){
            clear_chart()
            }

        build_chart(payload, '#spin0')
})

function clear_chart(){
    for(i=1; i<6; i++) {
//        console.log(typeof charts[i])
        if (typeof charts[i] !== 'undefined'){
            console.log('running clear:')
            console.log(charts[i])
            charts[i].destroy()
            charts_cleared = true
        }
    }
}

这也是我的html代码:


<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

        <!-- Load c3.css -->
        <link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.2/c3.css" rel="stylesheet">
        <link rel="stylesheet" type="text/css" href="//fonts.googleapis.com/css?family=Open+Sans|Arimo|Dosis|Play">

        <link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
        <link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css"/>
        <!--<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css"/>-->


        <link rel="stylesheet" type="text/css" href="../static/css/style.css" >
        <link rel="stylesheet" type="text/css" href="../static/css/autocomplete.css" >
        <link rel="stylesheet" type="text/css" href="../static/css/topnav.css" >
        <!-- Load d3.js and c3.js -->

        <script src="http://code.jquery.com/jquery-latest.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.7/d3.min.js"></script>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.2/c3.js"></script>
        <script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
    </head>
    <body>
<div class="container">
    <div class="row">
    </div>
    <div class="row">
    </div>
    <div class="row">
        <div class="col-2">
    <button id="submit" class="btn btn-primary btn-sm" type="submit">Generate Charts</button>
        <div class="spinner-border spinner-border-sm d-none text-light" role="status" aria-hidden="true" id="spin0"></div>
        </div>
        <div class="col-2">
            <button id="clear" class="btn btn-primary btn-sm" type="submit" onclick=clear_chart()>Clear Charts</button>
        </div>
    </div>
</div>
<div class="container" id="charts">
    <div class="row">
        <div class="col-md-12">
            <div id="event_chart1"></div>
        </div>
    </div>
</div>


<!--<script type="text/javascript" src="../static/js/candles.js"></script>-->
<script type="text/javascript" src="../static/js/tempCharts.js" defer></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js" ></script>


    </body>
</html>

标签: javascriptc3.js

解决方案


我认为您是正确的,因为您可能两次调用 clear_chart。您的 HTML 似乎引用了 onClick 以及您的 JS 代码 - 这可能会导致第二次调用。

不过,我不太关心全局 var 作为一种保护机制。我认为如果您的 clear_chart 函数可以输入两次(即使不应该),原始问题可能已经解决。您当前的 clear_chart 实现调用了 destroy(),但它留下了对图表的引用。

试试这个:

function clear_chart(){
    for(i=1; i<6; i++) {
//        console.log(typeof charts[i])
        if (typeof charts[i] !== 'undefined') { // might check for null also
            console.log('running clear:')
            console.log(charts[i])
            charts[i].destroy()
//            charts_cleared = true  // remove this global var
            charts[i] = undefined // or  = null, but this should remove the reference
        }
    }
}

推荐阅读