Git Product home page Git Product logo

blazor.echarts's Introduction

Blazor.ECharts

介绍

Blazor版本的ECharts图表组件

重新出发

本项目源自https://github.com/caopengfei/BlazorECharts,由于原作者有好长一段时间没有更新和处理PR,故在此基础上,重新做了这个

GitHub license

开源地址:https://github.com/lishewen/Blazor.ECharts

国内镜像:https://gitee.com/lishewen/Blazor.ECharts

ECharts配置请参考:

https://echarts.apache.org/examples/zh/index.html

使用方式

  1. 创建Blazor项目。
  2. 在NuGet中安装包Blazor.ECharts NuGet downloads
  3. _Imports.razor中添加@using Blazor.ECharts.Components
  4. wwwroot/index.html文件的Head中引入:
<script src="https://lib.baomitu.com/echarts/5.3.3/echarts.min.js"></script>

需要使用地图相关功能的则需要额外添加地图js的引用

<script type="text/javascript" src="https://api.map.baidu.com/api?v=2.0&ak=[Your Key Here]"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5/dist/extension/bmap.min.js"></script>
  1. wwwroot/index.html文件的Body中引入:
<script type="module" src="_content/Blazor.ECharts/core.js"></script>
  1. 修改Program.cs增加
builder.Services.AddECharts();
  1. 在页面中使用组件(可参考Demo项目)。

注意:因为没有设置默认的样式,所以需要在组件上设置Class或者Style来控制宽度和高度

Demo中也提供示范样式

.chart-container {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-start;
    padding-left: 20px;
    padding-bottom: 20px;
    padding-right: 0px;
    padding-top: 0px;
    height: 95%;
    width: 95%;
}

.chart-normal {
    border-radius: 4px;
    height: 300px;
    width: 400px;
    margin-top: 20px;
}

.chart-fill {
    width: 100%;
    height: 720px;
    margin-top: 20px;
    margin-right: 20px;
}

JS function的输出问题

由于function不是json的标准数据类型,所以json数据中若含function,则转换后,function会丢失。此库为解决这个问题通过JFuncConverter来实现转译输出。使用时传入一个JFunc对象即可。例如:

Position = new JFunc()
{
    RAW = """
    function (pt) {
        return [pt[0], '10%'];
    }
    """
}

功能实现进度

  • 公共配置
    • title
    • legend
    • grid(部分)
    • xAxis(部分)
    • yAxis(部分)
    • polar(部分)
    • radiusAxis(部分)
    • angleAxis(部分)
    • radar(部分)
    • dataZoom
    • visualMap(部分)
    • tooltip(部分)
    • axisPointer(部分)
    • toolbox(部分)
    • brush
    • geo
    • parallel
    • parallelAxis
    • singleAxis
    • timeline
    • graphic
    • calendar
    • dataset
    • aria
    • series(部分)
    • color
    • backgroundColor
    • textStyle
    • animation
    • animationThreshold
    • animationDuration
    • animationEasing
    • animationDelay
    • animationDurationUpdate
    • animationEasingUpdate
    • animationDelayUpdate
    • blendMode
    • hoverLayerThreshold
    • useUTC
  • 图表
    • 折线图(部分)
    • 柱状图(部分)
    • 饼图(部分)
    • 散点图(部分)
    • 地理坐标/地图(部分)
    • K线图(部分)
    • 雷达图(部分)
    • 盒须图
    • 热力图
    • 关系图(部分)
    • 路径图(部分)
    • 树图(部分)
    • 矩形树图(部分)
    • 旭日图(部分)
    • 平行坐标系
    • 桑基图(部分)
    • 漏斗图(部分)
    • 仪表盘(部分)
    • 象形柱图
    • 主题河流图
    • 日历坐标系
    • 词云图(使用方法:Blazor.ECharts.WordCloud/README.md)

Nuget Package中没有打包echarts.js的原因

  1. 减少包的体积
  2. 方便自由更换cdn
  3. 方便echarts小版本更新时,作者没有来得及更新Package内的js时,可自行在页面上更换

blazor.echarts's People

Contributors

aaasoft avatar abin-liu avatar andrewlei77 avatar lishewen avatar masq6r avatar qianmoxi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

blazor.echarts's Issues

删除曲线的问题

请问如何从曲线图中删除指定的曲线?
我用Option.Series.RemoveAt(i);
但是似乎曲线没有被删除。
请问有什么办法吗?能否做一个例子来说明,谢谢

Whether dynamic chart updates are supported

I would like to ask whether the current chart supports the dynamic update of data. I need to make a line chart for observing real-time data, but I haven't found anything similar in the demo. Is it not supported yet

关于dispatchAction功能

请问dispatchAction功能如何实现?能给个例子吗?
ECharts自带的例子里是这样写的: myChart.dispatchAction({...
但是在Blazor里没有myChart这样的变量。所以我不知道该怎么调用dispatchAction。

作者,您好,如何实时更新图表的亮暗主题

我看到core.js的代码会根据ID获取echarts实例,只有在初始化时设置主题才有效:

static setupChart(id, theme, option, notMerge) {
    let opt = eval('(' + option + ')');
    let chart = this.getChart(id);
    if (chart === null) {
        chart = this.initChart(id, theme);
    }
    chart.setOption(opt, notMerge);
}

如果我想在网站亮暗主题变更时也能更新图表的主题,让_funnel.Theme = "dark";实时生效,应该怎么更新?

关于拖动曲线功能

您好。我想实现用鼠标拖动曲线的功能。ECharts网上实例中提供了一个dragging points的例子。
您能否也提供一个类似的实例?
另外,我的曲线中数据点很多。我不想用例子中cicle的方法。能否直接拖动整条曲线?
谢谢

当使用EChartsOptions<T>配置图表的时候,Theme="dark"无效

当使用EChartsOptions配置图表的时候,深色模式的配置不起作用,使用OptionRaw不受影响。

重现步骤:
使用默认的Demo工程,打开后不作任何修改,启动工程,切换到/bar/bar3页面,深色模式正常;
在当前页面直接刷新浏览器,页面重新加载后,深色模式无效。

这个问题是我们在一个首页放置图表的工程发现,如果首页就使用EChartsOptions,那么无论如何,深色模式都不会生效。

总结下来就是当使用EChartsOptions配置图表,且当前页面是加载的第一个页面时,深色模式无效;
或EChartsOptions配置图表,当前页面不是第一个页面,但是刷新后深色模式无效。

Whether to support the rendering mode switching

Hello, I found that rendering is slow when drawing diagrams with large amounts of data. I see that echart supports two modes, canvas and svg, but I have not seen whether it is supported in the code

tooltip回调函数

tooltip中有个新增的回调函数valueFormatter。我按照网上例子这样写:ValueFormatter = "(value) => value.toFixed(2)" ,
在tooltip.cs中增加了 public string ValueFormatter { set; get; }
但是没有作用。tooltip不能显示了。
请您看看如何解决?谢谢

AxisLabel重要参数缺失

AxisLabel.Rotate
AxisLabel.Interval

这是轴线标签比较重要的两个属性,实际项目中极为常用,希望能添加进去,谢谢

请问X轴如果是日期类型应该如何传入数据?

如果将日期转为字符串类型,则X轴上的刻度是等间距的,不能按1天的最小单位绘制刻度。
我参考了AreaTimeAxis的示例代码,需要将日期转为UnixTimestamp,没有更好的办法吗?
谢谢!

eLine.SetupOptionAsync函数参数问题

在eLine.SetupOptionAsync函数中目前只支持一个参数opt。在echarts的手册中,还可以给第二个参数replaceMerge。比如:
chart.setOption(option, {
replaceMerge: ['xAxis', 'yAxis', 'series']
});
请问能否实现第二个参数的功能?谢谢

Can i use Boxplot in this package?

Hello, first of all, I have been using the Blazor EChart Package you created, and it's working well. I would like to use the boxplot feature in EChart, but I couldn't find the EBoxplot namespace. Could you please provide an example of how to use it? If it's possible using the general EChart class, could you also share an example for that? Thank you!

关于回调函数序列化

有部分选项接收的是回调函数,比如legend. formatter 可以接收
formatter: function (name) {
return 'Legend ' + name;
}
如果直接传字符串序列化出来不对,有没有什么办法设置呢

Support chart resizes

Hello, thanks for your efforts.
I need to resize charts (e.g. browser window resizes). I noticed that ECharts supports that via the .resize() function but I can't see a way to invoke that via this project. The ComponentBase.Refresh() doesn't do the trick.
Any plans to support this? Ideally this would be nice to work out of the box by handling it in JS maybe so that we actually don't care although manual invocation may be needed for other workflows though.

YAxis offset属性缺失

作者你好,我在设置多个Y轴的时候,发现YAxis 这个属性缺失,请问下个版本能补上吗?

点击两次查询再次才能显示正确

请问为什么我这个需要点击两次查询再次才能显示正确呢?是哪里设置不对吗?

@page "/bar/bar3"
@attribute [RouteName("ECharts 入门示例|666")]
@using Blazor.ECharts.Options
@using Blazor.ECharts.Options.Enum
@using B = Blazor.ECharts.Options.Series.Bar
@using L = Blazor.ECharts.Options.Series.Line
@using System.Data
@using System.Dynamic
@using System.Drawing
@using XYOA

<style>
    body {
        width: 100%;
        display: flex;
        flex-direction: column;
        min-height: 100vh;
    }

    .container {
        /* 设置.container元素高度 */
        height: 5vh;
        background-color: #eee;
        padding: 6px;
        display: flex;
        gap: 16px; /* 设置间距 */
    }
    .container label {margin-right: 16px; /* 设置标签之间的间距 */}

    .chart-container {
        flex: 1;
        /*--上,右,下,左-->*/
        /*margin: 36px 0px -1px -36px;*/
        /* 将.chart-container 铺满整个页面 */
        overflow: hidden;
    }
</style>
<body>
    <div class="container">
        <label>
            <input type="radio" name="chart" value="chart1" @onchange='(e => ShowSelectedChart("2020"))' checked />每天销售
        </label>
        <label>
            <input type="radio" name="chart" value="chart2" @onclick='(e => ShowSelectedChart("2021"))' />每月销售
        </label>
        <label>
            <input type="radio" name="chart" value="chart3" @onclick='(e => ShowSelectedChart("2022"))' />每年销售
        </label>
        <div><button name="btFind" class="btn btn-primary mx-6" @onclick="BtFind">查询</button></div>
        <button @onclick="ChangeTheme">切换主题 @theme</button>
    </div>
    <div class="chart-container">
        <EBar Option="@Option1" Class="flex-fill" Theme="@theme"></EBar>
    </div>
</body>
<!--
<table class="table table-striped">
    <thead>
        <tr>
            <th>月份</th>
            <th>去年</th>
            <th>今年</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var person in list)
        {
            <tr>
                <td>@person.月份</td>
                <td>@person.去年</td>
                <td>@person.今年</td>
            </tr>
        }
    </tbody>
</table>
-->
@code {
    dynamic dts;
    private EChartsOption<B.Bar> Option1;
    private string theme = "light";
    protected override async void OnInitialized()
    {
        base.OnInitialized();

        await GetDayData(2020);
    }

    protected async Task GetDayData(int year)
    {
        Option1 = new()
            {
                Grid = new()
            {
                new() { Left = "1%", Right = "1%", Bottom = "8%", ContainLabel = true }
            },
                Color = [ColorTranslator.ToHtml(Color.OrangeRed)],// 设置每个柱形的颜色
                Title = new()
                {
                    Left = "center",
                },
                Tooltip = new()
                {
                    Trigger = TooltipTrigger.Axis,
                    TriggerOn = "mousemove|click",
                    ValueFormatter = new("(value) => value.toFixed(2) + '万元'")
                },
                Legend = new Legend() { Show = true, Align = Align1.Right, Orient = Orient.Horizontal, Top = 36 },
                XAxis = new List<XAxis>()
                {
                    new XAxis(){Type=AxisType.Category, Data=dListYear }
                },
                YAxis = new()
                {
                    new(){ Type = AxisType.Value,}
                },
                Series = new()
                {
                    new B.Bar
                    {
                        Name = "今年",
                        Data=dList// 设置DataSet这里不需要再设置
                    },
                    new L.Line
                    {
                        Smooth=true,
                        Name = "去年",
                        Data=dList2
                    }
                }
            };
        string err = "";
        List<BList> list2 = [];
        try
        {
            list = SqlHelper.ExecSelect2Entity<BList>("exec PrShowDayChart '0'");//去年
            list2 = SqlHelper.ExecSelect2Entity<BList>("exec PrShowDayChart");//去年
            err = list.Count.ToString();
        }
        catch (Exception ex)
        {
            err = ex.Message;
        }
        Option1.Title.Text = $"每天销售汇总";
        // 设置每个柱形的颜色
        Option1.Color = [ColorTranslator.ToHtml(Color.OrangeRed)];
        dListYear = list.Select(obj => DateTime.Parse(obj.日期).Day.ToString()).ToArray();
        dList = list.Select(obj => obj.金额).ToArray();
        dList2 = list2.Select(obj => obj.金额).ToArray();
        (Option1.Series[0] as B.Bar).Data = dList;
        (Option1.Series[1] as L.Line).Data = dList2;
        await InvokeAsync(StateHasChanged);
    }
    protected async Task GetMonthData(int year)
    {
        Option1 = new()
            {
                Grid = new()
                {
                    new() { Left = "1%", Right = "1%", Bottom = "8%", ContainLabel = true }
                },
                Color = ["#6696ED", ColorTranslator.ToHtml(Color.OrangeRed)],// 设置每个柱形的颜色
                Title = new()
                {
                    Left = "center",
                },
                Tooltip = new()
                {
                    Trigger = TooltipTrigger.Axis,
                    TriggerOn = "mousemove|click",
                    ValueFormatter = new("(value) => value.toFixed(2) + '亿元'")
                },
                Legend = new Legend() { Show = true, Align = Align1.Right, Orient = Orient.Horizontal, Top = 36 },
                XAxis = new List<XAxis>()
                {
                    new XAxis(){Type=AxisType.Category, Data=dListYear }
                },
                YAxis = new()
                {
                    new(){ Type = AxisType.Value,}
                },
                Series = new()
                {
                    new B.Bar
                    {
                        Name = "今年",
                        Data=dList
                    },
                    new B.Bar
                    {
                        Name = "去年",
                        Data=dList2
                    }
                }
            };

        string err = "";
        try
        {
            list = SqlHelper.ExecSelect2Entity<BList>("exec PrGetMonthDataXY");
            list = list.OrderBy(item => item.月份).ToList();
            err = list.Count.ToString();
        }
        catch (Exception ex)
        {
            err = ex.Message;
        }
        Option1.Title.Text = $"每月销售汇总";
        dListYear = list.Select(obj => obj.月份).ToArray();
        dList = list.Select(obj => obj.去年).ToArray();
        dList2 = list.Select(obj => obj.今年).ToArray();
        (Option1.Series[0] as B.Bar).Data = dList;
        (Option1.Series[1] as B.Bar).Data = dList2;
        await InvokeAsync(StateHasChanged);
    }
    protected async Task GetYearData(int year)
    {
        Option1 = new EChartsOption<B.Bar>()
            {
                DataSet = new Options.DataSet
                {
                    Source = dts
                },
            Grid = new()
            {
                new() { Left = "1%", Right = "1%", Bottom = "8%", ContainLabel = true }
            },
            Color = [ColorTranslator.ToHtml(Color.OrangeRed)],// 设置每个柱形的颜色
            Title = new()
            {
                Left = "center",
            },
            Tooltip = new()
            {
                Trigger = TooltipTrigger.Axis,
                TriggerOn = "mousemove|click",
                ValueFormatter = new("(value) => value.toFixed(2) + '亿元'")
            },
            Legend = new Legend() { Show = true, Align = Align1.Right, Orient = Orient.Horizontal, Top = 36 },
            XAxis = new List<XAxis>()
            {
                new XAxis(){Type=AxisType.Category, Data=dListYear }
            },
            YAxis = new()
            {
                new(){ Type = AxisType.Value,}
            },
            Series = new()
            {
                new B.Bar
                {
                    Name = "今年",
                    Data=dList// 设置DataSet这里不需要再设置
                },
            }
            };
        string err = "";
        try
        {
            list = SqlHelper.ExecSelect2Entity<BList>("exec PrGetYearData");
            err = list.Count.ToString();
        }
        catch (Exception ex)
        {
            err = ex.Message;
        }
        Option1.Title.Text = $"每年销售汇总";
        dListYear = list.Select(obj => obj.日期).ToArray();
        dList = list.Select(obj => obj.金额).ToArray();
        (Option1.Series[0] as B.Bar).Data = dList;

        await InvokeAsync(StateHasChanged);
    }

    public class BList
    {
        public string 日期 { get; set; }
        public decimal 金额 { get; set; }
        public string 月份 { get; set; }
        public decimal 去年 { get; set; }
        public decimal 今年 { get; set; }
    }
    decimal[] dList = [];
    decimal[] dList2 = [];
    string[] dListYear = [];
    List<BList> list = [];

    private List<BList> Persons { get; set; } = new List<BList>() { };

    private async Task OnValueChanged(int year)
    {
        // TODO:需要点击两次查询再次才能显示正确
        switch (year)
        {
            case 2020:
                await GetDayData(year);
                break;
            case 2021:
                await GetMonthData(year);
                break;
            case 2022:
                await GetYearData(year);
                break;
        }
        await InvokeAsync(StateHasChanged);
    }
    private Task ChangeTheme()
    {
        theme = theme == "light" ? "dark" : "light";
        //通知组件其状态已更改。 如果适用,这将导致重新呈现组件
        StateHasChanged();
        return Task.CompletedTask;
    }
    private string selectedChart = "2020";
    private void ShowSelectedChart(string SelectType) => selectedChart = SelectType;

    private async void BtFind() => await OnValueChanged(int.Parse(selectedChart));
}

回调函数参数问题

你好。回调函数似乎只实现了鼠标消息,对于类似brush的消息,回调函数的参数里没有返回值。能否修正这个问题?谢谢

getDataURL功能的一点问题

在您给出的例子里面,getDataURL函数能够正常调用。不过这个例子是在Blazor.ECharts.Demo这个工程里,这个好像是WebAssembly。我自己的工程是Blazor Server. 我试着在Blazor.ECharts.Server.Demo这个工程里添加了ELine,然后调用getDataURL函数,页面显示“Attempting to reconnect to the server: 1 of 8”, 函数没有返回结果。
能否请您帮忙看一下问题在哪里?在Blazor Server应用里要怎么才能调用getDataURL函数?谢谢。

// counter.razor文件内容
@page "/counter"

Counter

Counter

Current count: @currentCount

<button class="btn btn-primary" @OnClick="IncrementCount">Click me

// counter.razor.cs文件内容

using Blazor.ECharts.Components;
using Blazor.ECharts.Options;
using Blazor.ECharts.Options.Enum;
using L = Blazor.ECharts.Options.Series.Line;

namespace Blazor.ECharts.Server.Demo.Pages
{
public partial class Counter
{
private int currentCount = 0;
private EChartsOption<L.Line> Option1;
ELine eLine1;

    private async void IncrementCount()
    {
        string imageSource = await eLine1.GetDataURL(new()
        {
             PixelRatio = 2,
            BackgroundColor = "#fff"
        });

        currentCount++;
    }

    protected override void OnInitialized()
    {
        base.OnInitialized();

        Option1 = new()
        {
            Title = new()
            {
                Text = "折线图"
            },
            YAxis = new()
        {
            new()
            {
                Type = AxisType.Value
            }
        },
            XAxis = new()
        {
            new()
            {
                Type = AxisType.Category,
                Data = new[] { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }
            }
        },
            Series = new()
        {
            new L.Line()
            {
                Type = "line",
                Data = new[] { 820, 932, 901, 934, 1290, 1330, 1320 }
            }
        }
        };

    }
}

}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.