export function fillTextLayout()

in packages/charts/src/chart_types/partition_chart/layout/viewmodel/fill_text_layout.ts [481:553]


export function fillTextLayout<C>(
  shapeConstructor: ShapeConstructor<C>,
  getShapeRowGeometry: GetShapeRowGeometry<C>,
  getRotation: GetRotation,
) {
  const specificFiller = fill(shapeConstructor, getShapeRowGeometry, getRotation);
  return function fillTextLayoutClosure(
    measure: TextMeasure,
    rawTextGetter: RawTextGetter,
    valueGetter: ValueGetterFunction,
    valueFormatter: ValueFormatter,
    childNodes: QuadViewModel[],
    style: PartitionStyle,
    layers: Layer[],
    textFillOrigins: PointTuple[],
    maxRowCount: number,
    leftAlign: boolean,
    middleAlign: boolean,
  ): RowSet[] {
    const allFontSizes: Pixels[][] = [];
    for (let l = 0; l <= layers.length; l++) {
      // get font size spec from config, which layer.fillLabel properties can override
      const { minFontSize, maxFontSize, idealFontSizeJump } = {
        ...style,
        ...(l < layers.length && layers[l]?.fillLabel),
      };
      const fontSizeMagnification = maxFontSize / minFontSize;
      const fontSizeJumpCount = Math.round(logarithm(idealFontSizeJump, fontSizeMagnification));
      const realFontSizeJump = Math.pow(fontSizeMagnification, 1 / fontSizeJumpCount);
      const fontSizes: Pixels[] = [];
      for (let i = 0; i <= fontSizeJumpCount; i++) {
        const fontSize = Math.round(minFontSize * Math.pow(realFontSizeJump, i));
        if (!fontSizes.includes(fontSize)) {
          fontSizes.push(fontSize);
        }
      }
      allFontSizes.push(fontSizes);
    }

    const filler = specificFiller(
      style.fillLabel,
      layers,
      measure,
      rawTextGetter,
      valueGetter,
      valueFormatter,
      maxRowCount,
      leftAlign,
      middleAlign,
    );

    return childNodes
      .map((node: QuadViewModel, i: number) => ({ node, origin: textFillOrigins[i] }))
      .sort((a, b) => b.node.value - a.node.value)
      .reduce<{ rowSets: RowSet[]; fontSizes: Pixels[][] }>(
        ({ rowSets, fontSizes }, { node, origin }) => {
          if (!origin) return { rowSets, fontSizes };
          const nextRowSet = filler(fontSizes, origin, node);
          const { fontSize } = nextRowSet;
          const layerIndex = node.depth - 1;
          return {
            rowSets: [...rowSets, nextRowSet],
            fontSizes: fontSizes.map((layerFontSizes: Pixels[], index: number) =>
              Number.isFinite(fontSize) && index === layerIndex && !layers[layerIndex]?.fillLabel?.maximizeFontSize
                ? layerFontSizes.filter((size: Pixels) => size <= fontSize)
                : layerFontSizes,
            ),
          };
        },
        { rowSets: [], fontSizes: allFontSizes },
      ).rowSets;
  };
}