热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

关于javascript:canvas-柱形图

在用uni-app做我的项目时,偶尔遇到一个中央须要柱形图,因为插件没找到适合的,本人就写了一个,分享给大家,如果有写得不好的中央,请大家多多指教。
canvas 柱形图

前言

在用uni-app做我的项目时,偶尔遇到一个中央须要柱形图,因为插件没找到适合的, 本人就写了一个,分享给大家,如果有写得不好的中央,请大家多多指教。

效果图

性能:通过X轴数组的长度,计算失去每段的宽度,从而能够实现图像宽度和地位的主动调配。通过Y轴数组最大值和最小值,计算出柱形在Y轴下面对应的坐标,从而实现图形比例调配高度。自定义宽高,未定义宽度时,自适应屏幕宽度。

绘制剖析

这个图标由xy轴、数据条形组成。

  • 轴线: 应用moveTo(x, y)lineTo(x, y)实现
  • 文字:应用fillText( text, x, y)实现
  • 长方形: 应用 fillRect(x, y, width, height )实现

实现步骤

–显示的数据

 itemsX: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月',],
 itemsY: [65, 35, 43, 77, 75, 48, 95, 80, 65, 35, 43, 77],

–定义画布

 
 

–计算Y轴上的刻度值数据

算出Y轴每段的长度,通过进行for循环,将每段的刻度值顺次保留到yScales数组中

Y轴每段长度 = (y轴最大值 – y轴最小值) / 总段数

getyScale () { 
      let length = (this.maxNum - this.yAxisMinNum) / this.yNumber 
      for (let index = 0; index 

–x轴和y轴的每段长度

计算出xy轴每段的长度,再通过for循环,每段的长度乘以for循环的索引值就能够失去每段在Y轴线和Y轴线上的坐标点

padding是给文字预留边距

XY轴每段长度 = (总长度 – 两边的边距)/ 总的段数

this.xLength = Math.floor((this.canvasWidth - this.padding * 2) / this.itemsX.length)
this.yLength = Math.floor((this.height - this.padding * 2) / this.yNumber)

–绘制刻度和刻度值

1.计算在轴线上的坐标点
坐标点 = 每段长度 * 对应第几段的索引值

let newlength = length * (index + 1)

2.绘制刻度

通过context.moveTo()context.lineTo()绘制刻度

context.moveTo(this.padding + newlength, this.height - this.padding)
context.lineTo(this.padding + newlength, this.height - this.padding + 5) 

3.绘制刻度值

刻度值通过for循环的在数组中失去对应的值,同时因为点位会间接定到轴线上,所应依据状况,增加偏移量

 context.fillText(items[index], this.padding - 15, this.height - this.padding - newlength + 5);

–绘制柱形图

1.计算柱形图高度

总高度减去预留两边的预留边距 乘以 Y轴数组的值除以总高度

通过去除边距的总高度Y轴对应刻度的值除以最大值的百分比计算出每个

柱形图的高度 = (总高度 – 两边边距)* ((Y轴对应的刻度值 – Y轴最小值)/ (Y轴最大值 – Y轴最小值)

let yHeight = Math.ceil((this.height - (this.padding * 2)) * ((this.itemsY[index] - this.yAxisMinNum) / (this.maxNum - this.yAxisMinNum)))  

2.计算fillRecty轴坐标值

因为canvas起始坐标(0,0)是左上角,所以要用总高度减去下方边距减去柱状图边距,从而失去y轴的坐标

let y = this.height - this.padding -yHeight 

3.计算fillRectx轴坐标值和宽度

宽度是每段长度的一半,所以为了保障图像在每段居中,x轴的坐标值就须要在每段4分之1的地位开始,因而在索引值前面须要加上一个0.25

let xWidth = this.xLength / 2let x = this.padding + this.xLength * (index + 0.25)

4.绘制柱形图

将计算的z,y坐标和对应的宽度长度填入context.fillRect()

context.fillRect(x, y, this.xLength / 2, yHeight,)

残缺代码

属性名 类型 默认值 是否必须 阐明
itemsX Array [ ] x轴显示数据
itemsY Array [ ] y轴显示数据
maxNumy Number y轴显示数据最大值 y轴刻度值最大值,小于y轴显示数据最大值时,替换为y轴显示最大值
minNumy Number 0 y轴刻度值最小值,大于y轴显示数据最小值时,替换为y轴显示最小值
width Number 屏幕宽度 图像宽度
height Number 500 图像高度
padding Number 30 图像边距
graphColor String ‘#000000’ 柱形图色彩
   data () {    return {      //自定义的变量      itemsX: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月',],      itemsY: [65, 35, 43, 77, 75, 48, 95, 80, 65, 35, 43, 77],      maxNumy: 0,      minNumy: 0,      width: 768,      height: 500,      yNumber: 5,      padding: 30,      graphColor: '#72f6ff',              //非自定义      yScales: [], //y轴上刻度值数组      xLength: '', //x轴每段长度      yLength: '', //y轴每段长度      scaleIntervalMax: '',  //y轴刻度值最大值      scaleIntervalMin: '',  //y轴刻度值最小值    }  },  computed: {    yAxisMinNum () { // 判断最小值是否大于itmsY数组中的最小值,大于则替换      return this.minNumy  this.maxNumy ? this.getMaxNum(this.itemsY) : this.maxNumy      this.scaleIntervalMin = this.getMinNum(this.itemsY)    this.getyScale()    this.getSingleLengths()    this.drawCanvas()  },  methods: {    getyScale () { // 取得y轴上刻度值数组      let length = (this.scaleIntervalMax - this.yAxisMinNum) / this.yNumber      for (let index = 0; index  num ? num = cur : null      }      return num    },    getMinNum (items) {      let num = items[0]      let cur      for (let i = 1; i 

推荐阅读
author-avatar
君与龙_501
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有