本期大纲
1、饼图绘制
2、如何添加动画效果
3、使用rollup
构建项目
相关阅读:
在微信小程序中绘制图表(part1)
在微信小程序中绘制图表(part2)
关注我的 github 项目 查看完整代码。
很久没更新了,最近事情比较多,今天来把坑填上!
饼图绘制
先看一下API
下面开始(使用ES6语法编写,后面我们可以使用rollup
编译成ES5的语法)
假设我们有这样的数据
const series = [
{data: 15, color: '#7cb5ec'},
{data: 35, color: '#f7a35c'},
{data: 78, color: '#434348'},
{data: 63, color: '#90ed7d'}
];
计算出各项所占的比例和开始的弧度
calPieData.js
export function calPieAngle (series) {
// 计算数据总和
let count = 0;
series.forEach((item) => {
count += item.data;
});
// 计算出开始的弧度和所占比例
let startAngle = 0;
return series.map((item) => {
item.proportion = item.data / count;
item.startAngle = startAngle;
startAngle += 2 * Math.PI * item.proportion;
return item;
});
}
数据已经计算出来了,下面让我开始绘制吧
drawPieChart.js
import { calPieAngle } from 'calPieData'
export default function drawPieChart (series) {
...
let pieSeries = calPieAngle(series);
pieSeries.forEach((item) => {
context.beginPath();
// 设置填充颜色
context.setFillStyle(item.color);
// 移动到原点
context.moveTo(100, 100);
// 绘制弧度
context.arc(100, 100, 80, item.startAngle, item.startAngle + 2 * Math.PI * item.proportion);
context.closePath();
context.fill();
});
...
}
调用drawPieChart(series)
就可以得到下面的结果:
很简单是不是,下面我们给各区块加上一个白色的分割线
因为arc
实际上是绘制了一条路径,所以我们简单的stroke
描边一下就可以了
...
context.setLineWidth(2);
context.setStrokeStyle('#ffffff');
pieSeries.forEach((item) => {
context.beginPath();
context.setFillStyle(item.color);
context.moveTo(100, 100);
context.arc(100, 100, 80, item.startAngle, item.startAngle + 2 * Math.PI * item.proportion);
context.closePath();
context.fill();
context.stroke();
})
...
添加动画效果
首先让我们创建一个动画工具,这个动画工具能够传入一些自定义的参数,比如动画时间,能够有动画每一步的回调以及动画结束的回调
animation.js
export default function Animation (opts) {
// 处理用户传入的动画时间,默认为1000ms
// 因为用户有可能传入duration为0,所以不能用opts.duration = opts.duration || 1000 来做默认值处理
// 否则用户传入0也会处理成默认值1000
opts.duration = typeof opts.duration === 'undefined' ? 1000 : opts.duration;
let startTimeStamp = null;
function step (timestamp) {
if (startTimeStamp === null) {
startTimeStamp = timestamp;
}
if (timestamp - startTimeStamp < opts.duration) {
// 计算出动画的进度
let process = (timestamp - startTimeStamp) / opts.duration;
// 触发动画每一步的回调,传入进度process
opts.onProcess && opts.onProcess(process);
// 动画进行中,执行下一次动画
requestAnimationFrame(step);
} else {
// 动画结束
opts.onProcess && opts.onProcess(1);
// 触发动画结束回调
opts.onAnimationFinish && opts.onAnimationFinish();
}
}
requestAnimationFrame(step);
}
动画使用了requestAnimationFrame
,并且已经满足了我们上面定义的需求
在实战中,此处的动画都是线性
的,一般我们还会加入缓动
选项,比如缓入
,缓出
,还有一点,在微信小程序真机中IOS设备是不支持requestAnimationFrame
的,所以要做降级处理,使用setTimeout
,查看完整的代码
下面我们调用animation来完成动画效果
app.js
import Animation from 'animation'
import drawPieChart from 'drawPieChart'
Animation({
duration: 1000,
onProcess: (process) => {
drawPieDataChart(series, process);
}
});
修改一下drawPieDataChart
function,能够接受process
参数
...
export default function drawPieChart (series, process = 1) {
...
// 将process传入给calPieAngle,计算出对应进度下的图表角度数据
let pieSeries = calPieAngle(series, process);
...
同样,修改一下calPieAngle
function,能够接受process
参数
export function calPieAngle (series, process = 1) {
...
// 计算出开始的弧度和所占比例
let startAngle = 0;
return series.map((item) => {
// 计算出当前动画进度的比例
item.proportion = item.data / count * process;
item.startAngle = startAngle;
startAngle += 2 * Math.PI * item.proportion;
return item;
});
}
好了,现在我们的动画就可以动起来了,类似这样
使用rollup
构建项目
Rollup is a next-generation JavaScript module bundler. Author your app or library using ES2015 modules, then efficiently bundle them up into a single file for use in browsers and Node.js.
也就是说rollup是一个前端构建工具,能够将我们的整个项目合并输出成一个最终的编译结果,上面我们编写代码的时候都是按照不同的功能放到不同的文件中,这样有利于后期的可持续性开发和维护,rollup正好能帮助我们构建出最后的编译结果
先安装rollup
npm install -g rollup
添加对ES6的支持
npm install --save-dev rollup-plugin-babel
npm install --save-dev babel-preset-es2015-rollup
创建.babelrc
文件在项目根目录,告诉babel
转义时使用哪个presets
{
"presets": ["es2015-rollup"],
}
好了剩下最后一步,定义我们的rollup.config.js
配置文件
import babel from 'rollup-plugin-babel';
export default {
// 入口文件
entry: 'app.js',
// 输出格式,这里使用commonJS
format: 'cjs',
// 输出文件
dest: 'dist/charts.js',
// 使用babel进行ES6转ES5
plugins: [
babel({
exclude: 'node_modules/**',
})
]
};
rollup会从入口文件开始,查找我们的依赖(import
),逐级往下深入,把依赖的文件全部收集起来并合并到一起,最后输出到我们定义的dest
文件中
执行
rollup -c
好了,我们就得到了我们最后的项目编译文件charts.js
下期预告
下一期中我一起讨论下有技术含量的内容,关于图表中文案显示的检测碰撞
问题,大概效果会是这样的,红框部分文案发生了碰撞,这里完成了避让,能够正常显示