实现效果图 页面调用方式
<view class="ponet_warp">
<view class="titel_name">环形百分比</view>
<annulus heights="{{heights}}" bfbNumber="{{bfb}}"></annulus>
</view>
<view class="ponet_warp">
<view class="titel_name">折线图</view>
<brokens heights="{{heights}}" nameArr="{{nameArr}}" valueArr="{{valueArr}}" ></brokens>
</view>
页面CSS
.ponet_warp{
display: flex;
flex-direction: column;
width: 100%;
justify-content: center;
align-items: center;
}
.titel_name{
width: 94%;
margin-left: 3%;
padding: 10px 0px;
font-size: 24px;
font-weight: 700;
}
页面JSON
{
"usingComponents": {
"annulus":"/component/annulus/annulus",
"brokens":"/component/brokens/brokens"
}
}
环形图组件代码
Component({
/**
* 组件的属性列表
*/
properties: {
/**
* 高度
*/
heights:{
type:Number,
value:300,
},
/**
* 百分比
*/
bfbNumber:{
type:Number,
value:0,
},
/**
* 圆弧半径
*/
rNumber:{
type:Number,
value:80
},
annuColor:{
type:String,
value:'#FF0000'
}
},
attached(){
this.createArc();
},
/**
* 组件的初始数据
*/
data: {
canvasWidth:0,
},
/**
* 组件的方法列表
*/
methods: {
createArc(){
let that =this;
let canvasWidth = 0;
wx.getSystemInfo({
success: function (res) {
canvasWidth = res.windowWidth - 56
that.setData({
canvasWidth
})
},
})
let num = that.properties.bfbNumber;
let rNumber = that.properties.rNumber;
let canvasHeight = that.properties.heights;
let annuColor = that.properties.annuColor;
if(num > 100){
num = 100
}
const ctx = wx.createCanvasContext('arc', this)
ctx.beginPath()
ctx.strokeStyle='#c0c0c0'
ctx.lineWidth = 7
ctx.arc(canvasWidth / 2 ,canvasHeight / 2 , rNumber, 0, Math.PI*2)
ctx.stroke()
ctx.beginPath()
ctx.strokeStyle= annuColor
ctx.arc(canvasWidth / 2 , canvasHeight / 2 , rNumber,Math.PI *1.5,(Math.PI * 2 / 100) * num + (Math.PI*1.5))
ctx.stroke()
ctx.draw()
},
}
})
环形图wxml
<canvas canvas-id="arc" style='width:{{canvasWidth}}px; height:{{heights}}px'></canvas>
折线图组件代码
// component/brokens/brokens.js
Component({
/**
* 组件的属性列表
*/
properties: {
/**
* 高度
*/
heights: {
type: Number,
value: 300,
},
valueArr: {
type: Array,
value: [],
},
nameArr: {
type: Array,
value: [],
},
colorArr:{
type:Array,
value:['#e54d42','#f37b1d','#fbbd08','#8dc63f','#39b54a','#1cbbb4','#0081ff']
}
},
/**
* 组件的初始数据
*/
data: {
canvasWidth:0,
},
attached() {
this.createLineCanvas();
},
/**
* 组件的方法列表
*/
methods: {
createLineCanvas() {
let that =this;
let canvasWidth = 0;
wx.getSystemInfo({
success: function (res) {
canvasWidth = res.windowWidth - 56
that.setData({
canvasWidth
})
},
})
let nameArr = that.properties.nameArr;
let valueArr = that.properties.valueArr;
let colorArr = that.properties.colorArr;
let heights = that.properties.heights - 20;
let maxData = this.getGroupAndMax(valueArr);
let hme = heights / maxData.max
let wme = canvasWidth / nameArr.length
const ctx = wx.createCanvasContext('linecanvas', this)
//底部字段
ctx.beginPath()
ctx.setTextAlign('center')
nameArr.forEach((item,index) =>{
ctx.fillText(item,wme * index +20,heights)
})
ctx.stroke();
//线段
valueArr.forEach((item,ind) =>{
ctx.lineWidth = 1;
ctx.beginPath()
ctx.strokeStyle= colorArr[ind]
item.data.forEach( (items,index) =>{
if(index == 0){
ctx.moveTo(wme*index+20 ,items * hme -20)
}else{
ctx.lineTo(wme*index+20 ,items * hme)
}
})
ctx.stroke();
ctx.closePath();
})
//右边标尺
ctx.beginPath()
ctx.strokeStyle = "#c0c0c0"
ctx.moveTo(20,0)
ctx.lineTo(20,heights-20)
ctx.stroke()
ctx.closePath();
ctx.beginPath()
let hdata = maxData.max / 10
let heid = heights / 10
for (let index = 0; index < 10; index++) {
if(index == 0){
ctx.fillText(hdata * (index+1),10,heights-20 - (heid *index))
}else{
ctx.fillText(hdata * (index+1),10,heights-20 - (heid *index))
}
}
//底部标尺
ctx.beginPath()
ctx.strokeStyle = "#c0c0c0"
ctx.moveTo(10,heights -20)
ctx.lineTo(canvasWidth,heights-20)
ctx.stroke()
ctx.closePath();
ctx.draw()
},
getGroupAndMax(arr){
let max = 0;
let group = [];
arr.forEach(element => {
group.push(element.name)
element.data.forEach(item =>{
if(item > max){
max = item;
}
})
});
let data = {
max,
group
}
return data;
},
}
})
折线图wxml
<canvas canvas-id="linecanvas" style='width:{{canvasWidth}}px; height:{{heights}}px'></canvas>
|