UNPKG

@minix-iot/ui

Version:

基于Vue的移动端轻量级UI组件库

278 lines (269 loc) 8.88 kB
import F2 from "@antv/f2" export function mixChart(){ return { props:{ axis:{ type: Object, }, geometry:{ type: Object, required: true }, data:{ type: Array | Object, required: true }, width:{ type: Number }, height:{ type: Number }, showTag:{ type: Boolean, default: false } }, data(){ return { chart:null } }, computed:{ isUsingYR(){ return Array.isArray(this.data[0]) } }, watch:{ axis(){ this.repaint() }, geometry(){ this.repaint() }, showTag(){ this.repaint() }, width(value){ this.chart.changeSize(value,null) }, height(value){ this.chart.changeSize(null,value) }, data(){ this.changeSource() } }, mounted(){ this.initChart() this.renderCoord() this.renderAxis() this.renderScale() this.renderTooltip() this.renderLegend() this.renderGuide() this.renderSource() this.renderGeometry() this.chart.render() this.useInteraction() }, beforeDestory(){ this.chart.destory() }, methods:{ initChart(){ this.chart = new F2.Chart({ el: this.getCanvas(), width: this.width, height: this.height, pixelRatio: window.devicePixelRatio }) }, renderCoord(){ }, renderAxis(){ this.chart.axis(this.getAxisOption()) }, renderScale(){ const {x,y,yr} = this.axis x.scale && this.chart.scale(x.use, x.scale) y.scale && this.chart.scale(y.use, y.scale) yr && yr.scale && this.chart.scale(yr.use,yr.scale) }, renderTooltip(){ this.chart.tooltip(this.getTooltipOption()) }, renderLegend(){ this.chart.legend({ align: 'center', marker:{ radius:4 }, nameStyle:{ fill:'#8A8A8F', fontSize: 12 }, valueStyle:{ fill:'#8A8A8F', fontSize: 12 } }) }, renderGuide(){ if(this.showTag){ const items = this.data.flat() const {x,y,yr} = this.axis const {classifyBy} = this.geometry items.forEach(item=>{ const position = [item[x.use],item[y.use] ?? item[yr.use]] const content = item[y.use] ?? item[yr.use] this.chart.guide().text(this.getGuideTextOption(position,content)) }) } }, renderSource(){ this.chart.source(this.data.flat()) }, renderGeometry(){ }, useInteraction(){ }, changeSource(){ this.chart.changeSource(this.data.flat()) }, repaint(){ this.chart.clear() this.renderCoord() this.renderAxis() this.renderScale() this.renderTooltip() this.renderLegend() this.renderGuide() this.renderSource() this.renderGeometry() this.chart.repaint() }, getCanvas(){ return this.$el }, getAxisOption(transposed = false){ const option = {} const {x,y,yr} = this.axis if(x){ option[x.use] = transposed ? this.getAxisYOption(): this.getAxisXOption() } if(y){ option[y.use] = transposed ? this.getAxisXOption() : this.getAxisYOption() } if(yr){ option[yr.use] =this.getAxisYOption(option=>option.positon='right') } return option }, getAxisXOption(configAxis = option=>option){ const option = { label:{ fill:'#8A8A8F', fontSize: 12, } } configAxis(option) return option }, getAxisYOption(configAxis = option=>option){ const option = { label:{ fill: '#C7C7CC', fontSize: 10 }, grid:{ stroke:'#F2F2F2', lineWidth:1, lineDash:0 } } configAxis(option) return option }, getTooltipOption(showCrosshairs = false){ const option = { showCrosshairs, crosshairsStyle: { stroke: '#C7C7CC', lineWidth: 1, lineDash: [3,1.2] }, background:{ fill:'#FFFFFF', radius: 15, padding:[8,25], shadowOffsetX:0, shadowOffsetY:2, shadowBlur:8, shadowColor:'rgba(0,0,0,0.1)', }, nameStyle:{ fill:'#666666', fontSize: 13, fontFamily:'PingFangSC-Medium', fontWeight:500 }, valueStyle:{ fill:'#666666', fontSize:13, fontFamily:'PingFangSC-Medium', fontWeight:500 } } if(this.geometry.classifyBy){ option.custom = true // onchange option.onChange = obj=>{ const legend = this.chart.get('legendController').legends.top?.[0]; if(!legend){ return } const tooltipItems = obj.items; const legendItems = legend.items; const map = {}; legendItems.forEach(function (item) { map[item.name] = {...item}; }); tooltipItems.forEach(function (item) { const name = item.name; const value = item.value; if (map[name]) { map[name].value = value; } }); legend?.setItems(Object.values(map)); } // onHide option.onHide = ()=>{ const legend = this.chart.get('legendController').legends.top?.[0]; legend?.setItems(this.chart.getLegendItems().country); } } return option }, getGuideTextOption(position,content){ const option = { position, content, style:{ fill:'#666666', fontSize:9 }, offsetY:-8 } return option }, getLinearColor(color,angle=90){ if(Array.isArray(color)){ return color.map(x=>`l(${angle}) 0:${x}FF 1:${x}00`) } return `l(${angle}) 0:${color}FF 1:${color}00` } } } }