computeSankeyNodeVisuals function

List<FluentSankeyNodeVisual> computeSankeyNodeVisuals({
  1. required FluentSankeyLayoutResult layout,
  2. required FluentChartTextMeasurer measurer,
  3. required TextStyle nameStyle,
  4. required TextStyle weightMeasurementStyle,
  5. required String formatNumber(
    1. double value
    ),
  6. required String nodeSemanticLabel(
    1. String name,
    2. String weight
    ),
})

Computes the text visuals for every node.

Ports _computeNodeAttributes (SankeyChart.tsx:619-665). The name budget is NODE_WIDTH - 8 less the padding: 8 on a tall node, and 8 + 6 + weightWidth on a short one, where the weight is measured at weightMeasurementStyle.

Implementation

List<FluentSankeyNodeVisual> computeSankeyNodeVisuals({
  required FluentSankeyLayoutResult layout,
  required FluentChartTextMeasurer measurer,
  required TextStyle nameStyle,
  required TextStyle weightMeasurementStyle,
  required String Function(double value) formatNumber,
  required String Function(String name, String weight) nodeSemanticLabel,
}) {
  final result = <FluentSankeyNodeVisual>[];
  for (var i = 0; i < layout.nodes.length; i++) {
    final node = layout.nodes[i];
    final height = math.max(node.y1 - node.y0, 0.0);
    final actualValue = layout.nodeActualValues[i];
    final formatted = formatNumber(actualValue);
    // `:631` — 8px of left margin inside the rectangle.
    var padding = 8.0;
    var weightOffset = 0.0;
    if (height < kSankeyMinHeightForDoubleLine) {
      // `:638` — 6px of breathing room between the name and the weight.
      padding += 6;
      weightOffset = measurer.width(formatted, weightMeasurementStyle);
      padding += weightOffset;
    }
    // `:647-649` — 124 - 8 = 116 is the rectangle width the truncation works
    // against, and `truncateText` subtracts the padding from it (`:391`).
    final name = truncateSankeyText(
      layout.data.nodes[i].name,
      kSankeyNodeWidth - 8 - padding,
      measurer: measurer,
      style: nameStyle,
    );
    result.add(
      FluentSankeyNodeVisual(
        name: name,
        trimmed: name.endsWith(kSankeyEllipsis),
        height: height,
        weightOffset: weightOffset,
        // `:855` — a falsy 0 bypasses the formatter entirely.
        weightText: actualValue != 0 ? formatted : '0',
        semanticLabel: nodeSemanticLabel(layout.data.nodes[i].name, formatted),
      ),
    );
  }
  return result;
}