paintBar method
void
paintBar(
- ChartCanvas canvas,
- double animationPercent,
- Iterable<
BarRendererElement< barElementsD> >
Paints a stack of bar elements on the canvas.
Implementation
@override
void paintBar(
ChartCanvas canvas,
double animationPercent,
Iterable<BarRendererElement<D>> barElements,
) {
final bars = <CanvasRect>[];
// When adjusting bars for stacked bar padding, do not modify the first bar
// if rendering vertically and do not modify the last bar if rendering
// horizontally.
final unmodifiedBar =
renderingVertically ? barElements.first : barElements.last;
// Find the max bar width from each segment to calculate corner radius.
var maxBarWidth = 0;
var measureIsNegative = false;
for (final bar in barElements) {
var bounds = bar.bounds;
measureIsNegative = measureIsNegative || bar.measureIsNegative!;
if (bar != unmodifiedBar) {
bounds = renderingVertically
? Rectangle<int>(
bar.bounds!.left,
max(
0,
bar.bounds!.top +
(measureIsNegative ? _stackedBarPaddingPx : 0),
),
bar.bounds!.width,
max(0, bar.bounds!.height - _stackedBarPaddingPx),
)
: Rectangle<int>(
max(
0,
bar.bounds!.left +
(measureIsNegative ? _stackedBarPaddingPx : 0),
),
bar.bounds!.top,
max(0, bar.bounds!.width - _stackedBarPaddingPx),
bar.bounds!.height,
);
}
bars.add(
CanvasRect(
bounds!,
dashPattern: bar.dashPattern,
fill: bar.fillColor,
pattern: bar.fillPattern,
stroke: bar.color,
strokeWidthPx: bar.strokeWidthPx,
),
);
maxBarWidth =
max(maxBarWidth, renderingVertically ? bounds.width : bounds.height);
}
bool roundTopLeft;
bool roundTopRight;
bool roundBottomLeft;
bool roundBottomRight;
if (measureIsNegative) {
// Negative bars should be rounded towards the negative axis direction.
// In vertical mode, this is the bottom. In horizontal mode, this is the
// left side of the chart for LTR, or the right side for RTL.
roundTopLeft = !renderingVertically && !isRtl;
roundTopRight = !renderingVertically && isRtl;
roundBottomLeft = renderingVertically || !isRtl;
roundBottomRight = renderingVertically || isRtl;
} else {
// Positive bars should be rounded towards the positive axis direction.
// In vertical mode, this is the top. In horizontal mode, this is the
// right side of the chart for LTR, or the left side for RTL.
roundTopLeft = renderingVertically || isRtl;
roundTopRight = !isRtl;
roundBottomLeft = isRtl;
roundBottomRight = !(renderingVertically || isRtl);
}
final barStack = CanvasBarStack(
bars,
radius: cornerStrategy.getRadius(maxBarWidth),
stackedBarPadding: _stackedBarPaddingPx,
roundTopLeft: roundTopLeft,
roundTopRight: roundTopRight,
roundBottomLeft: roundBottomLeft,
roundBottomRight: roundBottomRight,
);
// If bar stack's range width is:
// * Within the component bounds, then draw the bar stack.
// * Partially out of component bounds, then clip the stack where it is out
// of bounds.
// * Fully out of component bounds, do not draw.
final componentBounds = this.componentBounds!;
final barOutsideBounds = renderingVertically
? barStack.fullStackRect.left < componentBounds.left ||
barStack.fullStackRect.right > componentBounds.right
: barStack.fullStackRect.top < componentBounds.top ||
barStack.fullStackRect.bottom > componentBounds.bottom;
// TODO: When we have initial viewport, add image test for
// clipping.
if (barOutsideBounds) {
final clipBounds = _getBarStackBounds(barStack.fullStackRect);
// Do not draw the bar stack if it is completely outside of the component
// bounds.
if (clipBounds.width <= 0 || clipBounds.height <= 0) {
return;
}
canvas.setClipBounds(clipBounds);
}
canvas.drawBarStack(barStack, drawAreaBounds: componentBounds);
if (barOutsideBounds) {
canvas.resetClipBounds();
}
// Decorate the bar segments if there is a decorator.
barRendererDecorator?.decorate(
barElements,
canvas,
graphicsFactory!,
drawBounds: drawBounds!,
animationPercent: animationPercent,
renderingVertically: renderingVertically,
rtl: isRtl,
);
}