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;
}

}

}

Angular 饼图组件 - 设备类型统计

原文地址: https://www.cveoy.top/t/topic/qmzw 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录