layout()

in src/aop/controller/legend.ts [29:143]


  layout() {
    const widgetsCtx = (this.view as any)?.widgetsCtx;
    if (!widgetsCtx?.size) {
      return;
    }
    const [w, h] = widgetsCtx?.size;
    const legendConfig: any = {};
    const globalBaseConfig = widgetsCtx?.context?.defaultConfig?.baseConfig;
    const globalComsConfig = widgetsCtx?.context?.defaultConfig?.[widgetsCtx.chartName.replace('G2', '')] ?? {};
    merge(
      legendConfig,
      widgetsCtx?.defaultConfig?.legend ?? {},
      globalBaseConfig?.legend ?? {},
      globalComsConfig?.legend ?? {},
      widgetsCtx?.props?.config?.legend ?? {},
    );

    if (
      this.legendContainer &&
      !widgetsCtx?.isEmpty &&
      !widgetsCtx?.props?.loading &&
      !widgetsCtx?.props?.errorInfo &&
      legendConfig?.visible !== false &&
      (legendConfig?.table || legendConfig?.gradient || legendConfig?.foldable)
    ) {
      this.legendContainer.style.visibility = 'visible';
      const legendElement = this.legendContainer?.childNodes?.[0];
      const position = (legendConfig?.position ?? 'bottom').split('-')[0];

      // 根据legend配置项计算图表宽高
      let size = [w, h];
      let legendSize = [0, 0];
      let legendMaxSize = null;

      if (legendConfig?.table) {
        // 根据数据量计算高度
        // 目前暂时对多重圆环进行特殊处理,待规则统一梳理后,整理数据类型
        const dataType = widgetsCtx.chartName === 'G2MultiPie' ? 'treeNode' : 'common';
        let items = getStatistics(widgetsCtx.chart, [], widgetsCtx?.legendField || 'type', dataType);

        // 增加特殊逻辑,如果目前包含2层以上,则只展示第一层数据
        if (dataType === 'treeNode') {
          let filterData = [...(this?.view?.options?.data ?? [])];
          const firstDepthCount = filterData.filter((sub: any) => sub.depth === 1)?.length;
          const secondDepthCount = filterData.filter((sub: any) => sub.depth === 2)?.length;

          if (firstDepthCount > 0 && secondDepthCount > 0) {
            filterData = filterData.filter((sub: any) => sub.depth === 2);
          } else {
            filterData = [];
          }
          const filterDataIdList = filterData.map((sub: any) => sub.id);
          items = omit(items, filterDataIdList);
        }

        const num = Object.keys(items).length ?? 0;

        if (position === 'right') {
          size = [w / 2, h];
          const height = legendConfig?.table?.style?.height ?? Math.min(h, 20 * (num + 1));
          legendSize = [w / 2, height];
          legendMaxSize = [w / 2, h];
        } else {
          const height = legendConfig?.table?.style?.height ?? Math.min(h * 0.3, 20 * (num + 1));
          size = [w, h - height];
          legendSize = [w, height];
          legendMaxSize = [w, height];
        }
      } else if (legendConfig?.gradient) {
        size = [w, h - 50];
        legendSize = [w, 50];
        legendMaxSize = [w, 50];
      } else if (legendConfig?.foldable) {
        if (widgetsCtx.legendFolded || widgetsCtx.legendFolded === undefined) {
          size = [w, h - 20];
          legendSize = [w, 20];
        } else {
          // 折叠型legend的展开逻辑在FoldableLegend内实现
          if (legendElement) {
            legendElement.style.width = 'auto';
            legendElement.style.height = 'auto';
          }
          return;
        }
      }
      if (this.view?.canvas?.get('el')) {
        // @ts-ignore
        this.view?.changeSize(size[0], size[1]);
      }

      // 设置图表宽高
      const chartContainer = this.view.getCanvas().get('el')?.parentNode?.parentNode;
      if (chartContainer) {
        chartContainer.style.width = `${size[0]}px`;
        chartContainer.style.height = `${size[1]}px`;
      }

      // 设置legend宽高
      if (legendElement) {
        legendElement.style.width = `${legendSize[0]}px`;
        legendElement.style.height = `${legendSize[1]}px`;
        if (legendMaxSize) {
          legendElement.style.maxHeight = `${legendMaxSize[1]}px`;
        }

        // 记录legend尺寸
        widgetsCtx.legendSize = legendSize;
      }
    } else {
      if (this.legendContainer) {
        this.legendContainer.style.visibility = 'hidden';
      }
      super.layout();
    }
  }