function renderGeometries()

in packages/charts/src/chart_types/xy_chart/state/utils/utils.ts [278:504]


function renderGeometries(
  dataSeries: DataSeries[],
  xDomain: XDomain,
  yScales: Map<GroupId, ScaleContinuous>,
  smVScale: ScaleBand,
  smHScale: ScaleBand,
  barIndexOrderPerPanel: Record<string, string[]>,
  seriesSpecs: BasicSeriesSpec[],
  seriesColorsMap: Map<SeriesKey, Color>,
  defaultColor: string,
  axesSpecs: AxisSpec[],
  chartTheme: Theme,
  enableHistogramMode: boolean,
  chartRotation: Rotation,
  fallBackTickFormatter: TickFormatter,
  measureText: TextMeasure,
): Omit<ComputedGeometries, 'scales'> {
  const bars: Array<PerPanel<BarGeometry[]>> = [];
  const areas: Array<PerPanel<AreaGeometry>> = [];
  const lines: Array<PerPanel<LineGeometry>> = [];
  const bubbles: Array<PerPanel<BubbleGeometry>> = [];
  const geometriesIndex = new IndexedGeometryMap();
  const isMixedChart = isUniqueArray(seriesSpecs, ({ seriesType }) => seriesType) && seriesSpecs.length > 1;
  const geometriesCounts: GeometriesCounts = {
    points: 0,
    bars: 0,
    areas: 0,
    areasPoints: 0,
    lines: 0,
    linePoints: 0,
    bubbles: 0,
    bubblePoints: 0,
  };
  const barsPadding = enableHistogramMode ? chartTheme.scales.histogramPadding : chartTheme.scales.barsPadding;
  // This var remains Infinity if we don't have points, or we just have a single point per series.
  // In this case the point should be visible if the visibility style is set to `auto`
  let globalMinPointsDistance = Infinity;
  dataSeries.forEach((ds) => {
    const spec = getSpecsById<BasicSeriesSpec>(seriesSpecs, ds.specId);
    if (spec === undefined) {
      return;
    }
    // compute the y scale
    const yScale = yScales.get(getSpecDomainGroupId(ds.spec));
    if (!yScale) {
      return;
    }
    // compute the panel unique key
    const barPanelKey = [ds.smVerticalAccessorValue, ds.smHorizontalAccessorValue].join('|');
    const barIndexOrder = barIndexOrderPerPanel[barPanelKey] ?? [];
    // compute x scale
    const xScale = computeXScale({
      xDomain,
      totalBarsInCluster: barIndexOrder?.length ?? 0,
      range: [0, isHorizontalRotation(chartRotation) ? smHScale.bandwidth : smVScale.bandwidth],
      barsPadding,
      enableHistogramMode,
    });

    const { stackMode } = ds;

    const leftPos = (!isNil(ds.smHorizontalAccessorValue) && smHScale.scale(ds.smHorizontalAccessorValue)) || 0;
    const topPos = (!isNil(ds.smVerticalAccessorValue) && smVScale.scale(ds.smVerticalAccessorValue)) || 0;
    const panel: Dimensions = {
      width: smHScale.bandwidth,
      height: smVScale.bandwidth,
      top: topPos,
      left: leftPos,
    };
    const dataSeriesKey = getSeriesKey(
      {
        specId: ds.specId,
        yAccessor: ds.yAccessor,
        splitAccessors: ds.splitAccessors,
      },
      ds.groupId,
    );

    const color = seriesColorsMap.get(dataSeriesKey) || defaultColor;

    if (isBarSeriesSpec(spec)) {
      const shift = barIndexOrder.indexOf(getBarIndexKey(ds));

      if (shift === -1) return; // skip bar dataSeries if index is not available

      const barSeriesStyle = mergePartial(chartTheme.barSeriesStyle, spec.barSeriesStyle);
      const { yAxis } = getAxesSpecForSpecId(axesSpecs, spec.groupId, chartRotation);
      const valueFormatter = yAxis?.tickFormat ?? fallBackTickFormatter;

      const displayValueSettings = spec.displayValueSettings
        ? { valueFormatter, ...spec.displayValueSettings }
        : undefined;

      const renderedBars = renderBars(
        measureText,
        shift,
        ds,
        xScale,
        yScale,
        panel,
        chartRotation,
        spec.minBarHeight ?? 0,
        color,
        isBandedSpec(spec),
        barSeriesStyle,
        displayValueSettings,
        spec.styleAccessor,
        stackMode,
      );
      geometriesIndex.merge(renderedBars.indexedGeometryMap);
      bars.push({ panel, value: renderedBars.barGeometries });
      geometriesCounts.bars += renderedBars.barGeometries.length;
    } else if (isBubbleSeriesSpec(spec)) {
      const bubbleShift = barIndexOrder && barIndexOrder.length > 0 ? barIndexOrder.length : 1;
      const bubbleSeriesStyle = spec.bubbleSeriesStyle
        ? mergePartial(chartTheme.bubbleSeriesStyle, spec.bubbleSeriesStyle)
        : chartTheme.bubbleSeriesStyle;
      const xScaleOffset = computeXScaleOffset(xScale, enableHistogramMode);
      const renderedBubbles = renderBubble(
        (xScale.bandwidth * bubbleShift) / 2,
        ds,
        xScale,
        yScale,
        color,
        panel,
        isBandedSpec(spec),
        xScaleOffset,
        bubbleSeriesStyle,
        {
          enabled: spec.markSizeAccessor !== undefined,
          ratio: chartTheme.markSizeRatio,
        },
        isMixedChart,
        spec.pointStyleAccessor,
      );
      geometriesIndex.merge(renderedBubbles.indexedGeometryMap);
      bubbles.push({
        panel,
        value: renderedBubbles.bubbleGeometry,
      });
      geometriesCounts.bubblePoints += renderedBubbles.bubbleGeometry.points.length;
      geometriesCounts.bubbles += 1;
    } else if (isLineSeriesSpec(spec)) {
      const lineShift = barIndexOrder && barIndexOrder.length > 0 ? barIndexOrder.length : 1;
      const lineSeriesStyle = getLineSeriesStyles(chartTheme.lineSeriesStyle, spec.lineSeriesStyle);
      const xScaleOffset = computeXScaleOffset(xScale, enableHistogramMode, spec.histogramModeAlignment);

      const renderedLines = renderLine(
        // move the point on half of the bandwidth if we have mixed bars/lines
        (xScale.bandwidth * lineShift) / 2,
        ds,
        xScale,
        yScale,
        panel,
        color,
        spec.curve || CurveType.LINEAR,
        isBandedSpec(spec),
        xScaleOffset,
        lineSeriesStyle,
        {
          enabled: spec.markSizeAccessor !== undefined && lineSeriesStyle.point.visible !== 'never',
          ratio: chartTheme.markSizeRatio,
        },
        hasFitFnConfigured(spec.fit),
        spec.pointStyleAccessor,
      );

      geometriesIndex.merge(renderedLines.indexedGeometryMap);
      lines.push({
        panel,
        value: renderedLines.lineGeometry,
      });
      geometriesCounts.linePoints += renderedLines.lineGeometry.points.length;
      geometriesCounts.lines += 1;
      globalMinPointsDistance = Math.min(globalMinPointsDistance, renderedLines.lineGeometry.minPointDistance);
    } else if (isAreaSeriesSpec(spec)) {
      const areaShift = barIndexOrder && barIndexOrder.length > 0 ? barIndexOrder.length : 1;
      const areaSeriesStyle = getAreaSeriesStyles(chartTheme.areaSeriesStyle, spec.areaSeriesStyle);
      const xScaleOffset = computeXScaleOffset(xScale, enableHistogramMode, spec.histogramModeAlignment);
      const renderedArea = renderArea(
        // move the point on half of the bandwidth if we have mixed bars/lines
        (xScale.bandwidth * areaShift) / 2,
        ds,
        xScale,
        yScale,
        panel,
        color,
        spec.curve || CurveType.LINEAR,
        isBandedSpec(spec),
        xScaleOffset,
        areaSeriesStyle,
        {
          enabled: spec.markSizeAccessor !== undefined && areaSeriesStyle.point.visible !== 'never',
          ratio: chartTheme.markSizeRatio,
        },
        spec.stackAccessors ? spec.stackAccessors.length > 0 : false,
        hasFitFnConfigured(spec.fit),
        spec.pointStyleAccessor,
      );
      geometriesIndex.merge(renderedArea.indexedGeometryMap);
      areas.push({
        panel,
        value: renderedArea.areaGeometry,
      });
      geometriesCounts.areasPoints += renderedArea.areaGeometry.points.length;
      geometriesCounts.areas += 1;
      globalMinPointsDistance = Math.min(globalMinPointsDistance, renderedArea.areaGeometry.minPointDistance);
    }
  });

  return {
    geometries: {
      bars,
      areas: areas.map((a) => {
        a.value.minPointDistance = globalMinPointsDistance;
        return a;
      }),
      lines: lines.map((l) => {
        l.value.minPointDistance = globalMinPointsDistance;
        return l;
      }),
      bubbles,
    },
    geometriesIndex,
    geometriesCounts,
  };
}