drawGroupPrimitives method

  1. @override
List<MarkElement<ElementStyle>> drawGroupPrimitives(
  1. List<Attributes> group,
  2. CoordConv coord,
  3. Offset origin
)
override

Renders primitive elements of all tuples of a group.

The tuples are rendered in groups. the Attributes.shape of the first tuple of a group will be taken as a represent, and it's drawGroupPrimitives method decides the basic way to render the whole group. If different tuples have different shapes, define and call special element rendering methods for each item.

Implementation

@override
List<MarkElement> drawGroupPrimitives(
  List<Attributes> group,
  CoordConv coord,
  Offset origin,
) {
  assert(!(coord is PolarCoordConv && coord.transposed));

  final contours = <List<List<Offset>>>[];

  var currentContour = <List<Offset>>[];
  for (var item in group) {
    assert(item.shape is BasicAreaShape);

    final position = item.position;
    if (position[0].dy.isFinite && position[1].dy.isFinite) {
      final start = coord.convert(position[0]);
      final end = coord.convert(position[1]);
      currentContour.add([start, end]);
    } else if (currentContour.isNotEmpty) {
      contours.add(currentContour);
      currentContour = [];
    }
  }
  if (currentContour.isNotEmpty) {
    contours.add(currentContour);
  }

  if (loop &&
      group.first.position[0].dy.isFinite &&
      group.first.position[1].dy.isFinite &&
      group.last.position[0].dy.isFinite &&
      group.last.position[1].dy.isFinite) {
    // Because lines may be broken by NaN, don't loop by Path.close.
    contours.last.add(contours.first.first);
  }

  final primitives = <MarkElement>[];

  final style = getPaintStyle(group.first, false, 0, coord.region, null);

  for (var contour in contours) {
    final starts = <Offset>[];
    final ends = <Offset>[];
    for (var points in contour) {
      starts.add(points[0]);
      ends.add(points[1]);
    }

    final segments = <Segment>[];
    segments.add(MoveSegment(end: ends.first));
    if (smooth) {
      final controlsList = getCubicControls(ends, false, true);
      for (var c in controlsList) {
        segments.add(CubicSegment(control1: c[0], control2: c[1], end: c[2]));
      }
    } else {
      for (var point in ends) {
        segments.add(LineSegment(end: point));
      }
    }
    segments.add(LineSegment(end: starts.last));
    final reversedStarts = starts.reversed.toList();
    if (smooth) {
      final controlsList = getCubicControls(reversedStarts, false, true);
      for (var c in controlsList) {
        segments.add(CubicSegment(control1: c[0], control2: c[1], end: c[2]));
      }
    } else {
      for (var point in reversedStarts) {
        segments.add(LineSegment(end: point));
      }
    }
    segments.add(CloseSegment());

    primitives.add(PathElement(segments: segments, style: style));
  }

  return primitives;
}