博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Javascript图表插件HighCharts用法案例
阅读量:6924 次
发布时间:2019-06-27

本文共 13394 字,大约阅读时间需要 44 分钟。

最近还在忙着基于ABP的项目,但本篇博客和ABP无关,喜欢ABP框架的朋友请点击

这不,最近项目基本功能做的差不多了,现在在做一个数据统计的功能,需要绘制区域图(或折线图)和饼图。一开始,楼主就去Google了一下最常用的绘图插件都有哪些,最后直接去Github上搜索关键词chart,搜索结果如下:

png

点了几个进去看了之后,楼主考虑到项目要以后肯定要维护,万一维护的开发者英文不咋地呢(其实楼主我是喜欢看英文文档的)?所以,我起初选择了某度出品的Echarts.js。但是选择了它之后,查看文档学习,虽然文档是中文的,但我感觉这文档比英文还难读懂,因为有些术语解释不详细,最后好不容易做了个demo,但还出现了bug,开了一个,维护人员简单地敷衍之后反而直接给关了,楼主表示很受伤也很气愤。心想,好吧,你某度牛逼,我不用你的Echarts行了吧,惹不起还躲不起嘛。

最后,经过几个朋友的介绍,他们都选择的Highcharts,去Highcharts官网看了下,感觉文档就是比Echarts详细,简单易懂,所以我也就选择了她。【这里建议新手朋友们先使用Highcharts,等对图表熟悉了再使用Echarts,毕竟Echarts的图表种类很丰富】而且,到现在,功能也都实现了,效果如下:

图片

图片

楼主在学习的时候,发现网上这方面的资料也不是很多,尤其是从服务端如何传数据到客户端,没有详细的解决方案,也是摸索了很久,这次,我直接将自己的解决方案拿出来和大家分享,供初学者参考,少走弯路,大神请绕道。

区域图

收入趋势
var dateSpan;        Highcharts.setOptions({            lang: {                printChart: '打印图表',                downloadJPEG: '下载为JPEG图片',                downloadPDF: '下载为PDF',                downloadPNG: '下载为PNG图片',                downloadSVG: '下载为SVG矢量图',                months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],                weekdays: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],                shortMonths: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],            }        });        var isByDay = true;//default by days        var option = {            chart: {                type: 'area'            },            title: {                text: '收入趋势图'            },            subtitle: {                text: '没有选择时间范围的话,默认显示最近7天的数据'            },            credits: {                enabled: false            },            xAxis: {                type: 'datetime',                tickmarkPlacement: 'on',                title: {                    enabled: false                },                dateTimeLabelFormats: {                    day: "%Y-%m-%d",                    week: "%A",                    month: "%Y-%m",                    year: "%Y"                }            },            yAxis: {                title: {                    text: '单位:元'                },                labels: {                    formatter: function () {                        return this.value;                    }                }            },            tooltip: {                shared: true,                valueSuffix: ' 元',                dateTimeLabelFormats: {                    day: "%Y-%m-%d,%A",                    week: "%A开始, %Y-%m-%d",                    month: "%Y-%m",                    year: "%Y"                }            },            plotOptions: {                area: {                    stacking: 'normal',                    lineColor: '#666666',                    lineWidth: 1,                    marker: {                        lineWidth: 1,                        lineColor: '#666666'                    }                },                series: {                    //pointStart: Date.UTC(nowDate.getFullYear(), nowDate.getMonth(), nowDate.getDate() - 7),                    //pointInterval: 24 * 36e5 //一天                }            },            series: [{}]        }        var url = getTargetUrl('Dashboard', "GetJsonResult");//这里是url        var drp = $('#dateRange').data('daterangepicker');        if (!dateSpan) {            dateSpan = { start: drp.startDate.format('YYYY-MM-DD'), end: drp.endDate.format('YYYY-MM-DD') }        }        rawChart(isByDay);        $('#createChart').click(function (e) {            if ($('#byMonth').attr('checked')) {//按月                isByDay = false;                //alert('选择了' + $('#byMonth').attr('checked'));            }            e.preventDefault();            drawChart(isByDay);            drawPieChart(isByDay);        });        $('#defaultChart').click(function (e) {            e.preventDefault();            drp.setStartDate(moment().subtract(7, "days"));            drp.setEndDate(moment().subtract(1, "days"));            dateSpan = { start: drp.startDate.format('YYYY-MM-DD'), end: drp.endDate.format('YYYY-MM-DD') };            $('#dateRange').val('');            isByDay = true;            drawChart(isByDay);            drawPieChart(isByDay);        });        function drawChart(isByDay) {            var year = moment(dateSpan.start).format('YYYY');            var month = moment(dateSpan.start).format('M') - 1;//js的date函数的月份是从0-11,所以这里减1            var day = moment(dateSpan.start).format('D');            //console.log(year,month,day);            if (isByDay) {                $.getJSON(url, dateSpan, function (datas) {                    option.series = datas;                    option.plotOptions.series.pointStart = Date.UTC(year, month, day);                    option.plotOptions.series.pointInterval = 24 * 36e5;                    $('#incomeTrend').highcharts(option);                });            } else {                var start = drp.startDate.format('YYYY-MM');                var end = drp.endDate.format('YYYY-MM');                if (start == end) {                    start = drp.startDate.subtract(5, "month").format('YYYY-MM');                }                year = moment(start).format('YYYY');                month = moment(start).format('M')-1;                dateSpan = { start: start, end: end };                $.getJSON(url, dateSpan, function (datas) {                    option.series = datas;                    option.plotOptions.series.pointStart = Date.UTC(year, month, 1);                    option.plotOptions.series.pointInterval = 1;                    option.plotOptions.series.pointIntervalUnit = "month";                    $('#incomeTrend').highcharts(option);                });            }        }

注意: 区域图和饼图公用同一个action,所以代码一起放到最后。

饼图

收入比例
var pieChartOption = {            chart: {                plotBackgroundColor: null,                plotBorderWidth: null,                plotShadow: false,                type: 'pie'            },            title: {                text: ''            },            credits: {                enabled: false            },            tooltip: {                pointFormat: '{series.name}: {point.percentage:.1f}%'            },            plotOptions: {                pie: {                    allowPointSelect: true,                    cursor: 'pointer',                    dataLabels: {                        enabled: true,                        format: '{point.name}: {point.percentage:.1f}%
{y}元 ', style: { color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black' } } } }, series: [ { name: '占比', colorByPoint: true, data: [] } ] }; function drawPieChart() { var year = moment(dateSpan.start).format('YYYY'); var month = moment(dateSpan.start).format('M') - 1;//js的date函数的月份是从0-11,所以这里减1 var day = moment(dateSpan.start).format('D'); //console.log(year,month,day); $.getJSON(url + "?chartType=pie", dateSpan, function (datas) { pieChartOption.series[0].data = datas; var sum=0; for (var i = 0; i < datas.length; i++) { sum += datas[i].y; } pieChartOption.title.text = "收入比例情况:(总收入"+sum+")元"; $('#incomeRatio').highcharts(pieChartOption); }); } drawPieChart();

服务端Web层的C#代码如下:

public async Task
GetJsonResult(string start, string end) { string dataJsonStr; var defaultStart = DateTime.Parse(start); var defaultEnd = DateTime.Parse(end); var timeSpan = new DateTimeSpan { Start = defaultStart, End = defaultEnd }; var totalIncomeList = await _orderAppService.GetDateIncome(new GetDateIncomeDto { Start = defaultStart, End = defaultEnd });//总收入 var scanCodeChargeIncomeList = await _orderAppService.GetDateIncome(new GetDateIncomeDto { Start = defaultStart, End = defaultEnd, IsScanCodeChargingIncome = true });//扫码充电收入 var lineSoldIncomeList = await _orderAppService.GetDateIncome(new GetDateIncomeDto { Start = defaultStart, End = defaultEnd, IsLineSoldIncome = true });//售线收入 var castCoinsIncomeList = await _castCoinsAppService.GetDateCoinsIncome(new GetDateCoinsIncomeDto { Start = defaultStart, End = defaultEnd });//投币收入 var allKindsOfIncomeList = new List
{ new DateIncomeListWithName { DateIncomeDtos = castCoinsIncomeList, Name = "投币" }, new DateIncomeListWithName { DateIncomeDtos = lineSoldIncomeList, Name = "售线" }, new DateIncomeListWithName { DateIncomeDtos = scanCodeChargeIncomeList, Name = "扫码充电" } }; if (Request.QueryString.Get("chartType") == "pie")//饼图 { var pieDataList = new List
(); GetPieChartData(pieDataList, allKindsOfIncomeList); dataJsonStr = JsonConvert.SerializeObject(pieDataList, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() }); } else { var dataList = new List
(); allKindsOfIncomeList.Add(new DateIncomeListWithName{DateIncomeDtos = totalIncomeList,Name = "总收入"}); GetData(dataList,allKindsOfIncomeList,timeSpan); dataJsonStr = JsonConvert.SerializeObject(dataList, new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() }); } return Content(dataJsonStr); } private void GetData(List
dataList, List
incomeList, DateTimeSpan span) { var dateList = ConvertTimeSpanToList(span); foreach (DateIncomeListWithName dateIncomeListWithName in incomeList) { var newList = CheckoutIncomeList(dateIncomeListWithName.DateIncomeDtos, dateList); var list = newList.Select(dateIncomeDto => dateIncomeDto.Income).ToList(); dataList.Add(new ChartDataFormat { Name = dateIncomeListWithName.Name, Data = list }); } } private void GetPieChartData(List
dataList, List
incomeLists) { foreach (DateIncomeListWithName dateIncomeListWithName in incomeLists) { var total = dateIncomeListWithName.DateIncomeDtos.Sum(i => i.Income); var item = new PieChartDataFormat { Name = dateIncomeListWithName.Name, Y = total }; dataList.Add(item); } } List
CheckoutIncomeList(List
incomeList, List
dateList) { var newIncomeList = new List
(); newIncomeList = (from date in dateList join incomeDto in incomeList on date.Date equals incomeDto.Date into result from r in result.DefaultIfEmpty() select new DateIncomeDto { Date = date.Date, Income = r == null ? 0 : r.Income }).ToList(); return newIncomeList; } private List
ConvertTimeSpanToList(DateTimeSpan span) { var list = new List
(); for (DateTime i = span.Start; i <= span.End; i = i.AddDays(1)) { list.Add(i); } return list; }

上面这段代码,楼主自认为封装的还不错,很简洁(这已经成为楼主编程追求的目标),平均每个方法10行左右(除了第一个),仅供大家参考。

下面两个类定义了两种图表从Server端到Client端的数据格式 :

class ChartDataFormat    {        public string Name { get; set; }        public List
Data { get; set; } } class PieChartDataFormat { public string Name { get; set; } public decimal Y { get; set; } }

应用服务层也贴一个方法的代码,仅供参考

public async Task
> GetDateIncome(GetDateIncomeDto input) { var query= _orderRepository.GetAll() .Where(o => o.Status == OrderStatus.Freezen || o.Status == OrderStatus.Settled || o.Status == OrderStatus.HasInformedDevice) .Where(o => o.OrderDate >= input.Start && o.OrderDate <= input.End) .WhereIf(input.IsLineSoldIncome,o=>o.OrderType==OrderType.LineSold) .WhereIf(input.IsScanCodeChargingIncome,o=>o.OrderType==OrderType.Charge) .OrderBy(o => DbFunctions.TruncateTime(o.OrderDate)) .GroupBy(o => DbFunctions.TruncateTime(o.OrderDate)) .Select(group => new DateIncomeDto{Date=group.Key.Value,Income=group.Sum(item=>item.PayFee??0)}); var list = await query.ToListAsync(); return list; }

这些就是整个图表的实现方案,切记仅供参考,不可生搬硬套,如因程序bug导致您公司的重大损失,本人一概不负责任。此话莫当真,纯属娱乐一下。

转载地址:http://uhcjl.baihongyu.com/

你可能感兴趣的文章
utf8_bin跟utf8_general_ci的区别
查看>>
RDIFramework.NET ━ .NET快速信息化系统开发框架钜献 V2.9 版本震撼发布
查看>>
404页面怎么做
查看>>
解释服务器地址
查看>>
我的友情链接
查看>>
jquery validate 详解
查看>>
Java记录 -30- 包装类
查看>>
TurboMail邮件服务器,最懂您的邮件系统!
查看>>
js 异步加流加载
查看>>
QQ一键退朝效果
查看>>
man手册的基本使用
查看>>
ios9---通讯录权限
查看>>
我的友情链接
查看>>
oracle锁表查询及解锁
查看>>
ngnix之日志管理
查看>>
[置顶] Jquery乱码终极解决方案
查看>>
子网掩码、ip地址、主机号、网络号、网络地址、广播地址
查看>>
SplashScreen
查看>>
前端框架前景和后续发展预测
查看>>
UIPickerView 滚动选择器
查看>>