适合前端新手做的网站,网站建设区域代理,成都手机网站建设报价表,电子商务网站推广计划本期大纲 1、确定纵坐标的范围并绘制 2、根据真实数据绘制折线 相关阅读#xff1a;在微信小程序中绘制图表#xff08;part1#xff09;在微信小程序中绘制图表#xff08;part3#xff09; 关注我的 github 项目 查看完整代码。 确定纵坐标的范围并绘制 为了避免纵坐标的… 本期大纲 1、确定纵坐标的范围并绘制 2、根据真实数据绘制折线 相关阅读在微信小程序中绘制图表part1在微信小程序中绘制图表part3 关注我的 github 项目 查看完整代码。 确定纵坐标的范围并绘制 为了避免纵坐标的刻度出现小数的情况我们把纵坐标分为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轴可以参看 part1 中X轴的绘制方法此处不再累赘。 Y轴效果图 opts {...series: [{...data: [15, 20, 45, 37, 4, 80]}, {...data: [70, 40, 65, 100, 34, 18]}]
} 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]}]
} 效果还不错我们接着往下 根据真实数据绘制折线 问题的关键在于确定每个数据点的(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轴的范围已经本身的数值进行计算得出。 所以我们计算出的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);
} 现在我们已经确定了数据点在画布上的绘制坐标关于如何绘制折现请查看 part1 中相关内容此处不再累赘。 最终效果图如下 预告下一部分我们一起讨论绘制过程中的一些技巧、动画效果和如何工程化我们的项目。 相关阅读 在微信小程序中绘制图表part1在微信小程序中绘制图表part3