ASP.NET Core MVC 项目中使用 ECharts 图表详解:结合 Bootstrap 5 实现前后端数据可视化

在当今数据驱动的时代,数据可视化已成为构建现代 Web 应用不可或缺的一部分。无论是企业管理系统、数据仪表盘,还是报表分析平台,直观、交互性强的图表都能极大提升用户体验与决策效率。ECharts 作为一款功能强大、易于使用的开源图表库,凭借其丰富的图表类型和灵活的配置能力,已成为前端开发者的首选工具之一。

本教程将带你一步步掌握在 ASP.NET Core MVC 项目中集成 ECharts 的完整流程。我们将结合 Bootstrap 5 构建响应式前端界面,通过控制器返回 JSON 数据,实现前后端的无缝对接与图表动态渲染。无论你是初学者还是有一定经验的开发者,都能通过本教程快速上手,构建出专业、美观的数据可视化界面。

1. 项目准备与环境搭建

1.1 创建ASP.NET Core MVC项目

使用Visual Studio 2022或.NET CLI创建ASP.NET Core MVC项目:

dotnet new mvc -n EChartsDemo
cd EChartsDemo

项目结构如下:

EChartsDemo/
├── Controllers/
│   └── HomeController.cs
├── Views/
│   ├── Home/
│   │   └── Index.cshtml
│   └── Shared/
│       └── _Layout.cshtml
├── wwwroot/
│   ├── css/
│   ├── js/
│   └── lib/
├── Program.cs
└── EChartsDemo.csproj

项目目标框架建议使用.NET 6.0或.NET 7.0,确保兼容性和性能优化。

1.2 引入Bootstrap 5与ECharts资源

1.2.1 引入Bootstrap 5

推荐使用CDN方式引入Bootstrap 5,在Views/Shared/_Layout.cshtml中添加:

<!-- Bootstrap CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">

<!-- Bootstrap JS Bundle -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script>

1.2.2 引入ECharts

同样使用CDN引入ECharts 5.4.3版本:

<script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>

1.2.3 本地资源引入(可选)

如需本地引入,可通过LibMan或npm安装:

dotnet tool install -g Microsoft.Web.LibraryManager.Cli
libman init
libman install bootstrap@5.3.0 -d wwwroot/lib/bootstrap
libman install echarts@5.4.3 -d wwwroot/lib/echarts

1.3 配置项目结构与静态资源路径

1.3.1 配置静态资源路径

Program.cs中确保启用静态文件中间件:

app.UseStaticFiles();

1.3.2 创建图表页面结构

Views/Home/Index.cshtml中创建基础布局:

@{
    ViewData["Title"] = "ECharts 示例";
}

<div class="container mt-4">
    <div class="row">
        <div class="col-md-6">
            <div id="barChart" style="width: 100%; height: 400px;"></div>
        </div>
        <div class="col-md-6">
            <div id="lineChart" style="width: 100%; height: 400px;"></div>
        </div>
    </div>
</div>

@section Scripts {
    <script>
        // ECharts 初始化代码将在这里添加
    </script>
}

1.3.3 创建数据模型

Models文件夹中创建图表数据模型:

public class ChartData
{
    public List<string> Categories { get; set; }
    public List<int> Values { get; set; }
}

public class EChartsResponse
{
    public string Title { get; set; }
    public List<string> XAxisData { get; set; }
    public List<SeriesData> Series { get; set; }
}

public class SeriesData
{
    public string Name { get; set; }
    public string Type { get; set; }
    public List<int> Data { get; set; }
}

1.3.4 配置控制器路由

HomeController.cs中添加图表数据接口:

[Route("api/[controller]")]
[ApiController]
public class ChartController : ControllerBase
{
    [HttpGet("bar")]
    public IActionResult GetBarChartData()
    {
        var data = new EChartsResponse
        {
            Title = "月度销售数据",
            XAxisData = new List<string> { "1月", "2月", "3月", "4月", "5月", "6月" },
            Series = new List<SeriesData>
            {
                new SeriesData
                {
                    Name = "销售额",
                    Type = "bar",
                    Data = new List<int> { 120, 200, 150, 80, 70, 110 }
                }
            }
        };
        return Ok(data);
    }
}

1.3.5 配置跨域支持(如需要)

Program.cs中添加CORS配置:

builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAll",
        builder =>
        {
            builder.AllowAnyOrigin()
                   .AllowAnyMethod()
                   .AllowAnyHeader();
        });
});

// 在 app.Build() 后使用
app.UseCors("AllowAll");

1.3.6 项目依赖包确认

确保项目文件.csproj包含必要依赖:

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
  </PropertyGroup>
  
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.0" />
  </ItemGroup>
</Project>

以上配置完成后,项目基础环境搭建完毕,可以开始实现具体的ECharts图表功能。

2. 前端页面设计与布局

2.1 使用Bootstrap 5搭建响应式页面结构

在ASP.NET Core MVC项目中,结合Bootstrap 5可以快速构建响应式、美观的页面布局。以下是一个典型的图表展示页面结构,适用于多种设备屏幕:

@{
    ViewData["Title"] = "ECharts 图表展示";
}

<div class="container mt-4">
    <h2 class="text-center mb-4">销售数据可视化</h2>

    <div class="row">
        <div class="col-lg-6 col-md-12 mb-4">
            <div class="card shadow-sm">
                <div class="card-header bg-primary text-white">
                    月度销售额柱状图
                </div>
                <div class="card-body">
                    <div id="barChart" style="width: 100%; height: 400px;"></div>
                </div>
            </div>
        </div>
        <div class="col-lg-6 col-md-12 mb-4">
            <div class="card shadow-sm">
                <div class="card-header bg-success text-white">
                    季度趋势折线图
                </div>
                <div class="card-body">
                    <div id="lineChart" style="width: 100%; height: 400px;"></div>
                </div>
            </div>
        </div>
    </div>

    <div class="row">
        <div class="col-lg-12">
            <div class="card shadow-sm">
                <div class="card-header bg-warning text-white">
                    产品类别饼图
                </div>
                <div class="card-body">
                    <div id="pieChart" style="width: 100%; height: 400px;"></div>
                </div>
            </div>
        </div>
    </div>
</div>

该结构使用了Bootstrap 5的栅格系统(.row.col-*)实现响应式布局,适配桌面端、平板和手机等不同设备。同时,使用卡片组件(.card)增强视觉层次感。

2.2 页面中引入ECharts容器与初始化脚本

在页面中引入ECharts图表容器,并通过JavaScript初始化图表。以下是一个完整的示例,展示如何通过AJAX从后端获取数据并渲染图表:

@section Scripts {
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <script>
        document.addEventListener('DOMContentLoaded', function () {
            initBarChart();
            initLineChart();
            initPieChart();
        });

        function initBarChart() {
            var chartDom = document.getElementById('barChart');
            var myChart = echarts.init(chartDom);

            fetch('/api/chart/bar')
                .then(response => response.json())
                .then(data => {
                    var option = {
                        title: {
                            text: data.title,
                            left: 'center'
                        },
                        tooltip: {},
                        xAxis: {
                            type: 'category',
                            data: data.xAxisData
                        },
                        yAxis: {
                            type: 'value'
                        },
                        series: data.series.map(s => ({
                            name: s.name,
                            type: s.type,
                            data: s.data
                        }))
                    };
                    myChart.setOption(option);
                });
        }

        function initLineChart() {
            var chartDom = document.getElementById('lineChart');
            var myChart = echarts.init(chartDom);

            fetch('/api/chart/line')
                .then(response => response.json())
                .then(data => {
                    var option = {
                        title: {
                            text: data.title,
                            left: 'center'
                        },
                        tooltip: {
                            trigger: 'axis'
                        },
                        xAxis: {
                            type: 'category',
                            data: data.xAxisData
                        },
                        yAxis: {
                            type: 'value'
                        },
                        series: data.series.map(s => ({
                            name: s.name,
                            type: s.type,
                            data: s.data,
                            smooth: true
                        }))
                    };
                    myChart.setOption(option);
                });
        }

        function initPieChart() {
            var chartDom = document.getElementById('pieChart');
            var myChart = echarts.init(chartDom);

            fetch('/api/chart/pie')
                .then(response => response.json())
                .then(data => {
                    var option = {
                        title: {
                            text: data.title,
                            left: 'center'
                        },
                        tooltip: {
                            trigger: 'item'
                        },
                        series: [
                            {
                                name: data.series[0].name,
                                type: 'pie',
                                radius: '50%',
                                data: data.series[0].data,
                                emphasis: {
                                    itemStyle: {
                                        shadowBlur: 10,
                                        shadowOffsetX: 0,
                                        shadowColor: 'rgba(0, 0, 0, 0.5)'
                                    }
                                }
                            }
                        ]
                    };
                    myChart.setOption(option);
                });
        }
    </script>
}

每个图表容器(如 #barChart)都通过 echarts.init() 初始化,并通过 fetch() 从后端API获取JSON数据,动态渲染图表。

2.3 页面与控制器路由配置

控制器中需要为每个图表提供对应的API接口,返回ECharts所需的JSON格式数据。以下是完整的控制器代码示例:

[Route("api/[controller]")]
[ApiController]
public class ChartController : ControllerBase
{
    [HttpGet("bar")]
    public IActionResult GetBarChartData()
    {
        var data = new EChartsResponse
        {
            Title = "月度销售额",
            XAxisData = new List<string> { "1月", "2月", "3月", "4月", "5月", "6月" },
            Series = new List<SeriesData>
            {
                new SeriesData
                {
                    Name = "销售额",
                    Type = "bar",
                    Data = new List<int> { 120, 200, 150, 80, 70, 110 }
                }
            }
        };
        return Ok(data);
    }

    [HttpGet("line")]
    public IActionResult GetLineChartData()
    {
        var data = new EChartsResponse
        {
            Title = "季度销售趋势",
            XAxisData = new List<string> { "Q1", "Q2", "Q3", "Q4" },
            Series = new List<SeriesData>
            {
                new SeriesData
                {
                    Name = "2024年",
                    Type = "line",
                    Data = new List<int> { 300, 450, 500, 600 }
                },
                new SeriesData
                {
                    Name = "2025年",
                    Type = "line",
                    Data = new List<int> { 320, 470, 530, 650 }
                }
            }
        };
        return Ok(data);
    }

    [HttpGet("pie")]
    public IActionResult GetPieChartData()
    {
        var data = new EChartsResponse
        {
            Title = "产品类别占比",
            XAxisData = null,
            Series = new List<SeriesData>
            {
                new SeriesData
                {
                    Name = "产品类别",
                    Type = "pie",
                    Data = new List<int> { 40, 30, 20, 10 } // 对应:电子产品、服装、食品、其他
                }
            }
        };
        return Ok(data);
    }
}

此外,确保在 Program.cs 中启用控制器路由和静态文件支持:

app.UseStaticFiles();
app.UseRouting();

app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");

至此,前端页面与后端控制器已完成对接,页面加载时将自动请求数据并渲染图表,实现了完整的ECharts图表展示功能。

3. 后端控制器设计与数据准备

3.1 创建ChartController并配置路由

在ASP.NET Core MVC项目中,控制器负责处理前端请求并返回数据。为实现ECharts图表的数据交互,需创建一个专门的ChartController,并配置RESTful风格的路由。

3.1.1 创建控制器

Controllers文件夹中添加ChartController.cs

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using EChartsDemo.Models;

namespace EChartsDemo.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ChartController : ControllerBase
    {
        [HttpGet("bar")]
        public IActionResult GetBarChartData()
        {
            var data = new EChartsResponse
            {
                Title = "月度销售数据",
                XAxisData = new List<string> { "1月", "2月", "3月", "4月", "5月", "6月" },
                Series = new List<SeriesData>
                {
                    new SeriesData
                    {
                        Name = "销售额",
                        Type = "bar",
                        Data = new List<int> { 120, 200, 150, 80, 70, 110 }
                    }
                }
            };
            return Ok(data);
        }

        [HttpGet("line")]
        public IActionResult GetLineChartData()
        {
            var data = new EChartsResponse
            {
                Title = "季度销售趋势",
                XAxisData = new List<string> { "Q1", "Q2", "Q3", "Q4" },
                Series = new List<SeriesData>
                {
                    new SeriesData
                    {
                        Name = "2024年",
                        Type = "line",
                        Data = new List<int> { 300, 450, 500, 600 }
                    },
                    new SeriesData
                    {
                        Name = "2025年",
                        Type = "line",
                        Data = new List<int> { 320, 470, 530, 650 }
                    }
                }
            };
            return Ok(data);
        }

        [HttpGet("pie")]
        public IActionResult GetPieChartData()
        {
            var data = new EChartsResponse
            {
                Title = "产品类别占比",
                XAxisData = null,
                Series = new List<SeriesData>
                {
                    new SeriesData
                    {
                        Name = "产品类别",
                        Type = "pie",
                        Data = new List<int> { 40, 30, 20, 10 }
                    }
                }
            };
            return Ok(data);
        }

        [HttpGet("heatmap")]
        public IActionResult GetHeatmapData()
        {
            var data = new EChartsResponse
            {
                Title = "用户活跃度热力图",
                XAxisData = new List<string> { "周一", "周二", "周三", "周四", "周五", "周六", "周日" },
                Series = new List<SeriesData>
                {
                    new SeriesData
                    {
                        Name = "活跃度",
                        Type = "heatmap",
                        Data = new List<int> { 10, 20, 30, 40, 50, 60, 70 }
                    }
                }
            };
            return Ok(data);
        }
    }
}

3.1.2 路由配置说明

  • 使用[Route("api/[controller]")]定义统一前缀为/api/chart

  • 每个图表类型通过[HttpGet("{type}")]区分,如/api/chart/bar

  • 返回类型统一为IActionResult,便于扩展和统一处理。

3.2 构造ECharts所需的数据模型

为了使前端ECharts能够正确解析数据,后端需构造符合其结构的数据模型。以下是推荐的数据模型设计:

3.2.1 数据模型定义

Models文件夹中创建EChartsModels.cs

namespace EChartsDemo.Models
{
    public class EChartsResponse
    {
        public string Title { get; set; }
        public List<string> XAxisData { get; set; }
        public List<SeriesData> Series { get; set; }
    }

    public class SeriesData
    {
        public string Name { get; set; }
        public string Type { get; set; }
        public List<int> Data { get; set; }
    }

    public class PieSeriesData : SeriesData
    {
        public List<PieDataItem> PieData { get; set; }
    }

    public class PieDataItem
    {
        public string Name { get; set; }
        public int Value { get; set; }
    }
}

3.2.2 饼图数据结构示例

饼图的数据结构与其他图表略有不同,需构造如下格式:

[HttpGet("pie")]
public IActionResult GetPieChartData()
{
    var data = new
    {
        Title = "产品类别占比",
        Series = new[]
        {
            new
            {
                Name = "产品类别",
                Type = "pie",
                Radius = "55%",
                Center = new[] { "50%", "60%" },
                Data = new[]
                {
                    new { Name = "电子产品", Value = 40 },
                    new { Name = "服装", Value = 30 },
                    new { Name = "食品", Value = 20 },
                    new { Name = "其他", Value = 10 }
                }
            }
        }
    };
    return Ok(data);
}

3.3 使用JsonResult返回数据给前端

ASP.NET Core 提供了多种方式返回 JSON 数据,最常用的是通过 Ok() 方法返回 IActionResult,系统会自动序列化为 JSON。

3.3.1 使用 Ok() 返回数据

[HttpGet("bar")]
public IActionResult GetBarChartData()
{
    var data = new EChartsResponse
    {
        Title = "月度销售数据",
        XAxisData = new List<string> { "1月", "2月", "3月", "4月", "5月", "6月" },
        Series = new List<SeriesData>
        {
            new SeriesData
            {
                Name = "销售额",
                Type = "bar",
                Data = new List<int> { 120, 200, 150, 80, 70, 110 }
            }
        }
    };
    return Ok(data);
}

3.3.2 使用 Json() 方法(可选)

在某些场景下,若需自定义序列化设置,可使用 Json() 方法:

[HttpGet("line")]
public IActionResult GetLineChartData()
{
    var data = new EChartsResponse { ... };
    return Json(data);
}

3.3.3 配置 JSON 序列化选项(可选)

Program.cs 中配置 JSON 序列化行为,如使用 PascalCase 或 CamelCase:

builder.Services.AddControllers()
    .AddJsonOptions(options =>
    {
        options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
    });

3.3.4 返回动态类型数据(适用于快速原型)

[HttpGet("dynamic")]
public IActionResult GetDynamicChartData()
{
    return Ok(new
    {
        title = "动态数据示例",
        xAxisData = new[] { "A", "B", "C" },
        series = new[]
        {
            new
            {
                name = "系列1",
                type = "bar",
                data = new[] { 10, 20, 30 }
            }
        }
    });
}

3.3.5 支持跨域请求(如前后端分离)

Program.cs 中配置 CORS:

builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowFrontend",
        policy =>
        {
            policy.WithOrigins("http://localhost:3000")
                  .AllowAnyHeader()
                  .AllowAnyMethod();
        });
});

app.UseCors("AllowFrontend");

至此,后端控制器已具备完整的图表数据接口能力,前端可通过 AJAX 请求获取结构化 JSON 数据并渲染 ECharts 图表。

4. ECharts图表配置与渲染

4.1 前端通过AJAX请求获取图表数据

在ASP.NET Core MVC项目中,前端页面通过AJAX请求从后端API获取图表所需的数据。推荐使用fetch()$.ajax()方法进行异步数据请求,确保页面无刷新更新图表内容。

4.1.1 使用fetch()获取JSON数据

function fetchChartData(endpoint) {
    return fetch(endpoint)
        .then(response => {
            if (!response.ok) {
                throw new Error('Network response was not ok');
            }
            return response.json();
        })
        .catch(error => {
            console.error('Fetch error:', error);
        });
}

4.1.2 示例:获取柱状图数据

function initBarChart() {
    const chartDom = document.getElementById('barChart');
    const myChart = echarts.init(chartDom);

    fetchChartData('/api/chart/bar').then(data => {
        if (data) {
            const option = {
                title: {
                    text: data.title,
                    left: 'center'
                },
                tooltip: {
                    trigger: 'axis'
                },
                xAxis: {
                    type: 'category',
                    data: data.xAxisData
                },
                yAxis: {
                    type: 'value'
                },
                series: data.series.map(s => ({
                    name: s.name,
                    type: s.type,
                    data: s.data
                }))
            };
            myChart.setOption(option);
        }
    });
}

4.1.3 使用jQuery.ajax()(如项目中已引入jQuery)

function initLineChart() {
    const chartDom = document.getElementById('lineChart');
    const myChart = echarts.init(chartDom);

    $.ajax({
        url: '/api/chart/line',
        method: 'GET',
        dataType: 'json',
        success: function (data) {
            const option = {
                title: {
                    text: data.title,
                    left: 'center'
                },
                tooltip: {
                    trigger: 'axis'
                },
                xAxis: {
                    type: 'category',
                    data: data.xAxisData
                },
                yAxis: {
                    type: 'value'
                },
                series: data.series.map(s => ({
                    name: s.name,
                    type: s.type,
                    data: s.data,
                    smooth: true
                }))
            };
            myChart.setOption(option);
        },
        error: function (xhr, status, error) {
            console.error('AJAX error:', error);
        }
    });
}

4.2 使用ECharts API配置图表类型与样式

ECharts 提供丰富的配置项,支持多种图表类型(如 bar、line、pie、scatter、heatmap 等),并可通过 setOption() 方法进行灵活配置。

4.2.1 柱状图配置示例

const barOption = {
    title: {
        text: '月度销售额',
        left: 'center'
    },
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'shadow'
        }
    },
    xAxis: {
        type: 'category',
        data: ['1月', '2月', '3月', '4月', '5月', '6月'],
        axisLabel: {
            interval: 0,
            rotate: 30
        }
    },
    yAxis: {
        type: 'value',
        name: '销售额(万元)'
    },
    series: [{
        name: '销售额',
        type: 'bar',
        data: [120, 200, 150, 80, 70, 110],
        itemStyle: {
            color: '#5470c6'
        },
        label: {
            show: true,
            position: 'top'
        }
    }]
};

4.2.2 折线图配置示例

const lineOption = {
    title: {
        text: '季度销售趋势',
        left: 'center'
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['2024年', '2025年'],
        bottom: 0
    },
    xAxis: {
        type: 'category',
        data: ['Q1', 'Q2', 'Q3', 'Q4']
    },
    yAxis: {
        type: 'value',
        name: '销售额(万元)'
    },
    series: [
        {
            name: '2024年',
            type: 'line',
            data: [300, 450, 500, 600],
            smooth: true,
            lineStyle: {
                width: 3
            }
        },
        {
            name: '2025年',
            type: 'line',
            data: [320, 470, 530, 650],
            smooth: true,
            lineStyle: {
                width: 3,
                type: 'dashed'
            }
        }
    ]
};

4.2.3 饼图配置示例

const pieOption = {
    title: {
        text: '产品类别占比',
        left: 'center'
    },
    tooltip: {
        trigger: 'item',
        formatter: '{a} <br/>{b}: {c} ({d}%)'
    },
    legend: {
        orient: 'vertical',
        left: 'left',
        data: ['电子产品', '服装', '食品', '其他']
    },
    series: [
        {
            name: '产品类别',
            type: 'pie',
            radius: '55%',
            center: ['50%', '60%'],
            data: [
                { value: 40, name: '电子产品' },
                { value: 30, name: '服装' },
                { value: 20, name: '食品' },
                { value: 10, name: '其他' }
            ],
            emphasis: {
                itemStyle: {
                    shadowBlur: 10,
                    shadowOffsetX: 0,
                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                }
            }
        }
    ]
};

4.3 动态绑定数据并渲染图表

图表初始化后,通过 setOption() 方法将后端返回的数据动态绑定到图表中,实现图表的渲染与更新。

4.3.1 初始化图表并绑定数据

function renderChart(containerId, endpoint) {
    const chartDom = document.getElementById(containerId);
    const myChart = echarts.init(chartDom);

    fetchChartData(endpoint).then(data => {
        if (!data) return;

        const option = {
            title: {
                text: data.title,
                left: 'center'
            },
            tooltip: {},
            xAxis: {
                type: 'category',
                data: data.xAxisData || []
            },
            yAxis: {
                type: 'value'
            },
            series: data.series.map(s => ({
                name: s.name,
                type: s.type,
                data: s.data
            }))
        };

        myChart.setOption(option);
    });

    return myChart;
}

4.3.2 页面加载完成后统一初始化图表

document.addEventListener('DOMContentLoaded', function () {
    renderChart('barChart', '/api/chart/bar');
    renderChart('lineChart', '/api/chart/line');
    renderChart('pieChart', '/api/chart/pie');
});

4.3.3 支持图表自适应窗口大小

window.addEventListener('resize', function () {
    const charts = document.querySelectorAll('[id$="Chart"]');
    charts.forEach(chartDom => {
        const instance = echarts.getInstanceByDom(chartDom);
        if (instance) {
            instance.resize();
        }
    });
});

4.3.4 动态更新图表数据(如定时刷新)

setInterval(() => {
    renderChart('barChart', '/api/chart/bar');
    renderChart('lineChart', '/api/chart/line');
}, 60000); // 每60秒刷新一次

通过以上方式,前端页面可以灵活地从后端获取数据,并使用 ECharts 提供的 API 动态配置图表类型、样式和数据,实现丰富的可视化效果。

5. 示例:实现柱状图与折线图

5.1 控制器返回模拟数据

在ASP.NET Core MVC项目中,控制器负责提供图表所需的结构化数据。以下示例展示了如何在ChartController中返回柱状图和折线图所需的模拟数据。

5.1.1 柱状图数据接口

[HttpGet("bar")]
public IActionResult GetBarChartData()
{
    var data = new
    {
        title = "月度销售额统计",
        xAxisData = new[] { "1月", "2月", "3月", "4月", "5月", "6月" },
        series = new[]
        {
            new
            {
                name = "销售额",
                type = "bar",
                data = new[] { 120, 200, 150, 80, 70, 110 },
                itemStyle = new
                {
                    color = "#5470c6"
                },
                label = new
                {
                    show = true,
                    position = "top"
                }
            }
        }
    };
    return Ok(data);
}

5.1.2 折线图数据接口

[HttpGet("line")]
public IActionResult GetLineChartData()
{
    var data = new
    {
        title = "季度销售趋势对比",
        xAxisData = new[] { "Q1", "Q2", "Q3", "Q4" },
        series = new[]
        {
            new
            {
                name = "2024年",
                type = "line",
                data = new[] { 300, 450, 500, 600 },
                smooth = true,
                lineStyle = new
                {
                    width = 3,
                    color = "#91cc75"
                }
            },
            new
            {
                name = "2025年",
                type = "line",
                data = new[] { 320, 470, 530, 650 },
                smooth = true,
                lineStyle = new
                {
                    width = 3,
                    type = "dashed",
                    color = "#fac858"
                }
            }
        }
    };
    return Ok(data);
}

5.1.3 数据模型说明

  • title:图表标题,用于前端展示

  • xAxisData:X轴分类数据

  • series:图表系列数据,支持多系列对比

  • type:图表类型(bar/line/pie等)

  • data:具体数值数组

  • itemStyle / lineStyle:样式配置对象

5.2 前端页面配置ECharts图表参数

前端页面通过JavaScript获取控制器返回的数据,并配置ECharts图表参数。以下分别展示柱状图和折线图的完整配置示例。

5.2.1 柱状图配置与渲染

function initBarChart() {
    const chartDom = document.getElementById('barChart');
    const myChart = echarts.init(chartDom);

    fetch('/api/chart/bar')
        .then(response => response.json())
        .then(data => {
            const option = {
                title: {
                    text: data.title,
                    left: 'center',
                    textStyle: {
                        fontSize: 16
                    }
                },
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'shadow'
                    },
                    formatter: '{b}: {c} 万元'
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '3%',
                    containLabel: true
                },
                xAxis: {
                    type: 'category',
                    data: data.xAxisData,
                    axisLabel: {
                        interval: 0,
                        rotate: 0
                    }
                },
                yAxis: {
                    type: 'value',
                    name: '销售额(万元)',
                    nameTextStyle: {
                        padding: [0, 0, 0, 40]
                    }
                },
                series: data.series.map(s => ({
                    name: s.name,
                    type: s.type,
                    data: s.data,
                    itemStyle: s.itemStyle,
                    label: s.label
                }))
            };
            myChart.setOption(option);
        })
        .catch(error => {
            console.error('柱状图数据加载失败:', error);
        });
}

5.2.2 折线图配置与渲染

function initLineChart() {
    const chartDom = document.getElementById('lineChart');
    const myChart = echarts.init(chartDom);

    fetch('/api/chart/line')
        .then(response => response.json())
        .then(data => {
            const option = {
                title: {
                    text: data.title,
                    left: 'center',
                    textStyle: {
                        fontSize: 16
                    }
                },
                tooltip: {
                    trigger: 'axis',
                    formatter: function(params) {
                        let result = params[0].name + '<br/>';
                        params.forEach(param => {
                            result += `${param.seriesName}: ${param.value} 万元<br/>`;
                        });
                        return result;
                    }
                },
                legend: {
                    data: data.series.map(s => s.name),
                    bottom: 0
                },
                grid: {
                    left: '3%',
                    right: '4%',
                    bottom: '60px',
                    containLabel: true
                },
                xAxis: {
                    type: 'category',
                    data: data.xAxisData,
                    boundaryGap: false
                },
                yAxis: {
                    type: 'value',
                    name: '销售额(万元)'
                },
                series: data.series.map(s => ({
                    name: s.name,
                    type: s.type,
                    data: s.data,
                    smooth: s.smooth,
                    lineStyle: s.lineStyle,
                    symbol: 'circle',
                    symbolSize: 8
                }))
            };
            myChart.setOption(option);
        })
        .catch(error => {
            console.error('折线图数据加载失败:', error);
        });
}

5.2.3 图表容器HTML结构

<div class="container mt-4">
    <div class="row">
        <div class="col-lg-6 col-md-12 mb-4">
            <div class="card shadow-sm">
                <div class="card-header bg-primary text-white">
                    月度销售额柱状图
                </div>
                <div class="card-body">
                    <div id="barChart" style="width: 100%; height: 400px;"></div>
                </div>
            </div>
        </div>
        <div class="col-lg-6 col-md-12 mb-4">
            <div class="card shadow-sm">
                <div class="card-header bg-success text-white">
                    季度销售趋势折线图
                </div>
                <div class="card-body">
                    <div id="lineChart" style="width: 100%; height: 400px;"></div>
                </div>
            </div>
        </div>
    </div>
</div>

5.3 页面加载完成后初始化图表

为确保DOM元素已完全加载,图表初始化代码应在DOMContentLoaded事件触发后执行。

5.3.1 统一初始化函数

document.addEventListener('DOMContentLoaded', function () {
    initBarChart();
    initLineChart();
});

5.3.2 支持窗口大小变化自适应

window.addEventListener('resize', function () {
    const barChart = echarts.getInstanceByDom(document.getElementById('barChart'));
    const lineChart = echarts.getInstanceByDom(document.getElementById('lineChart'));

    if (barChart) barChart.resize();
    if (lineChart) lineChart.resize();
});

5.3.3 错误处理与加载提示

function initBarChart() {
    const chartDom = document.getElementById('barChart');
    const myChart = echarts.init(chartDom);

    myChart.showLoading();

    fetch('/api/chart/bar')
        .then(response => response.json())
        .then(data => {
            myChart.hideLoading();
            const option = { ... };
            myChart.setOption(option);
        })
        .catch(error => {
            myChart.hideLoading();
            myChart.showToast({
                message: '数据加载失败',
                type: 'error'
            });
            console.error(error);
        });
}

通过以上实现,柱状图与折线图可分别从后端获取数据并渲染,图表具备响应式布局、错误处理、加载提示等完整功能,满足实际项目开发需求。

6. 总结

本教程详细介绍了如何在ASP.NET Core MVC项目中集成ECharts图表库,结合Bootstrap 5实现响应式前端界面,并通过控制器返回JSON数据,完成前后端的数据交互与图表渲染。通过本教程的学习,开发者可以掌握以下内容:

6.1 项目搭建与环境配置

  • 使用.NET CLI或Visual Studio创建ASP.NET Core MVC项目,推荐使用.NET 6.0或.NET 7.0。

  • 引入Bootstrap 5与ECharts资源,支持CDN与本地两种方式。

  • 配置静态文件中间件与控制器路由,确保前后端通信正常。

  • 创建图表数据模型,统一后端返回数据结构,便于前端解析。

6.2 前端页面设计与布局

  • 使用Bootstrap 5栅格系统与卡片组件构建响应式页面结构。

  • 在页面中嵌入ECharts图表容器,并通过JavaScript初始化图表。

  • 使用fetch()$.ajax()从后端API获取数据,动态渲染图表。

  • 支持图表自适应窗口大小,提升用户体验。

6.3 后端控制器与数据接口设计

  • 创建ChartController,配置RESTful风格路由。

  • 构造符合ECharts结构的数据模型,支持柱状图、折线图、饼图等多种图表类型。

  • 使用Ok()Json()方法返回JSON数据,支持跨域请求与动态类型返回。

  • 提供模拟数据接口,便于前端开发与测试。

6.4 ECharts图表配置与渲染

  • 使用ECharts API配置图表类型、样式、提示框、坐标轴等参数。

  • 动态绑定后端返回的数据,实现图表的初始化与更新。

  • 支持图表加载提示、错误处理、定时刷新等增强功能。

  • 实现多种图表类型(柱状图、折线图、饼图等)的完整渲染流程。

6.5 示例实现:柱状图与折线图

  • 控制器返回结构化的模拟数据,支持多系列对比与样式配置。

  • 前端页面通过AJAX请求获取数据,并配置ECharts参数完成渲染。

  • 页面加载完成后统一初始化图表,支持响应式布局与窗口自适应。

  • 提供完整的错误处理与加载提示机制,增强用户体验。

通过本教程的实践,开发者可以快速掌握在ASP.NET Core MVC项目中使用ECharts构建数据可视化界面的完整流程,具备从项目搭建、前端布局、后端接口设计到图表渲染的全栈开发能力。该方案适用于企业管理系统、数据仪表盘、报表分析等多种应用场景,具有良好的扩展性与维护性。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caifox菜狐狸

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值