layout method

  1. @override
void layout(
  1. Context context,
  2. BoxConstraints constraints, {
  3. bool parentUsesSize = false,
})
override

First widget pass to calculate the children layout and bounding box

Implementation

@override
void layout(Context context, BoxConstraints constraints,
    {bool parentUsesSize = false}) {
  final _offset = _isFullCircle ? 0 : offset;

  final grid = Chart.of(context).grid as PieGrid;
  final len = grid.radius + _offset;
  var x = -len;
  var y = -len;
  var w = len * 2;
  var h = len * 2;

  final lp = legendPosition == PieLegendPosition.auto
      ? (angleEnd - angleStart > pi / 6
          ? PieLegendPosition.inside
          : PieLegendPosition.outside)
      : legendPosition;

  // Find the legend position
  final bisect = _isFullCircle ? 1 / 4 * pi : (angleStart + angleEnd) / 2;

  final _legendAlign = legendAlign ??
      (lp == PieLegendPosition.inside
          ? TextAlign.center
          : (bisect > pi ? TextAlign.right : TextAlign.left));

  _legendWidget ??= legend == null
      ? null
      : RichText(
          text: TextSpan(
            children: [TextSpan(text: legend!, style: legendStyle)],
            style: TextStyle(
                color: lp == PieLegendPosition.inside
                    ? color!.isLight
                        ? PdfColors.white
                        : PdfColors.black
                    : null),
          ),
          textAlign: _legendAlign,
        );

  if (_legendWidget != null) {
    _legendWidget!.layout(context,
        BoxConstraints(maxWidth: grid.radius, maxHeight: grid.radius));
    assert(_legendWidget!.box != null);

    final ls = _legendWidget!.box!.size;

    // final style = Theme.of(context).defaultTextStyle.merge(legendStyle);

    switch (lp) {
      case PieLegendPosition.outside:
        final o = grid.radius + legendOffset;
        final cx = sin(bisect) * (_offset + o);
        final cy = cos(bisect) * (_offset + o);

        _legendStart = PdfPoint(
          sin(bisect) * (_offset + grid.radius + legendOffset * 0.1),
          cos(bisect) * (_offset + grid.radius + legendOffset * 0.1),
        );

        _legendPivot = PdfPoint(cx, cy);
        if (bisect > pi) {
          _legendAnchor = PdfPoint(
            cx - legendOffset / 2 * 0.8,
            cy,
          );
          _legendWidget!.box = PdfRect.fromPoints(
              PdfPoint(
                cx - legendOffset / 2 - ls.x,
                cy - ls.y / 2,
              ),
              ls);
          w = max(w, (-cx + legendOffset / 2 + ls.x) * 2);
          h = max(h, cy.abs() * 2 + ls.y);
          x = -w / 2;
          y = -h / 2;
        } else {
          _legendAnchor = PdfPoint(
            cx + legendOffset / 2 * 0.8,
            cy,
          );
          _legendWidget!.box = PdfRect.fromPoints(
              PdfPoint(
                cx + legendOffset / 2,
                cy - ls.y / 2,
              ),
              ls);
          w = max(w, (cx + legendOffset / 2 + ls.x) * 2);
          h = max(h, cy.abs() * 2 + ls.y);
          x = -w / 2;
          y = -h / 2;
        }
        break;
      case PieLegendPosition.inside:
        final double o;
        final double cx;
        final double cy;
        if (innerRadius == 0) {
          o = _isFullCircle ? 0 : grid.radius * 2 / 3;
          cx = sin(bisect) * (_offset + o);
          cy = cos(bisect) * (_offset + o);
        } else {
          o = (grid.radius + innerRadius) / 2;
          if (_isFullCircle) {
            cx = 0;
            cy = o;
          } else {
            cx = sin(bisect) * (_offset + o);
            cy = cos(bisect) * (_offset + o);
          }
        }
        _legendWidget!.box = PdfRect.fromPoints(
            PdfPoint(
              cx - ls.x / 2,
              cy - ls.y / 2,
            ),
            ls);
        break;
      default:
        break;
    }
  }

  box = PdfRect(x, y, w, h);
}