Angular 饼图组件 - 设备类型统计
import { Component, Input, OnInit } from '@angular/core'; import { Chart, Util } from '@antv/g2'; import { GetDateService } from '@proxy/get-data'; import { UtilsService } from 'src/app/shared/services/utils.service';
@Component({ selector: 'app-piechartofequipments', templateUrl: './piechartofequipments.component.html', styleUrls: ['./piechartofequipments.component.scss'] }) export class PiechartofequipmentsComponent implements OnInit { @Input() depId: any;
chart: Chart; sbzlList; public idLabel: Map<number, string>;
constructor( private getdateService: GetDateService, private utils: UtilsService, ) { this.sbzlList = this.utils.getDicTypeData("ep_category"); this.idLabel = this.utils.getDicIdLabel(); // console.info('this.sbzlList', this.sbzlList); } ngOnInit(): void {
}
ngAfterViewInit(): void { this.initdata(); }
initdata() { let eqdata = []; // // 得到全部预警数据 // this.getdateService.getWarnDataCount().subscribe(val => { // console.log('valvalva', val); // })
// 得到各种设备的数量
let eqdataObj;
let eqdatanum = 0;
this.getdateService.getEquipmenLbCount().subscribe(item => {
console.log('itemitemitem', item);
if (item) {
for (let key in item) {
eqdatanum += item[key];
eqdataObj = {
// item: this.sbzlList.filter(res => res.id == key)[0].dataLabel,
item: this.idLabel.get(parseInt(key)),
count: item[key],
// percent: 0,
}
eqdata.push(eqdataObj);
// console.info("key", eqdata)
}
eqdata.forEach(i => { i['percent'] = i.count / eqdatanum; })
console.info("eqdata", eqdata)
this.draw(eqdata);
}
})
}
draw(data) { this.chart = new Chart({ container: 'container', autoFit: true, height: 500, }); // 新建一个 view 用来单独渲染Annotation const innerView = this.chart.createView(); this.chart.coordinate('theta', { radius: 0.75, innerRadius: 0.5, });
this.chart.data(data);
this.chart.scale('percent', {
formatter: val => {
val = val * 100 + '%';
return val;
},
});
this.chart.tooltip(false);
// 声明需要进行自定义图例字段: 'item'
this.chart.legend('item', {
position: 'bottom', // 配置图位置', // 配置图例显示位置
custom: true, // 关键字段,告诉 G2,要使用自定义的图例
items: data.map((obj, index) => {
return {
name: obj.item, // 对应 itemName
value: obj.count, // 对应 itemValue
marker: {
symbol: 'square', // marker 的形状
style: {
r: 5, // marker 图形半径
fill: this.chart.getTheme().colors10[index], // marker 颜色,使用默认颜色,同图形对应
},
},
// marker 配置
};
}),
itemName: {
style: {
fill: '#fff',
},
},
itemValue: {
style: {
fill: '#fff',
},
// 配置 itemValue 样式
// formatter: val => `${val * 100}%` // 格式化 itemValue 内容
},
});
this.chart
.interval()
.adjust('stack')
.position('percent')
.color('item')
.style({
fillOpacity: 1,
})
.state({
active: {
style: element => {
const shape = element.shape;
return {
lineWidth: 10,
stroke: shape.attr('fill'),
strokeOpacity: shape.attr('fillOpacity'),
};
},
},
});
// 移除图例点击过滤交互
this.chart.removeInteraction('legend-filter');
this.chart.interaction('element-active');
this.chart.on('afterrender', () => {
// label 绘制图层
let labelGroup = this.chart.foregroundGroup.findById('customLabels');
if (labelGroup) {
labelGroup.remove();
} else {
labelGroup = this.chart.foregroundGroup.addGroup({
capture: false,
id: 'customLabels'
});
}
const offset = 30; // 拐点折线的长度
const textOffset = 8;
const elements = this.chart.geometries[0].elements;
const coordinate = this.chart.getCoordinate();
const center = coordinate.getCenter();
const radius = coordinate.getRadius();
const count = elements.length;
let preWidth = 0;
let firstPoint1; // 第一个 label 的第一个点
let firstPoint2; // 第一个 label 的拐点
for (let i = 0; i < count; i++) {
const label = this.chart.foregroundGroup.addGroup();
const element = elements[i];
const mappingData = element.getModel(); // 使用getModel()方法获取元素对应的数据
const originData = mappingData; // 获取原始数据
// const mappingData = element.getModel();
if (i === count - 1) {
// 最后一个图形 label 横着长
label.addShape('path', {
attrs: {
path: [
['M', center.x, center.y],
['L', center.x + radius + offset, center.y],
],
stroke: mappingData.color,
lineWidth: 1,
},
});
label.addShape('text', {
attrs: {
x: center.x + radius + offset + textOffset,
y: center.y,
text: originData.count + originData.count,
textBaseline: 'middle',
fill: '#000',
},
});
} else {
const nextElement = elements[i + 1];
const nextBBox = nextElement.getBBox();
const bbox = element.getBBox();
// 第一个点
const width = bbox.maxX - nextBBox.maxX;
const pointRadius = radius - preWidth - (width / 2);
const point1 = Util.polarToCartesian(center.x, center.y, pointRadius, - 3 * Math.PI / 8 + (Math.PI / 8) * i);
let point2;
if (i === 0) {
point2 = {
x: bbox.maxX,
y: bbox.minY
};
firstPoint2 = point2;
firstPoint1 = point1;
} else {
point2 = {
x: Math.min(firstPoint2.x + point1.x - firstPoint1.x, elements[0].getBBox().maxX),
y: firstPoint2.y + point1.y - firstPoint1.y,
};
}
const point3 = {
x: point2.x + offset,
y: point2.y
};
label.addShape('path', {
attrs: {
path: [
['M', point1.x, point1.y],
['L', point2.x, point2.y],
['L', point3.x, point3.y],
],
stroke: mappingData.color,
lineWidth: 1,
},
});
label.addShape('text', {
attrs: {
x: point3.x + textOffset, // 加个偏移量
y: point3.y,
text: originData.count + ': ' + originData.count,
textBaseline: 'middle',
fill: '#000',
},
});
preWidth += width;
}
}
});
this.chart.render();
// 监听 element 上状态的变化来动态更新 Annotation 信息
this.chart.on('element:statechange', (ev) => {
const { state, stateStatus, element } = ev.gEvent.originalEvent;
// 本示例只需要监听 active 的状态变化
if (state === 'active') {
const data = element.getData();
if (stateStatus) {
// 更新 Annotation
updateAnnotation(data);
} else {
// 隐藏 Annotation
clearAnnotation();
}
}
});
// 绘制 annotation
let lastItem;
function updateAnnotation(data) {
if (data.item !== lastItem) {
innerView.annotation().clear(true);
innerView
.annotation()
.text({
position: ['50%', '50%'],
content: data.item,
style: {
fontSize: 20,
fill: '#fff',
textAlign: 'center',
},
offsetY: -20,
})
.text({
position: ['50%', '50%'],
content: data.count + '台',
style: {
fontSize: 28,
fill: '#fff',
textAlign: 'center',
},
offsetX: -10,
offsetY: 20,
})
// .text({
// position: ['50%', '50%'],
// content: '台',
// style: {
// fontSize: 20,
// fill: '#fff',
// textAlign: 'center',
// },
// offsetY: 20,
// offsetX: 20,
// });
innerView.render(true);
lastItem = data.item;
}
}
// 清空 annotation
function clearAnnotation() {
innerView.annotation().clear(true);
innerView.render(true);
lastItem = null;
}
}
}
原文地址: https://www.cveoy.top/t/topic/qmzw 著作权归作者所有。请勿转载和采集!