You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

jQuery获取数据后C3图表仅最后一个渲染的问题求助

问题排查与解决方案

你遇到的这个问题,核心原因是使用innerHTML +=动态添加DOM元素时,会重新渲染整个父容器。每次执行document.getElementById("chartBlocks").innerHTML += ...,浏览器都会把chartBlocks里的所有内容重新解析一遍——之前已经绑定了C3图表的元素会被销毁再重建,但C3已经和原来的DOM节点绑定了,新生成的节点并没有被C3初始化,所以前面的图表就显示不出来;只有最后一次添加的元素因为是最后创建的,还没被覆盖,能正常渲染。

之前用for循环正常工作,应该是因为你当时没有用innerHTML +=的方式,而是直接创建元素并追加,或者是一次性渲染所有元素后再初始化图表。

下面给你两种具体的解决方案:

方案一:用createElement和appendChild添加元素(推荐)

这种方式不会重新渲染整个父容器,而是直接把新元素追加进去,原来的DOM节点不会被破坏,C3的绑定也能正常生效。修改你的代码如下:

$.getJSON('api/randomData?chartCount=' + chartsToMake).done( function(data) {
    // Extract list of servers from the data...
    var hostList = []
    $.map(data, function(row) {
        hostList.push(row.host);
    });
    // Make it a unique list
    var uniqueHostList = hostList.unique();
    // 获取父容器
    var chartBlocks = document.getElementById("chartBlocks");
    // Iterate over the unique list of servers
    uniqueHostList.forEach( function(host) {
        var tag = "chart" + host.replace(/\./g, "");
        var hostdata = data.filter( (v,i,a) => v.host === host)
        console.log("Processing Server:" + host + " with " + hostdata.length + " rows");
        // 创建DOM元素并追加到父容器
        var chartDiv = document.createElement('div');
        chartDiv.id = tag.replaceAll('#','');
        chartBlocks.appendChild(chartDiv);
        // Create the Chart here
        var chart = c3.generate({
            bindto: "#" + tag,
            data: {
                json: hostdata,
                keys: {
                    value: ['lowerband']
                }
            }
        });
    });
});

方案二:先批量创建所有DOM元素,再初始化图表

如果不想修改元素添加的方式,可以先把所有需要的div都用innerHTML +=创建好,然后再循环遍历这些div来初始化C3图表,这样就不会因为DOM重新渲染导致绑定失效:

$.getJSON('api/randomData?chartCount=' + chartsToMake).done( function(data) {
    // Extract list of servers from the data...
    var hostList = []
    $.map(data, function(row) {
        hostList.push(row.host);
    });
    // Make it a unique list
    var uniqueHostList = hostList.unique();
    
    // 第一步:先创建所有DOM元素
    var chartBlocks = document.getElementById("chartBlocks");
    var html = '';
    uniqueHostList.forEach( function(host) {
        var tag = "chart" + host.replace(/\./g, "");
        html += "<div id=\"" + tag.replaceAll('#','') + "\"></div>";
    });
    chartBlocks.innerHTML = html;
    
    // 第二步:再循环初始化每个图表
    uniqueHostList.forEach( function(host) {
        var tag = "chart" + host.replace(/\./g, "");
        var hostdata = data.filter( (v,i,a) => v.host === host)
        console.log("Processing Server:" + host + " with " + hostdata.length + " rows");
        var chart = c3.generate({
            bindto: "#" + tag,
            data: {
                json: hostdata,
                keys: {
                    value: ['lowerband']
                }
            }
        });
    });
});

这两种方案都能解决你遇到的问题,推荐第一种,因为它的DOM操作效率更高,也更符合现代前端的最佳实践。

内容的提问来源于stack exchange,提问作者Exie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:10:32