基于echarts异步加载数据之多个series加载实例

本文介绍如何解决ECharts中多个series样式异步加载JSON数据的问题,通过定义不同图表类型的模板并根据JSON数据动态填充,实现折线图与柱状图的组合展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

基于本人最近在参与研究公司echarts报表部分的功能,其中遇到了不少的坑,这里将echarts异步加载json数据中涉及到的多个series加载实例问题解决方案做一个共享。

问题描述

我们在加载echarts复杂图形时,比如说折线图和柱状图结合,会涉及到多个series样式,给个例子,
双区域缩放的折线图和柱状图

option = {
    tooltip: {
        trigger: 'axis',
        formatter: function(params, ticket, callback) {

            var res = params[0].name;

            for (var i = 0, l = params.length; i < l; i++) {
                if (params[i].seriesType === 'line') {
                    res += '<br/>' + params[i].seriesName + ' : ' + (params[i].value ? params[i].value : '-') + 'h';
                } else {
                    res += '<br/>' + params[i].seriesName + ' : ' + (params[i].value ? params[i].value : '-') + '个';
                }
            }
            return res;

        }
    },
    grid: {
        containLabel: true
    },
    legend: {
        data: ['时间', '人均个数', '总体个数']
    },
    xAxis: [{
        type: 'category',
        axisTick: {
            alignWithLabel: true
        },
        data: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
    }],
    dataZoom: [{
        type: 'slider',
        xAxisIndex: 0,
        filterMode: 'empty',
        start: 0,
        end: 100
    }, {
        type: 'slider',
        yAxisIndex: 0,
        filterMode: 'empty',
        start: 0,
        end: 100
    }, {
        type: 'inside',
        xAxisIndex: 0,
        filterMode: 'empty',
        start: 0,
        end: 100
    }, {
        type: 'inside',
        yAxisIndex: 0,
        filterMode: 'empty',
        start: 0,
        end: 100
    }],
    yAxis: [{
        type: 'value',
        name: '时间',
        min: 0,
        position: 'left',
        axisLabel: {
            formatter: '{value} h'
        }
    }, {
        type: 'value',
        name: '个数',
        min: 0,
        position: 'right',
        axisLabel: {
            formatter: '{value} 个'
        }
    }],
    series: [{
        name: '时间',
        type: 'line',
        label: {
            normal: {
                show: true,
                position: 'top',
            }
        },
        lineStyle: {
            normal: {
                width: 3,
                shadowColor: 'rgba(0,0,0,0.4)',
                shadowBlur: 10,
                shadowOffsetY: 10
            }
        },
        data: [1, 13, 37, 35, 15, 13, 25, 21, 6, 45, 32, 2]
    }, {
        name: '人均个数',
        type: 'bar',
        yAxisIndex: 1,
        label: {
            normal: {
                show: true,
                position: 'top'
            }
        },
        data: [22, 22, 23, 77, 24, 55, 55, 89, 98, 164, 106, 224]
    }, {
        name: '总体个数',
        type: 'bar',
        yAxisIndex: 1,
        label: {
            normal: {
                show: true,
                position: 'top'
            }
        },
        data: [201, 222, 223, 777, 244, 255, 555, 879, 938, 1364, 1806, 2324]
    }]
};

我们发现这个echarts图表是双y轴并且由柱状图和折线图组成。时间是用折线图表示的,人均个数和总体个数是由柱状图表示的。并且这是写死的样例,那么我们实际应用中的数据肯定是用异步加载的方式加载数据的,json串的数据格式是一样的,这种不同的series如何用json串异步加载呢?

实际解决方案

这里,楼主用自己所做的项目为例,贴出核心代码。首先,获取到的json串格式如图。total的数据格式头是data。即:data:{total:{date:…}}
json

var option = {
    title: {
            text: '交易量统计趋势图'
        },
    tooltip: {
            trigger: 'axis',
            axisPointer: { // 坐标轴指示器,坐标轴触发有效
                type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
            },
   formatter: function (params, ticket,callback){
                var res = params[0].name;

                for (var i = 0, l = params.length; i < l; i++) {
                    if (params[i].seriesType === 'line') {
                        res += '<br/>' + params[i].seriesName + ' : ' + (params[i].value ? params[i].value : '-') + '元';
                    } else {
                        res += '<br/>' + params[i].seriesName + ' : ' + (params[i].value ? params[i].value : '-') + '元';
                    }
                }
                return res;
            }
        },
        legend: {
            data: [],
            align: 'right',
            right: 10
        },
        grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
        },
        xAxis: [{
            type: 'category',
            data: []
        }],
        yAxis: [{
            type: 'value',
            name: '总价(元)',
            axisLabel: {
                formatter: '{value}'
            }
        }],
        series: []
    };

其次,需要加载数据的3个地方legend(表示图例组件),xAxis(表示x轴数据),series(图表类型和样式等)全部设置为默认,前期的准备工作就这样做好了。
然后,我们的核心代码来了,最终我们要实现的效果是让series有2个不同的图表类型。那么,这里我们分别定义2个不同的图表类型,即折线和柱状,即:

   //表示折线图
   var ItemLine = function () {
        return {
            name: '',
            type: 'line',
            label: {
                normal: {
                    show: true,
                    position: 'top',
                }
            },
            lineStyle: {
                normal: {
                    width: 3,
                    shadowColor: 'rgba(0,0,0,0.4)',
                    shadowBlur: 10,
                    shadowOffsetY: 10
                }
            },
            data: []
        }
    };
    //表示柱状图
    var ItemBar = function () {
        return {
            name: '',
            type: 'bar',
            data: []
        }

    }

定义3个变量分别存储legend,xAxis,series的值。

var legends=[];
var xDateArr=[];
var SeriesTotal=[];

将json串赋值给3个变量。这里十分重要!十分重要!十分重要!(重要的事情说3遍)。回到我们刚才的json串,注意,是以data为头的。我们遍历这个json串:

//给x轴赋值
xDataArr=data.total.date;
for (var k in data.total.element) {
 //给legend赋值
 lengends.push(data.total.element[k].name);
     //核心,给series赋值,分开包装的思想。
        if (k == 0) {
            var itemLine = new ItemLine();
            itemLine.name = data.total.element[k].name;
            itemLine.data = data.total.element[k].value;
            SeriesTotal.push(itemLine);
        } else {
            var itemBar = new ItemBar();
            itemBar.name = data.total.element[k].name;
            itemBar.data = data.total.element[k].value;
            SeriesTotal.push(itemBar);
        }
    }

当然,我这里是用下标做分割的,小伙伴们也可以用json头等做标志分割2个不同的series,主要思想是分次包装,这样就能实现series多个系列的数据异步加载了。哪怕3个,4个图例都so easy了~~~
最后,再把这3个变量赋值给option,并将option加载到dom容器中即可。

var myChartTransactionTotal = echarts.init(document.getElementById('main_chart_transaction_total'));
    option.legend.data = lengends;
    //注意这里是xAxis[0],如果直接写xAxis会报错,因为x轴默认有2个,上半年轴和下半轴。
    option.xAxis[0].data = data.total.date;
    option.series = SeriesTotal;
    //这里最好加上true参数,否则会出现切换图表时前面数据不会清除掉的情况。
myChartTransactionTotal.setOption(option, true);

让我们来看下实际效果,是不是很简单有木有。如果有问题欢迎大家一起交流讨论哦!

这里写图片描述

<think>我们正在处理用户关于ECharts异步加载数据的问题。根据用户需求,我们需要提供一个ECharts异步加载数据的示例代码,并解释其实现方法。参考引用内容:引用[1]展示了一个基本的异步加载示例,使用setTimeout模拟异步请求,获取数据后通过setOption填充数据。引用[2]提到使用$.get()从服务器获取数据(如JSON格式),然后填入数据。引用[3]同样提到使用$.get()获取JSON数据加载的例子。引用[4]提供了一个data.json的示例数据结构。因此,我们可以提供两种常见方式:1.使用setTimeout模拟异步请求(适用于演示或模拟数据)2.使用AJAX(如jQuery的$.get)从服务器获取数据我们将按照以下步骤构建示例:a.初始化ECharts实例b.设置一个初始的option(包含标题、坐标轴、系列等基本配置,但数据为空)c.异步获取数据(模拟或真实请求)d.获取数据后,使用setOption方法将新数据填入图表注意:由于用户要求的是示例代码,我们将提供一个完整的HTML示例,并包含必要的注释。同时,根据引用[2]和[3],我们也可以提供一个使用jQuery的示例,但考虑到用户可能没有引入jQuery,我们也可以使用原生的fetch或XMLHttpRequest。但为了通用性和简单性,我们先使用setTimeout模拟,再使用原生fetch方法(不需要额外库)作为示例。用户问题:我想获取ECharts异步加载数据的实现方法,请问ECharts异步加载数据示例代码。我们将提供两个示例:示例1:使用setTimeout模拟异步加载(如引用[1])示例2:使用fetch API进行异步数据加载(现代浏览器支持)另外,根据引用[4],我们还可以展示如何解析类似data.json的数据结构。由于引用[4]中的数据结构是:{"serviceTypeInfo":[{ "name":"魔术贴","value": "17717282"},...]}我们可以调整示例,使其能够处理这种格式的数据。但是,用户没有指定具体的数据结构,所以我们将采用引用[1]中的简单数据结构(月份和销量)。步骤:1.创建HTML结构,引入ECharts2.初始化图表3.设置初始option4.异步获取数据并更新图表我们将提供两个示例代码,并解释。注意:用户要求使用中文回答,且代码部分需要正确格式化。由于用户要求生成相关问题,我们将在最后提出几个相关问题。</think>### ECharts 异步加载数据实现方法 ECharts 异步加载数据主要通过以下步骤实现: 1. **初始化图表**:创建 ECharts 实例并设置基本配置项 2. **定义空数据占位**:在初始配置中保留空的数据容器 3. **异步获取数据**:通过 AJAX 请求或模拟异步操作获取数据 4. **更新图表**:使用 `setOption()` 方法将新数据注入图表 #### 示例代码(使用原生 JavaScript) ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>异步数据加载示例</title> <script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.4.0/echarts.min.js"></script> </head> <body> <div id="chart" style="width:800px; height:500px;"></div> <script> // 1. 初始化图表 const chartDom = document.getElementById(&#39;chart&#39;); const myChart = echarts.init(chartDom); // 2. 设置初始配置(空数据) const option = { title: { text: &#39;销售数据统计&#39; }, tooltip: {}, legend: { data: [&#39;销量&#39;] }, xAxis: { data: [] }, // 预留空X轴 yAxis: {}, series: [{ name: &#39;销量&#39;, type: &#39;bar&#39;, data: [] // 预留空数据 }] }; myChart.setOption(option); // 3. 异步数据加载(模拟API请求) setTimeout(() => { // 模拟从服务器获取的数据 const asyncData = { categories: [&#39;1月&#39;, &#39;2月&#39;, &#39;3月&#39;, &#39;4月&#39;, &#39;5月&#39;, &#39;6月&#39;], values: [125, 232, 201, 184, 219, 238] }; // 4. 更新图表数据 myChart.setOption({ xAxis: { data: asyncData.categories }, series: [{ data: asyncData.values }] }); }, 1000); // 模拟1秒网络延迟 </script> </body> </html> ``` #### 关键实现细节: 1. **数据占位设计** 初始配置中保留 `xAxis.data` 和 `series.data` 作为空数组,为异步数据预留位置[^1]。 2. **异步更新机制** 使用 `setOption()` 进行局部更新,ECharts 会自动合并新旧配置,仅更新变化的部分[^2]。 3. **真实数据加载**(使用 fetch API) ```javascript // 替换setTimeout部分 fetch(&#39;https://api.example.com/sales-data&#39;) .then(response => response.json()) .then(data => { myChart.setOption({ xAxis: { data: data.months }, series: [{ data: data.sales }] }); }); ``` 4. **多数据加载** 可结合 `Promise.all()` 加载多个数据源: ```javascript Promise.all([ fetch(&#39;/api/sales&#39;), fetch(&#39;/api/inventory&#39;) ]).then(([salesRes, invRes]) => { // 合并多个数据集更新图表 }); ``` #### 注意事项: - **数据一致性**:确保异步返回的数据结构与预设的 series 匹配 - **加载状态**:可添加 `myChart.showLoading()` 提升用户体验 - **错误处理**:需捕获网络请求异常,避免图表渲染失败 - **性能优化**:大数据量建议使用分页加载或增量渲染 [^1]: ECharts 官方推荐先初始化空图表再填充数据异步加载模式。 [^2]: `setOption()` 的增量更新机制可高效处理数据变化。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值