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,
) {
  double? stepXRst = tileCounts?[0] == null ? null : 1 / tileCounts![0]!;
  double? stepYRst = tileCounts?[1] == null ? null : 1 / tileCounts![1]!;

  if (stepXRst == null || stepYRst == null) {
    var stepX = double.infinity;
    var stepY = double.infinity;
    for (var i = 0; i < group.length - 1; i++) {
      final point = group[i].position.last;
      final nextPoint = group[i + 1].position.last;
      final dx = (nextPoint.dx - point.dx).abs();
      final dy = (nextPoint.dy - point.dy).abs();
      if (dx != 0) {
        stepX = min(stepX, dx);
      }
      if (dy != 0) {
        stepY = min(stepY, dy);
      }
    }
    if (!stepX.isFinite) {
      stepX = 1;
    }
    if (!stepY.isFinite) {
      stepY = 1;
    }

    stepXRst = stepXRst ?? stepX;
    stepYRst = stepYRst ?? stepY;
  }

  final biasX = stepXRst / 2;
  final biasY = stepYRst / 2;

  final rst = <MarkElement>[];

  for (var item in group) {
    assert(item.shape is HeatmapShape);

    final style = getPaintStyle(item, false, 0, null, null);

    final point = item.position.last;
    if (coord is RectCoordConv) {
      assert(!sector);
      rst.add(RectElement(
        rect: Rect.fromPoints(
          coord.convert(Offset(point.dx - biasX, point.dy + biasY)),
          coord.convert(Offset(point.dx + biasX, point.dy - biasY)),
        ),
        borderRadius: (item.shape as HeatmapShape).borderRadius,
        style: style,
        tag: item.tag,
      ));
    } else {
      if (sector) {
        coord as PolarCoordConv;
        final startAngle =
            coord.transposed ? point.dy - biasY : point.dx - biasX;
        final endAngle =
            coord.transposed ? point.dy + biasY : point.dx + biasX;
        final r = coord.transposed ? point.dx + biasX : point.dy + biasY;
        final r0 = coord.transposed ? point.dx - biasX : point.dy - biasY;
        rst.add(SectorElement(
          center: coord.center,
          endRadius: coord.convertRadius(r),
          startRadius: coord.convertRadius(r0),
          startAngle: coord.convertAngle(startAngle),
          endAngle: coord.convertAngle(endAngle),
          borderRadius: (item.shape as HeatmapShape).borderRadius,
          style: style,
          tag: item.tag,
        ));
      } else {
        assert((item.shape as HeatmapShape).borderRadius == null);

        // [topLeft, topRight, bottomRight, bottomLeft]
        final vertices = [
          Offset(point.dx - biasX, point.dy + biasY),
          Offset(point.dx + biasX, point.dy + biasY),
          Offset(point.dx + biasX, point.dy - biasY),
          Offset(point.dx - biasX, point.dy - biasY),
        ];
        rst.add(PolygonElement(
            points: vertices.map(coord.convert).toList(),
            style: style,
            tag: item.tag));
      }
    }
  }
  return rst;
}