buildFluentChartPopoverMultiValue function

Widget buildFluentChartPopoverMultiValue(
  1. FluentChartPopoverData data,
  2. FluentChartPopoverStyle style,
  3. Color fallbackForeground
)

Builds the stacked popover body. ChartPopover.tsx:116-165.

fallbackForeground is colorNeutralForeground1, the false arm of ChartPopover.tsx:257.

Implementation

Widget buildFluentChartPopoverMultiValue(
  FluentChartPopoverData data,
  FluentChartPopoverStyle style,
  Color fallbackForeground,
) {
  const states = <WidgetState>{};
  final values = data.yValues ?? const <FluentYValueHover>[];
  final hasSubCounts = fluentChartPopoverHasSubCounts(values);

  final rows = <Widget>[
    for (var index = 0; index < values.length; index++)
      _popoverRow(
        values[index],
        style,
        fallbackForeground,
        popoverColour: data.color,
        hasSubCounts: hasSubCounts,
        // ChartPopover.tsx:187 — every column but the last carries a 16px
        // trailing margin.
        isLast: index == values.length - 1,
      ),
  ];

  return Column(
    crossAxisAlignment: CrossAxisAlignment.start,
    mainAxisSize: MainAxisSize.min,
    children: <Widget>[
      Padding(
        // ChartPopover.tsx:122 — 11px below the date container, but only when
        // subcounts exist. The same 11 as the single-value accent bar margin.
        padding: EdgeInsets.only(
          bottom: hasSubCounts ? kChartPopoverAccentBarMarginTop : 0,
        ),
        child: Text(
          data.xValue ?? '',
          style: style.xTextStyle!.resolve(states),
        ),
      ),
      // ChartPopover.tsx:131 — subcounts lay the rows out as a flex row;
      // otherwise they stack.
      if (hasSubCounts)
        Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: rows,
        )
      else
        Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          mainAxisSize: MainAxisSize.min,
          children: rows,
        ),
      // ChartPopover.tsx:161 renders the description INSIDE the row wrapper
      // here, unlike the single-value path where it is a sibling at :106.
      if (data.descriptionMessage != null)
        Text(
          data.descriptionMessage!,
          style: style.descriptionTextStyle!.resolve(states),
        ),
    ],
  );
}