init()

in src/Wsunburst/index.tsx [169:366]


  init(chart: Chart, config: WsunburstConfig, data: ChartData) {
    const { source, total } = computeData(data, config, this);

    this.totalData = numberDecimal(total, config?.legend?.decimal ?? config?.tooltip?.decimal ?? 2);

    chart.data(source);

    const thetaConfig: Types.CoordinateCfg = {
      radius: Math.max(Math.min(config.outerRadius, 1), 0.01),
    };
    if (config.startAngle !== undefined) {
      thetaConfig.startAngle = config.startAngle;
    }
    if (config.endAngle !== undefined) {
      thetaConfig.endAngle = config.endAngle;
    }
    if (config.cycle) {
      thetaConfig.innerRadius = Math.max(Math.min(config.innerRadius, 1), 0);
    }

    chart.coordinate('polar', thetaConfig);

    chart.axis(false);

    // 多重圆环默认开启分组,这里通过自定义图例实现
    // 自定义图例会有更新问题
    const newItems: G2Dependents.ListItem[] = dodgeItems(source, config);

    rectLegend(
      this,
      chart,
      config,
      {
        items: newItems,
      },
      'single',
      null,
      true,
    );

    // tooltip
    rectTooltip(
      this,
      chart,
      config,
      {
        showTitle: false,
        showMarkers: false,
        showCrosshairs: false,
        shared: false,
      },
      (ev: any) => {
        const { items } = ev.data;
        items.forEach((item: any, index: number) => {
          if (typeof config.tooltip === 'boolean') {
            return;
          }

          const pointData = item.data;
          const rootNode = pointData?.parentList?.[0];
          const percent = numberDecimal(item.value / rootNode.value, 4);

          if (config.tooltip.valueFormatter) {
            item.value = config.tooltip.valueFormatter(
              item.value,
              {
                percent,
                ...pointData,
              },
              index,
              items,
            );
          }
          if (config.tooltip.nameFormatter) {
            item.name = config.tooltip.nameFormatter(
              item.name,
              {
                percent,
                ...pointData,
              },
              index,
              items,
            );
          }
        });
      },
      {
        showTitle: false,
        showMarkers: false,
        showCrosshairs: false,
        shared: false,
      },
    );

    const geom = chart
      .polygon({
        // TODO 控制每一层的宽度占比
        // 多层饼图配置不生效
        // multiplePieWidthRatio: 1
      })
      .position('x*y')
      // 暂不支持自定义颜色
      .color('name*color', (xVal, yVal) => {
        return yVal;
      })
      .tooltip('name*value*rawValue*depth', (name, value) => {
        return {
          name,
          value,
        };
      });

    geomStyle(
      geom,
      config.geomStyle,
      (...args: any) => {
        const value = args[1] || args[2];
        const deep = args[3];
        const percent = args[4];
        return {
          // 增加圆环边线装饰
          stroke: themes['widgets-color-background'],
          lineWidth: config.showSpacing && value !== 0 && percent > 0.005 ? 1 : 0,
          cursor: config.select && deep === 1 && !this.isEmpty ? 'pointer' : 'default',
        }
      },
      'name*value*rawValue*depth*percent',
    );

    polarLegendLayout(chart);

    // 环图中心内容
    if (
      config.cycle &&
      config.innerContent &&
      !this.props.children &&
      !this.isEmpty &&
      !this.props.loading &&
      !this.props.errorInfo
    ) {
      const container = deleteChildren(this.chartDom);
      container.className = `${FullCrossName}-children`;
      const firstChild = this.chartDom.firstChild;
      this.chartDom.insertBefore(container, firstChild);

      const content = (
        <Wnumber
          bottomTitle={config?.innerContent?.title ?? this.rawData?.name}
          unit={config?.innerContent?.unit ?? ''}
        >
          {config?.innerContent?.value ?? this.totalData}
        </Wnumber>
      );
      ReactDOM.render(content, container);
    } else if (!this.props.children) {
      // 删去中心内容
      deleteChildren(this.chartDom);
    }

    chart.on('afterpaint', () => {
      updateChildrenPosition(chart, this.chartDom);
    });

    drillDown(chart, (context: any, isCenter?: boolean) => {
      const { view } = context;
      const filterData = view.filteredData ?? [];
      const eventData = get(context, ['event', 'data', 'data']);

      if (!this.isEmpty) {
        let sum = 0;
        if (isCenter) {
          sum = this.totalData;
        } else {
          filterData.forEach((el: any) => {
            if (!el?.children) {
              sum += el?.value ?? 0;
            }
          })
        }
  
        const newContainer = deleteChildren(this.chartDom);
        newContainer.className = `${FullCrossName}-children`;
        const firstChild = this.chartDom.firstChild;
        this.chartDom.insertBefore(newContainer, firstChild);
        const content = (
          <Wnumber
            bottomTitle={config?.innerContent?.title ?? eventData?.name ?? this?.rawData?.name}
            unit={config?.innerContent?.unit ?? ''}
          >
            {config?.innerContent?.value ?? sum}
          </Wnumber>
        );
        ReactDOM.render(content, newContainer);
  
        updateChildrenPosition(chart, this.chartDom);
      }
    });
  }