博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在微信小程序中绘制图表(part2)
阅读量:5949 次
发布时间:2019-06-19

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

本期大纲

1、确定纵坐标的范围并绘制

2、根据真实数据绘制折线

相关阅读:

关注我的 项目 查看完整代码。

确定纵坐标的范围并绘制

为了避免纵坐标的刻度出现小数的情况,我们把纵坐标分为5个区块,我们取最小单位刻度为例如10(能够被5整除),当然真实情况会比这复杂,待会儿我们再讨论。

所以我们的处理输入输出应该是下面的结果

(5, 34.1)  => (10, 40)(10, 34)   => (10, 40)(-5.1, 40) => (-10, 40)
// 确定Y轴取值范围function findRange (num, type, limit) {    limit = limit || 10;        // upper向上查找,lower向下查找    type = type ? type : 'upper';    // 进行取整操作,避免while时进入死循环    if (type === 'upper') {        num = Math.ceil(num);    } else {        num = Math.floor(num);    }    while (num % limit !== 0) {        if (type === 'upper') {            num++;        } else {            num--;        }    }    return num;}

好了,初步的确定范围已经完成了,但是细想一下这个范围还是不是很理想,比如用户传入的数据都是小数级别的,比如 (0.2, 0.8),我们输出的范围是(0, 5)这个范围偏大,图表展现的效果则会是上面有大部分的留白,同样用户输入的数据很大,比如(10000, 18000),我们得到的范围是(10000, 18010),这个范围则没什么意义,所以我们需要根据传入的数据的范围来分别确定我们的最小单位刻度。

规定我们的参数格式是这样的:

opts = {    ...    series: [{            ...            data: [15, 20, 45, 37, 4, 80]        }, {            ...            data: [70, 40, 65, 100, 34, 18]        }    ]}

让我们继续进行优化

// 合并数据,将series中的每项data整合到一个数组当中function dataCombine(series) {    return series.reduce(function(a, b) {        return (a.data ? a.data : a).concat(b.data);    }, []);}// 根据数据范围确定最小单位刻度function getLimit (maxData, minData)    var limit = 0;    var range = maxData - minData;    if (range >= 10000) {        limit = 1000;    } else if (range >= 1000) {        limit = 100;    } else if (range >= 100) {        limit = 10;    } else if (range >= 10) {        limit = 5;    } else if (range >= 1) {        limit = 1;    } else if (range >= 0.1) {        limit = 0.1;    } else {        limit = 0.01;    }}var dataList = dataCombine(opts.series);// 获取传入数据的最小值var minData = Math.min.apply(this, dataList);// 获取传入数据的最大值var maxData = Math.max.apply(this, dataList);var limit = getLimit(maxData, minData);var minRange = findRange(minData, 'lower', limit);var maxRange = findRange(maxData, 'upper', limit);

现在我们动态的确定除了合适的最小刻度范围,接下来我们接着优化一下上面的findRange方法,主要是增加对小数的支持

function findRange (num, type, limit) {    limit = limit || 10;    type = type ? type : 'upper';    var multiple = 1;    while (limit < 1) {        limit *= 10;        multiple *= 10;    }    if (type === 'upper') {        num = Math.ceil(num * multiple);    } else {        num = Math.floor(num * multiple);    }    while (num % limit !== 0) {        if (type === 'upper') {            num++;        } else {            num--;        }    }    return num / multiple;}

现在我们已经确定好了Y轴的取值范围,关于如何画出Y轴可以参看 中X轴的绘制方法,此处不再累赘。

Y轴效果图:

opts = {    ...    series: [{            ...            data: [15, 20, 45, 37, 4, 80]        }, {            ...            data: [70, 40, 65, 100, 34, 18]        }    ]}

clipboard.png

opts = {    ...    series: [{            ...            data: [0.15, 0.2, 0.45, 0.37, 0.4, 0.8]        }, {            ...            data: [0.30, 0.37, 0.65, 0.78, 0.69, 0.94]        }    ]}

clipboard.png

效果还不错,我们接着往下

根据真实数据绘制折线

问题的关键在于确定每个数据点的(x, y)坐标,x坐标比较好确定,我们根据画布的宽度以及opts.categories即可确定。

规定我们的配置为:

config = {    xAxisHeight: 30, // X轴高度    yAxisWdith: 30   // Y轴宽度}
var data = [15, 20, 45, 37, 4, 80];var xPoints = [];var validWidth = opts.width - config.yAxisWidth;var eachSpace = validWidth / opts.categories.length;var start = config.yAxisWidth;data.forEach(function (item, index) {    xPoints.push(start + (index + 0.5) * eachSpace);});

y坐标稍微会复杂一点,需要根据Y轴的范围已经本身的数值进行计算得出。

clipboard.png

所以我们计算出的y应该为

y = validHeight * (data - min) / (max - min);// 由于canvas画布是左上角为原点坐标,故我们变化一下// 得到最终的y绘制点y = valideHeight - y;

代码如下:

var data = [15, 20, 45, 37, 4, 80];var yPoints = [];var validHeight = opts.height - config.xAxisHeight;data.forEach(function(item) {    var y = validHeight * (item - min) / (max - min);    y = validHeight - y;    yPoints.push(y);}

现在我们已经确定了数据点在画布上的绘制坐标,关于如何绘制折现请查看 中相关内容,此处不再累赘。

最终效果图如下:

clipboard.png

预告:下一部分我们一起讨论绘制过程中的一些技巧、动画效果和如何工程化我们的项目。

相关阅读

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

你可能感兴趣的文章
lombok
查看>>
Dev-FAT-UAT-PRO
查看>>
Maven, IntellJ Idea 配置注意点
查看>>
Android开发学习总结(五)——Android应用目录结构分析(转)
查看>>
观察者模式
查看>>
python操作excel (openpyxl)
查看>>
[PHP]PHP rpc框架hprose测试
查看>>
Atom 编辑器系列视频课程
查看>>
C#三种定时器
查看>>
范数 L1 L2
查看>>
协同过滤及大数据处理
查看>>
Java8 本地DateTime API
查看>>
jQuery 增加 删除 修改select option
查看>>
[原][osgearth]osgearthviewer读取earth文件,代码解析(earth文件读取的一帧)
查看>>
springboot 常用插件
查看>>
一个基于特征向量的近似网页去重算法——term用SVM人工提取训练,基于term的特征向量,倒排索引查询相似文档,同时利用cos计算相似度...
查看>>
[转]Newtonsoft.Json高级用法
查看>>
35个Java代码性能优化总结
查看>>
Spring+SpringMVC+MyBatis+easyUI整合基础篇(一)项目简述及技术选型介绍
查看>>
第一百五十一节,封装库--JavaScript,表单验证--密码确认验证--回答验证--电子邮件验证加自动补全...
查看>>