-
-
Notifications
You must be signed in to change notification settings - Fork 5
Adding Progress Bars #38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Add ProgressGeometry with horizontal, vertical, and circular orientations - Add geomProgress method to CristalyseChart API - Support multiple styles: filled, striped, gradient - Include customizable thickness, corners, colors, and labels - No breaking changes - purely additive feature Progress so far: ✅ ProgressGeometry class added ✅ geomProgress method added 🔄 Next: Add progress-specific data mapping 🔄 Next: Implement rendering logic
- Add progressValueColumn, progressLabelColumn, progressCategoryColumn fields - Add mappingProgress() method for progress-specific data mapping - Update AnimatedCristalyseChartWidget to accept progress columns - Update build() method to pass progress columns to widget - No breaking changes - purely additive feature
…ientations - Implement ProgressGeometry with support for filled, striped, and gradient styles - Add progress bar rendering in animated chart painter with animations - Include comprehensive examples and tests for all progress bar features - Integrate progress bars tab in example app with slider controls
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds progress-bar charts end-to-end: new ProgressGeometry and enums, mappingProgress/geomProgress APIs, widget→painter wiring for progress mappings, painter rendering for multiple progress styles/orientations, example demos and router integration, validation tests, docs, and release/version bumps. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor User
participant App as Example App / Router
participant Screen as ChartScreen
participant ChartAPI as CristalyseChart
participant Widget as AnimatedCristalyseChartWidget
participant Painter as AnimatedChartPainter
User->>App: navigate to "Progress Bars"
App->>Screen: build ChartScreen (chartIndex)
Screen->>ChartAPI: mappingProgress(value,label,category)
Screen->>ChartAPI: geomProgress(orientation,style,thickness,...)
Screen->>Widget: instantiate with data + progress*Column params
Widget->>Painter: create with geometries + progress mapping names
Note right of Painter: paint loop (frames, animations)
Painter->>Painter: detect ProgressGeometry
alt horizontal / vertical / circular
Painter->>Painter: _drawHorizontal/Vertical/CircularProgressBar(...)
end
alt stacked/grouped/gauge/concentric
Painter->>Painter: _drawStacked/_drawGrouped/_drawGauge/_drawConcentric(...)
end
Painter-->>Widget: composited frame
Widget-->>Screen: rendered chart
Screen-->>User: visual update
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches🧪 Generate unit tests
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (15)
💤 Files with no reviewable changes (2)
✅ Files skipped from review due to trivial changes (6)
🧰 Additional context used🪛 markdownlint-cli2 (0.18.1)CHANGELOG.md3-3: Heading levels should only increment by one level at a time (MD001, heading-increment) 🔇 Additional comments (22)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🧪 Early access (Sonnet 4.5): enabledWe are currently testing the Sonnet 4.5 model, which is expected to improve code review quality. However, this model may lead to increased noise levels in the review comments. Please disable the early access features if the noise level causes any inconvenience. Note:
Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/src/widgets/animated_chart_painter.dart (1)
2462-2485: Include progress mapping fields in shouldRepaint.Changes to progressValue/Label/Category columns won’t trigger a repaint, causing stale visuals.
Apply this diff:
bool shouldRepaint(covariant AnimatedChartPainter oldDelegate) { return oldDelegate.data != data || oldDelegate.xColumn != xColumn || oldDelegate.yColumn != yColumn || oldDelegate.y2Column != y2Column || oldDelegate.colorColumn != colorColumn || oldDelegate.sizeColumn != sizeColumn || oldDelegate.pieValueColumn != pieValueColumn || oldDelegate.pieCategoryColumn != pieCategoryColumn || oldDelegate.heatMapXColumn != heatMapXColumn || oldDelegate.heatMapYColumn != heatMapYColumn || oldDelegate.heatMapValueColumn != heatMapValueColumn || + oldDelegate.progressValueColumn != progressValueColumn || + oldDelegate.progressLabelColumn != progressLabelColumn || + oldDelegate.progressCategoryColumn != progressCategoryColumn || oldDelegate.geometries != geometries || oldDelegate.xScale != xScale || oldDelegate.yScale != yScale || oldDelegate.y2Scale != y2Scale || oldDelegate.colorScale != colorScale || oldDelegate.sizeScale != sizeScale || oldDelegate.theme != theme || oldDelegate.animationProgress != animationProgress || oldDelegate.coordFlipped != coordFlipped || !_listEquals(oldDelegate.panXDomain, panXDomain) || !_listEquals(oldDelegate.panYDomain, panYDomain); }
🧹 Nitpick comments (6)
lib/src/core/geometry.dart (1)
1-269: Fix formatting issues causing pipeline failure.The Dart formatter is failing. Run
dart format .to fix the formatting issues before merging.example/lib/graphs/progress_bars.dart (2)
1-155: Fix formatting issues in the example file.The Dart formatter is reporting issues. Please run
dart format .to fix the formatting.
127-155: Consider making test data more realistic.The current test data uses generic task names. Consider using more realistic examples that better demonstrate the use cases for progress bars.
Consider updating the test data to be more domain-specific:
List<Map<String, dynamic>> _generateProgressData() { return [ { - 'task': 'Backend API', + 'task': 'Backend API Development', 'completion': 85.0, 'department': 'Engineering' }, { - 'task': 'Frontend UI', + 'task': 'Frontend UI Implementation', 'completion': 70.0, 'department': 'Engineering' }, { - 'task': 'User Testing', + 'task': 'User Acceptance Testing', 'completion': 45.0, - 'department': 'Product' + 'department': 'Quality Assurance' }, { - 'task': 'Documentation', + 'task': 'Technical Documentation', 'completion': 30.0, - 'department': 'Product' + 'department': 'Technical Writing' }, { 'task': 'Marketing Campaign', 'completion': 90.0, 'department': 'Marketing' }, ]; }test/progress_bar_test.dart (1)
1-318: Fix formatting issues in test file.The Dart formatter is reporting issues with this file. Please run
dart format .to fix the formatting.example/lib/main.dart (1)
1-1240: Fix formatting issues in main.dart.The Dart formatter is reporting issues. Please run
dart format .to fix the formatting.lib/src/widgets/animated_chart_painter.dart (1)
2755-2765: Center horizontal label above the bar (optional).Current label is centered at barX (left edge). Centering improves readability.
Apply this diff:
_drawProgressLabel( canvas, labelText, - Offset(barX, barY - geometry.labelOffset), + Offset(barX + barWidth / 2, barY - geometry.labelOffset), geometry.labelStyle ?? theme.axisTextStyle, );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
example/pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (8)
example/lib/graphs/progress_bars.dart(1 hunks)example/lib/main.dart(11 hunks)lib/src/core/chart.dart(4 hunks)lib/src/core/geometry.dart(1 hunks)lib/src/core/util/painter.dart(1 hunks)lib/src/widgets/animated_chart_painter.dart(4 hunks)lib/src/widgets/animated_chart_widget.dart(2 hunks)test/progress_bar_test.dart(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Flutter Tests
example/lib/graphs/progress_bars.dart
[error] 1-1: Dart format reformatted the file. Command 'dart format --output=none --set-exit-if-changed .' exited with code 1.
test/progress_bar_test.dart
[error] 1-1: Dart format reformatted the file. Command 'dart format --output=none --set-exit-if-changed .' exited with code 1.
lib/src/core/geometry.dart
[error] 1-1: Dart format reformatted the file. Command 'dart format --output=none --set-exit-if-changed .' exited with code 1.
lib/src/widgets/animated_chart_painter.dart
[error] 1-1: Dart format reformatted the file. Command 'dart format --output=none --set-exit-if-changed .' exited with code 1.
example/lib/main.dart
[error] 1-1: Dart format reformatted the file. Command 'dart format --output=none --set-exit-if-changed .' exited with code 1.
lib/src/core/chart.dart
[error] 1-1: Dart format reformatted the file. Command 'dart format --output=none --set-exit-if-changed .' exited with code 1.
🔇 Additional comments (16)
lib/src/core/geometry.dart (1)
211-219: LGTM! Well-structured enum definitions.The
ProgressOrientationandProgressStyleenums are clearly defined with good naming conventions and appropriate options for progress bar visualization.lib/src/core/util/painter.dart (1)
61-63: LGTM! Progress column mappings properly wired.The new progress-related column mappings are correctly added to the
AnimatedChartPainterinstantiation, maintaining consistency with the existing pattern.example/lib/graphs/progress_bars.dart (1)
4-124: Well-structured progress bar showcase!The
buildProgressBarsTabfunction provides an excellent demonstration of the three progress orientations with appropriate styling and animation configurations. The implementation follows Flutter best practices.lib/src/widgets/animated_chart_widget.dart (1)
30-32: LGTM! Progress column properties correctly integrated.The three new progress-related column properties are properly declared and wired through the constructor, following the established pattern for other column mappings.
Also applies to: 59-61
test/progress_bar_test.dart (2)
6-51: Excellent test coverage for ProgressGeometry!The tests thoroughly verify both default and custom values for all ProgressGeometry properties, ensuring the API works as expected.
282-317: Well-structured theme integration test!The test properly verifies that custom themes are applied to progress bars, ensuring visual consistency.
example/lib/main.dart (4)
123-123: TabController length correctly updated.The TabController length has been properly incremented from 18 to 19 to accommodate the new Progress Bars tab.
322-324: Good thickness calculation for progress bars.The displayed value calculation for progress bars (15.0 + sliderValue * 25.0) provides a reasonable range of 15-40px thickness.
978-991: Progress Bars page properly integrated!The new Progress Bars chart page is correctly positioned at index 13 with appropriate stats cards showing orientations, styles, and animations information.
693-703: Verify menu item indices after adding "Progress Bars" (value = 14)PopupMenuItem values found: 0–18. Confirm in example/lib/main.dart (around lines ~693–703) that:
- TabBarView.children.length == max(menu value) + 1 (18 + 1 = 19).
- tabs: [...] count == 19.
- PopupMenuButton.onSelected (switch/case or index mapping) routes each value to the corresponding tab; update any index-based logic for items > 14 if needed.
lib/src/widgets/animated_chart_painter.dart (2)
24-26: Wiring for progress mappings and dispatch looks good.New fields, constructor params, and ProgressGeometry routing are consistent with the rest of the painter.
Also applies to: 80-82, 674-684
1-1: Run dart format and commit formatting fixes.
Formatter failing in CI — rundart format --set-exit-if-changed .(ordart format .) and commit the resulting changes. Couldn't verify here (Dart CLI not available).lib/src/core/chart.dart (4)
123-135: API: mappingProgress looks consistent.Naming aligns with other mapping methods and is intuitive.
841-844: Widget build wiring passes new progress fields correctly.Matches painter and widget additions.
827-857: Confirmed: AnimatedCristalyseChartWidget and AnimatedChartPainter include and forward the three progress named args.*
Constructors/fields are present in lib/src/widgets/animated_chart_widget.dart and lib/src/widgets/animated_chart_painter.dart, and the args are forwarded in lib/src/core/util/painter.dart.
1-1: Fix formatting: run dart format locally and commitCI reports a formatter failure in lib/src/core/chart.dart; sandbox verification failed ('dart: command not found'). Run locally: dart format --set-exit-if-changed . || dart format . and commit any changes.
…and concentric - Add 4 new ProgressStyle enum values: stacked, grouped, gauge, concentric - Extend ProgressGeometry with properties for: * Stacked progress: segments and segmentColors * Grouped progress: groupCount and groupSpacing * Gauge progress: startAngle, sweepAngle, showTicks, tickCount, gaugeRadius * Concentric progress: concentricRadii and concentricThicknesses - Implement rendering for all new progress bar styles: * Stacked: Multiple colored segments in single bar * Grouped: Multiple progress bars side-by-side * Gauge: Speedometer-style with tick marks and needle * Concentric: Multiple rings with varying progress levels - Update geomProgress API to accept all new parameters - Add comprehensive examples showing all progress bar variants - Extend test coverage for enhanced progress bar functionality - All tests passing (177 tests total) Progress bars now support 7 different styles matching the reference image: horizontal/vertical bars, circular progress, stacked segments, grouped bars, gauge indicators, and concentric rings with full animation support.
Input Validation & Safety: - Add comprehensive assertions in ProgressGeometry constructor with clear error messages - Validate minValue < maxValue, animationDuration > 0, non-negative numeric inputs - Check segments, concentricRadii, and other array values are valid - Enforce groupCount > 0, gaugeRadius > 0, and other logical constraints Critical Bug Fixes: - Fix division by zero in normalizedValue calculation with proper range checking - Add safe fallback (0.5) when maxVal - minVal <= 0 or not finite - Fix Color vs Gradient type handling in horizontal progress bar rendering - Fix Color vs Gradient type handling in vertical progress bar rendering - Support dynamic fill sources from colorScale that can return Color or Gradient - Maintain proper precedence: explicit gradient > color scale gradient > default gradient > solid color Test Coverage: - Add 13 new validation tests covering all assertion conditions - Add edge case tests for invalid numeric values (NaN, infinity) - Verify proper error messages and exception types - Test graceful handling of malformed data - All 186 tests passing with comprehensive coverage Production Readiness: - Fail-fast validation prevents runtime crashes from invalid configs - Graceful degradation for edge cases like zero ranges or invalid numbers - Type-safe gradient/color handling prevents casting exceptions - Consistent behavior across all progress bar rendering paths These fixes address critical production stability issues and ensure the library handles edge cases gracefully while providing clear feedback for configuration errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (6)
lib/src/widgets/animated_chart_painter.dart (5)
2516-2525: Guard against division by zero when minValue == maxValue.
2689-2716: Support both Color and Gradient from ColorScale.
2793-2820: Apply same gradient handling for vertical bars.
2869-2872: Prevent division by zero in circular layout calculation.
2896-2898: Add gradient support for circular progress bars.lib/src/core/chart.dart (1)
457-488: Add validation for minValue/maxValue range.
🧹 Nitpick comments (7)
lib/src/core/geometry.dart (1)
1-1: Rundart formatto fix formatting issues.The pipeline indicates formatting changes are needed. Please run
dart formaton this file.#!/bin/bash # Check the specific formatting differences dart format --set-exit-if-changed lib/src/core/geometry.dart --output showexample/lib/graphs/progress_bars.dart (2)
136-137: Consider extracting segment colors to theme or configuration.The hard-coded colors
[Colors.red.shade400, Colors.orange.shade400, Colors.green.shade400]could be made configurable or derived from the theme for better maintainability.Consider extracting to a constant or deriving from theme:
+ // At the top of the file or in a theme configuration + static const List<Color> defaultStackedColors = [ + Color(0xFFEF5350), // Colors.red.shade400 + Color(0xFFFFA726), // Colors.orange.shade400 + Color(0xFF66BB6A), // Colors.green.shade400 + ]; + .geomProgress( orientation: ProgressOrientation.horizontal, style: ProgressStyle.stacked, thickness: 25.0 + (sliderValue * 15.0), cornerRadius: 6.0, showLabel: true, segments: [30.0, 45.0, 25.0], // Three segments - segmentColors: [Colors.red.shade400, Colors.orange.shade400, Colors.green.shade400], + segmentColors: defaultStackedColors, )
1-1: Rundart formatto fix formatting issues.The pipeline indicates formatting changes are needed.
#!/bin/bash # Check the specific formatting differences dart format --set-exit-if-changed example/lib/graphs/progress_bars.dart --output showlib/src/widgets/animated_chart_painter.dart (1)
1-1: Rundart formatto fix formatting issues.#!/bin/bash # Check the specific formatting differences dart format --set-exit-if-changed lib/src/widgets/animated_chart_painter.dart --output showtest/progress_bar_test.dart (2)
215-243: Consider adding test for out-of-range values.Good coverage of different data types. Consider also testing values outside the min/max range to ensure they're properly clamped.
Add a test case for out-of-range values:
testWidgets('should handle out-of-range progress values gracefully', (WidgetTester tester) async { final chart = CristalyseChart() .data([ {'progress': -10}, // Below minValue {'progress': 150}, // Above maxValue {'progress': null}, // Null value {'progress': 'abc'}, // Non-numeric string ]) .geomProgress( orientation: ProgressOrientation.horizontal, minValue: 0.0, maxValue: 100.0, ); await tester.pumpWidget( MaterialApp( home: Scaffold( body: SizedBox( width: 400, height: 300, child: chart.build(), ), ), ), ); await tester.pumpAndSettle(); // Should not crash and should render the widget expect(find.byType(AnimatedCristalyseChartWidget), findsOneWidget); });
1-1: Rundart formatto fix formatting issues.#!/bin/bash # Check the specific formatting differences dart format --set-exit-if-changed test/progress_bar_test.dart --output showlib/src/core/chart.dart (1)
1-1: Rundart formatto fix formatting issues.#!/bin/bash # Check the specific formatting differences dart format --set-exit-if-changed lib/src/core/chart.dart --output show
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
example/lib/graphs/progress_bars.dart(1 hunks)lib/src/core/chart.dart(4 hunks)lib/src/core/geometry.dart(2 hunks)lib/src/widgets/animated_chart_painter.dart(4 hunks)test/progress_bar_test.dart(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Flutter Tests
lib/src/widgets/animated_chart_painter.dart
[error] 1-1: Dart format changes were applied to this file. Run 'dart format' to review and commit formatting changes.
test/progress_bar_test.dart
[error] 1-1: Dart format changes were applied to this file. Run 'dart format' to review and commit formatting changes.
example/lib/graphs/progress_bars.dart
[error] 1-1: Dart format changes were applied to this file. Run 'dart format' to review and commit formatting changes.
lib/src/core/geometry.dart
[error] 1-1: Dart format changes were applied to this file. Run 'dart format' to review and commit formatting changes.
lib/src/core/chart.dart
[error] 1-1: Dart format changes were applied to this file. Run 'dart format' to review and commit formatting changes.
🔇 Additional comments (3)
lib/src/core/geometry.dart (1)
308-322: LGTM! Robust validation for progress geometry parameters.The constructor properly validates all critical parameters with clear error messages. The validation ensures data integrity by checking min/max values, non-negative dimensions, positive durations, and valid geometric properties.
test/progress_bar_test.dart (1)
556-650: Excellent validation test coverage!The validation tests thoroughly cover all edge cases including invalid min/max combinations, negative values, invalid durations, and segment/radii validation. This ensures the API contract is properly enforced.
lib/src/core/chart.dart (1)
392-490: Well-designed progress bar API with comprehensive documentation!The
geomProgressmethod provides excellent flexibility with support for multiple styles (stacked, grouped, gauge, concentric) and comprehensive customization options. The documentation with examples is particularly helpful.
… data test Division by Zero Fixes: - Fix cols calculation in circular progress bar grid layout using math.max(1, ...) - Prevent division by zero when plotArea.width / centerSpacing results in 0 - Ensure safe integer division and modulus operations for row/col calculation - Apply fix to all circular layout methods (circular, gauge, concentric) Enhanced Test Coverage: - Add comprehensive test for invalid progress values (negative, above max, null, strings) - Test graceful handling of out-of-range data without crashes - Verify widget renders successfully with mixed valid/invalid data - Cover edge cases: -25.0, 150.0, null, 'invalid', 0.0, 100.0, 75.0 - All 187 tests passing with robust edge case coverage Production Stability: - Prevents runtime crashes from zero-width plot areas - Handles malformed data gracefully in real-world scenarios - Maintains consistent grid layout behavior under all conditions - Comprehensive validation of data parsing and clamping logic These fixes ensure the progress bar rendering is bulletproof against layout edge cases and invalid data inputs commonly encountered in production.
9177303 to
a534c9d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
lib/src/core/geometry.dart (1)
308-312: Asserts for min/max and duration look good.This addresses prior feedback on validation.
lib/src/core/chart.dart (1)
425-491: Normalize min/max before constructing ProgressGeometry (release-safe).Without normalization,
maxValue <= minValuecan slip in release builds (asserts stripped) and break normalization downstream.CristalyseChart geomProgress({ @@ YAxis? yAxis, }) { - _geometries.add( + // Normalize min/max to ensure a positive range in all build modes. + final double safeMin = minValue ?? 0.0; + final double safeMax = + (maxValue == null || maxValue <= safeMin) ? (safeMin + 1.0) : maxValue!; + + _geometries.add( ProgressGeometry( orientation: orientation ?? ProgressOrientation.horizontal, thickness: thickness ?? 20.0, cornerRadius: cornerRadius ?? 4.0, backgroundColor: backgroundColor, fillColor: fillColor, style: style ?? ProgressStyle.filled, - minValue: minValue ?? 0.0, - maxValue: maxValue ?? 100.0, + minValue: safeMin, + maxValue: safeMax, showLabel: showLabel ?? true, labelStyle: labelStyle, labelFormatter: labelFormatter, fillGradient: fillGradient, strokeWidth: strokeWidth ?? 1.0, strokeColor: strokeColor, labelOffset: labelOffset ?? 5.0, @@ - startAngle: startAngle ?? -1.5707963267948966, // -π/2 - sweepAngle: sweepAngle ?? 3.141592653589793, // π + startAngle: startAngle ?? -math.pi / 2, // -π/2 + sweepAngle: sweepAngle ?? math.pi, // π gaugeRadius: gaugeRadius, showTicks: showTicks ?? false, tickCount: tickCount ?? 10, concentricRadii: concentricRadii, concentricThicknesses: concentricThicknesses, yAxis: yAxis ?? YAxis.primary, ), ); return this; }And add the import at the top:
+import 'dart:math' as math; import 'package:flutter/material.dart';
🧹 Nitpick comments (4)
example/lib/graphs/progress_bars.dart (2)
198-213: Prefer math constants for gauge angles.Improves readability and avoids magic numbers. Adds a local
mathimport.+import 'dart:math' as math; import 'package:cristalyse/cristalyse.dart'; import 'package:flutter/material.dart'; @@ - startAngle: -2.356, // -3π/4 (225 degrees) - sweepAngle: 4.712, // 3π/2 (270 degrees) + startAngle: -3 * math.pi / 4, // 225° + sweepAngle: 3 * math.pi / 2, // 270°Also applies to: 1-2
25-153: Reduce duplication with a small helper.The seven nearly identical chart builders can be parameterized to cut boilerplate and lower maintenance cost.
Also applies to: 155-251
lib/src/core/geometry.dart (1)
236-253: Clarify thickness semantics in docs.Avoids confusion between thickness and radius for circular/gauge.
class ProgressGeometry extends Geometry { final ProgressOrientation orientation; - final double thickness; + /// Horizontal/Vertical: bar thickness in logical pixels. + /// Circular/Gauge: ring stroke width (not radius). + final double thickness;lib/src/core/chart.dart (1)
425-453: Expose per-geometry animation flags.Optional API polish: allow callers to override
animated/animationDurationfor progress without affecting the whole chart.CristalyseChart geomProgress({ ProgressOrientation? orientation, @@ List<double>? concentricThicknesses, YAxis? yAxis, + bool? animated, + Duration? animationDuration, }) { @@ ProgressGeometry( @@ + animated: animated ?? true, + animationDuration: animationDuration ?? const Duration(milliseconds: 800),Also applies to: 458-489
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
example/lib/graphs/progress_bars.dart(1 hunks)example/lib/main.dart(11 hunks)lib/src/core/chart.dart(4 hunks)lib/src/core/geometry.dart(2 hunks)lib/src/widgets/animated_chart_painter.dart(4 hunks)test/progress_bar_test.dart(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- test/progress_bar_test.dart
- example/lib/main.dart
- lib/src/widgets/animated_chart_painter.dart
🔇 Additional comments (3)
example/lib/graphs/progress_bars.dart (2)
105-109: Fix misleading comment for circular thickness."thickness" here is ring stroke width, not radius.
[raise_nitpick_issue]- thickness: 25.0 + (sliderValue * 25.0), // 25-50px radius + thickness: 25.0 + (sliderValue * 25.0), // 25-50px ring stroke width
171-180: Confirm grouped count vs data length.You set groupCount: 4 but
_generateProgressData()yields 5 items. Verify painter behavior (clipping/overflow/auto-wrap).lib/src/core/chart.dart (1)
123-136: Progress mappings wiring looks good.API is consistent with other mapping methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
lib/src/core/geometry.dart (1)
255-257: Only allow segments with stacked style.Prevent accidental use of
segmentsunder non‑stacked styles.assert(segments == null || segments.every((s) => s >= 0), 'all segments must be >= 0'), + assert(segments == null || style == ProgressStyle.stacked, + 'segments are only supported for ProgressStyle.stacked'), assert(style != ProgressStyle.stacked || segments != null, 'stacked style requires non-null segments'),Also applies to: 337-338
🧹 Nitpick comments (9)
lib/src/core/geometry.dart (6)
242-244: Make minValue/maxValue non-nullable (avoid release-mode gaps).They’re always required and asserted non-null. Prefer strong typing to catch misuse at compile time and in release.
Apply:
- final double? minValue; - final double? maxValue; + final double minValue; + final double maxValue; @@ - }) : assert(minValue != null && maxValue != null && minValue < maxValue, + }) : assert(minValue < maxValue, 'minValue must be less than maxValue'),Also applies to: 308-310
266-268: Tighten tick validation when showTicks = true.Currently
showTicks: truewithtickCount: nullpasses. Guard it explicitly.- assert(tickCount == null || tickCount > 0, 'tickCount must be > 0'), + assert(tickCount == null || tickCount > 0, 'tickCount must be > 0'), + assert(!showTicks || (tickCount != null && tickCount > 0), + 'tickCount must be > 0 when showTicks is true'),Also applies to: 319-319
236-241: Constrain gauge/concentric styles to circular orientation.These styles are inherently circular; enforce to avoid painter inconsistencies.
assert(style != ProgressStyle.gauge || gaugeRadius != null, 'gauge style requires non-null gaugeRadius'), + assert(style != ProgressStyle.gauge || orientation == ProgressOrientation.circular, + 'gauge style requires circular orientation'), assert(style != ProgressStyle.concentric || (concentricRadii != null && concentricThicknesses != null), 'concentric style requires non-null concentricRadii and concentricThicknesses'); + assert(style != ProgressStyle.concentric || orientation == ProgressOrientation.circular, + 'concentric style requires circular orientation');Also applies to: 339-343
275-276: Prevent impossible ring geometry: thickness must not exceed radius (gauge).Large
thicknessvs smallgaugeRadiuscan invert/overlap arcs.assert( gaugeRadius == null || gaugeRadius > 0, 'gaugeRadius must be > 0'), + assert(gaugeRadius == null || thickness <= gaugeRadius, + 'thickness must be <= gaugeRadius for gauge style'),Also applies to: 265-266, 321-321, 339-339
238-239: Clamp cornerRadius to avoid visual artifacts.Rounded bars typically cap at half the thickness.
- assert(cornerRadius >= 0, 'cornerRadius must be >= 0'), + assert(cornerRadius >= 0, 'cornerRadius must be >= 0'), + assert(cornerRadius <= thickness / 2, + 'cornerRadius must be <= thickness/2'),Also applies to: 275-276
246-247: Optional: provide a default labelFormatter (consistency with PieGeometry).To avoid per-site instantiations doing formatting.
- final LabelCallback? labelFormatter; + static final _defaultPercentageFormatter = intl.NumberFormat.percentPattern(); + final LabelCallback? labelFormatter; @@ - this.labelFormatter, + this.labelFormatter, @@ - }) : assert(... + }) : assert(...), + labelFormatter = labelFormatter ?? _defaultPercentageFormatter.format;test/progress_geometry_validation_test.dart (3)
118-154: Add a test for showTicks=true with null tickCount.Catches the tightened validation.
@@ test('should validate sweepAngle range', () { @@ }); + + test('should require tickCount when showTicks is true', () { + expect( + () => ProgressGeometry( + showTicks: true, + tickCount: null, + ), + throwsA(isA<AssertionError>()), + ); + });
156-182: Add a test to forbid segments under non-stacked styles.Ensures
segmentsis only used withProgressStyle.stacked.@@ test('should validate segments and segmentColors length matching', () { @@ }); + + test('should forbid segments when style is not stacked', () { + expect( + () => ProgressGeometry( + style: ProgressStyle.filled, + segments: [10.0, 20.0], + ), + throwsA(isA<AssertionError>()), + ); + });
284-301: Add orientation coupling tests for gauge/concentric.Validates circular requirement if adopted.
@@ test('should validate gauge style requires gaugeRadius', () { @@ }); + + test('gauge style should require circular orientation', () { + expect( + () => ProgressGeometry( + style: ProgressStyle.gauge, + gaugeRadius: 50.0, + orientation: ProgressOrientation.horizontal, + ), + throwsA(isA<AssertionError>()), + ); + }); @@ test('should validate concentric style requires both concentricRadii and concentricThicknesses', () { @@ }); + + test('concentric style should require circular orientation', () { + expect( + () => ProgressGeometry( + style: ProgressStyle.concentric, + concentricRadii: [10.0, 20.0], + concentricThicknesses: [2.0, 4.0], + orientation: ProgressOrientation.vertical, + ), + throwsA(isA<AssertionError>()), + ); + });Also applies to: 331-340
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
lib/src/core/geometry.dart(2 hunks)test/progress_geometry_validation_test.dart(1 hunks)
🧰 Additional context used
🪛 GitHub Actions: Flutter Tests
test/progress_geometry_validation_test.dart
[error] 1-1: Dart format check failed. Changes were made to this file by 'dart format' (exit code 1 due to --set-exit-if-changed). Review and commit the reformatted file.
lib/src/core/geometry.dart
[error] 1-1: Dart format check failed. Changes were made to this file by 'dart format' (exit code 1 due to --set-exit-if-changed). Review and commit the reformatted file.
🔇 Additional comments (4)
lib/src/core/geometry.dart (2)
212-345: API surface for progress geometry looks solid.Enums, defaults, and validations are comprehensive and consistent with existing geometries.
If you accept the new asserts, please add/adjust unit tests accordingly (see suggestions in the test file comments).
1-1: Fix formatting to unblock CI.
Verification failed here: Dart SDK not available in the verification environment (/bin/bash: dart: command not found). Run: dart format lib/src/core/geometry.dart (or dart format .) and commit the result so CI can pass.test/progress_geometry_validation_test.dart (2)
1-364: Great coverage on constructor invariants.Tests are thorough and map 1:1 to asserts.
1-1: Run dart format and commit.
Rundart format .(ordart format --set-exit-if-changed -o none .) and commit — CI is failing for formatting in test/progress_geometry_validation_test.dart. Verification here failed becausedartis not installed in the environment (/bin/bash: line 3: dart: command not found).
- Add assertions for minValue < maxValue and positive animationDuration - Validate non-negative values for thickness, cornerRadius, strokeWidth, labelOffset - Ensure positive values for groupCount, tickCount, and gaugeRadius - Validate sweepAngle is > 0 and <= 2π (360 degrees) - Enforce matching array lengths for segments/segmentColors and concentricRadii/concentricThicknesses - Add style-specific validations (stacked requires segments, gauge requires gaugeRadius, concentric requires both radii and thicknesses) - Include comprehensive test coverage with 19 validation tests - All assertions provide clear error messages for debugging - Prevents runtime crashes from invalid configurations
8263e99 to
0a918f3
Compare
- Added gaugeRadius: 80.0 to gauge progress bar configuration - Fixes assertion error: 'gauge style requires non-null gaugeRadius' - Updated .gitignore to exclude debug files - Resolves runtime crash in progress bars example
…Router ## New Features - **URL-based routing**: Each chart now has its own route (e.g., /scatter-plot, /line-chart) - **Navigation 2.0**: Full GoRouter implementation with proper state management - **19 dedicated routes**: All chart types accessible via clean URLs - **Navigation drawer**: Comprehensive chart gallery with route highlighting - **Route indicators**: Visual feedback for current route with left border - **Mobile-friendly**: Responsive drawer navigation for all screen sizes ## Routes Added - /scatter-plot - Interactive scatter plots with sizing and categorization - /interactive - Hover and tap interactions with rich tooltips - /panning - Real-time pan detection with range callbacks - /line-chart - Smooth line charts with customizable styles - /area-chart - Area fills with progressive animation - /bubble-chart - Three-dimensional data visualization - /bar-chart - Classic bar charts with animations - /grouped-bars - Multiple bar groups for comparison - /horizontal-bars - Horizontal bar charts for categorical data - /stacked-bars - Part-to-whole relationships - /pie-chart - Interactive pie charts with segments - /dual-y-axis - Dual-axis charts for different metrics - /heatmap - Color-coded heatmaps for patterns - /contributions - GitHub-style contribution graphs - /progress-bars - Multiple progress styles including gauge/concentric - /multi-series - Multi-series line charts with category colors - /export - SVG export functionality - /gradient-bars - Beautiful gradient fills (experimental) - /advanced-gradients - Multiple gradient types (experimental) ## Technical Implementation - **AppRouter class**: Centralized route management with metadata - **ChartScreen widget**: Dedicated screen for individual charts - **Route state management**: Proper current route detection and highlighting - **Navigation drawer**: Full chart gallery with descriptions and badges - **SEO-friendly URLs**: Clean, descriptive routes for each chart type - **Browser integration**: Back/forward buttons and direct URL access ## UI/UX Improvements - **Clean navigation**: No more horizontal tab overflow - **Better organization**: Categorized navigation with New/Experimental badges - **Responsive design**: Works across desktop, tablet, and mobile - **Visual indicators**: Clear current route highlighting with blue left border - **Accessibility**: Proper semantic navigation structure ## Dependencies - Added go_router: ^14.6.2 for Navigation 2.0 support All existing chart functionality preserved with enhanced navigation experience.\
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
lib/src/widgets/animated_chart_painter.dart (1)
39-94: Update constructor documentation to include progress columns.The constructor documentation (lines 39-67) mentions
heatMapXColumn,heatMapYColumn, andheatMapValueColumnbut omits the newly addedprogressValueColumn,progressLabelColumn, andprogressCategoryColumnparameters. Add brief parameter descriptions for these new fields to keep the documentation complete and consistent./// - [heatMapXColumn]: Column name for heat map X-axis categories. /// - [heatMapYColumn]: Column name for heat map Y-axis categories. /// - [heatMapValueColumn]: Column name for heat map cell values. + /// - [progressValueColumn]: Column name for progress bar values. + /// - [progressLabelColumn]: Column name for progress bar labels. + /// - [progressCategoryColumn]: Column name for progress bar categories. /// - [geometries]: List of visual geometries that define how data is rendered.
♻️ Duplicate comments (1)
lib/src/core/chart.dart (1)
488-519: Validate min/max to avoid zero or negative range.If
maxValue <= minValue, progress normalization will fail downstream. The values should be normalized before constructingProgressGeometry.Apply this diff to add validation:
+ final double safeMin = minValue ?? 0.0; + final double safeMax = + (maxValue == null || maxValue <= safeMin) ? (safeMin + 1.0) : maxValue!; _geometries.add( ProgressGeometry( orientation: orientation ?? ProgressOrientation.horizontal, thickness: thickness ?? 20.0, cornerRadius: cornerRadius ?? 4.0, backgroundColor: backgroundColor, fillColor: fillColor, style: style ?? ProgressStyle.filled, - minValue: minValue ?? 0.0, - maxValue: maxValue ?? 100.0, + minValue: safeMin, + maxValue: safeMax, showLabel: showLabel ?? true, labelStyle: labelStyle, labelFormatter: labelFormatter, fillGradient: fillGradient, strokeWidth: strokeWidth ?? 1.0, strokeColor: strokeColor, labelOffset: labelOffset ?? 5.0, segments: segments, segmentColors: segmentColors, groupSpacing: groupSpacing ?? 8.0, groupCount: groupCount ?? 1, startAngle: startAngle ?? -1.5707963267948966, sweepAngle: sweepAngle ?? 3.141592653589793, gaugeRadius: gaugeRadius, showTicks: showTicks ?? false, tickCount: tickCount ?? 10, concentricRadii: concentricRadii, concentricThicknesses: concentricThicknesses, yAxis: yAxis ?? YAxis.primary, ), );This issue was previously flagged and has not been addressed.
🧹 Nitpick comments (3)
lib/src/widgets/animated_chart_painter.dart (1)
2925-3009: Consider adding gradient support for circular progress.The circular progress rendering correctly prevents division-by-zero with
math.max(1, ...)on line 2946 (addressing a past review concern). However, the code currently assigns only a solid color toprogressPaint.color(line 2978) and does not handlegeometry.fillGradientor gradients fromcolorScale, unlike the horizontal and vertical bar renderers. A past review comment suggested supporting gradients for circular progress arcs by creating a shader from a gradient.Consider applying the same gradient-handling logic used in horizontal/vertical bars to circular progress for consistency and richer visual effects. If gradient support is intentionally omitted for circular progress, document this design choice.
// Priority: explicit fillColor > category-based color > theme palette by index - Color fillColor = geometry.fillColor ?? + final dynamic fillSource = geometry.fillColor ?? (categoryColumn != null ? colorScale.scale(point[categoryColumn]) : theme.colorPalette[index % theme.colorPalette.length]); - progressPaint.color = fillColor; + if (geometry.fillGradient != null) { + progressPaint.shader = geometry.fillGradient!.createShader( + Rect.fromCircle(center: center, radius: radius)); + } else if (fillSource is Gradient) { + progressPaint.shader = fillSource.createShader( + Rect.fromCircle(center: center, radius: radius)); + } else { + progressPaint.color = (fillSource as Color); + }example/lib/graphs/striped_progress_example.dart (1)
5-97: Consider reusing generated data.The example is well-structured and demonstrates striped progress bars effectively. However,
_generateProgressData()is called twice (lines 39 and 70), which regenerates identical data.Consider generating the data once for slight efficiency improvement:
Widget buildStripedProgressExample(ChartTheme currentTheme) { + final progressData = _generateProgressData(); return SingleChildScrollView( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ ... SizedBox( height: 300, child: CristalyseChart() - .data(_generateProgressData()) + .data(progressData) .mappingProgress( value: 'completion', label: 'task', category: 'department') ... ), ... SizedBox( height: 300, child: CristalyseChart() - .data(_generateProgressData()) + .data(progressData) .mappingProgress( value: 'completion', label: 'task', category: 'department') ... ), ], ), ); }example/lib/router/app_router.dart (1)
7-125: Consider refactoring route definitions to reduce duplication.The route definitions follow an identical pattern with only the path and chartIndex varying. This creates maintenance overhead when adding, removing, or reordering routes.
Consider extracting route generation into a helper function:
static final GoRouter _router = GoRouter( initialLocation: '/scatter-plot', routes: routes .asMap() .entries .map((entry) => GoRoute( path: entry.value.path, builder: (BuildContext context, GoRouterState state) { return ChartScreen(chartIndex: entry.key); }, )) .toList(), );This approach:
- Eliminates repetitive builder code
- Automatically maintains chartIndex ordering based on the
routeslist- Reduces the chance of index mismatches
- Makes adding/removing routes simpler (single location update)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
example/pubspec.lockis excluded by!**/*.lock
📒 Files selected for processing (12)
.github/workflows/test.yml(1 hunks).gitignore(1 hunks)example/lib/graphs/progress_bars.dart(1 hunks)example/lib/graphs/striped_progress_example.dart(1 hunks)example/lib/main.dart(3 hunks)example/lib/router/app_router.dart(1 hunks)example/lib/screens/chart_screen.dart(1 hunks)example/lib/utils/chart_feature_list.dart(1 hunks)example/pubspec.yaml(1 hunks)lib/src/core/chart.dart(4 hunks)lib/src/widgets/animated_chart_painter.dart(6 hunks)test/progress_bar_test.dart(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- .gitignore
🚧 Files skipped from review as they are similar to previous changes (1)
- example/lib/graphs/progress_bars.dart
🔇 Additional comments (28)
.github/workflows/test.yml (1)
20-20: Approve version bump—Flutter 3.35.5 is a valid stable release published on 2025-09-29.lib/src/widgets/animated_chart_painter.dart (13)
24-26: LGTM! New progress-mapping fields follow established patterns.The three new nullable string fields for progress-bar data mapping are consistent with the existing column-mapping fields (xColumn, yColumn, etc.) and integrate cleanly into the class structure.
200-242: LGTM! Progress chart detection and axis skip logic are correct.The
hasProgressChartflag properly detectsProgressGeometryinstances, and the updated grid/axes skip logic is consistent with the behavior for pie and heat map charts. The conditional at line 239 (hasHeatMapChart && !hasProgressChart) ensures that heat map axes are drawn only when there's no progress chart, which is the expected behavior.
680-689: LGTM! ProgressGeometry dispatch follows existing patterns.The dispatch logic for
ProgressGeometryis consistent with other geometry type handlers (points, lines, bars, etc.) and correctly forwards the required parameters to the new_drawProgressAnimatedmethod.
2494-2652: LGTM! Normalization and dispatch logic are robust.The
_drawProgressAnimatedmethod correctly:
- Falls back to standard columns when progress-specific columns are null (lines 2504-2506).
- Guards against division-by-zero with a safe fallback when the value range is invalid (lines 2524-2528), addressing previous review concerns.
- Applies staggered per-item animation delays (lines 2534-2541) for smooth visual effects.
- Dispatches to the appropriate renderer based on style and orientation (lines 2546-2651), with a clear hierarchy: style-specific renderers first, then orientation-based for basic styles.
2654-2786: LGTM! Horizontal progress bar rendering with comprehensive gradient support.The
_drawHorizontalProgressBarmethod correctly:
- Applies dynamic spacing and scaling to fit multiple bars within the plot area (lines 2667-2679).
- Handles both
ColorandGradientfill sources with a safe extraction helpergetFillColor()(lines 2715-2730), addressing the past review concern about gradients fromcolorScale.- Branches appropriately for explicit
fillGradient, gradient fromcolorScale, default gradient style, striped style, and solid color (lines 2732-2772).- Avoids double-drawing for striped style by returning early (lines 2753-2768).
2788-2923: LGTM! Vertical progress bar rendering mirrors horizontal logic correctly.The
_drawVerticalProgressBarmethod correctly:
- Applies vertical layout with bottom-up fill (lines 2838-2841).
- Uses the same safe
getFillColor()helper and gradient-handling logic as the horizontal bar (lines 2853-2910).- Uses appropriate vertical gradient direction (Alignment.bottomCenter to topCenter) for default gradient style (lines 2883-2890).
- Avoids double-drawing for striped style by returning early (lines 2891-2906).
3012-3055: LGTM! Stripe rendering with proper clipping.The
_drawStripeshelper correctly:
- Creates a semi-transparent darker color for stripes (lines 3019-3024).
- Clips the canvas to the rounded rect boundary to prevent stripe bleed (lines 3035-3039).
- Draws diagonal stripes at 45-degree angles using trapezoid paths (lines 3042-3051).
- Restores canvas state after clipping (line 3054).
3058-3075: LGTM! Stroke drawing helper is straightforward and correct.The
_drawProgressBarStrokehelper correctly draws a border stroke on the progress bar whenstrokeWidth > 0, using either the geometry's stroke color or the theme's border color as a fallback.
3078-3120: LGTM! Label positioning is correct for both orientations.The
_drawProgressBarLabelhelper correctly positions labels based on bar orientation:
- Horizontal bars: labels positioned to the left of the bar, right-aligned (lines 3101-3107).
- Vertical bars: labels positioned below the bar, centered (lines 3108-3115).
3123-3267: LGTM! Stacked progress bar rendering with proper segment stacking.The
_drawStackedProgressBarmethod correctly:
- Calculates bar dimensions based on orientation (lines 3139-3156).
- Includes a safety check to prevent division-by-zero when
totalValue <= 0(lines 3172-3174).- Draws each segment with correct color selection (segmentColors, category-based, or theme palette) and stacking logic using
currentPosition(lines 3176-3220).- Draws stroke and label appropriately (lines 3223-3266).
3270-3445: LGTM! Grouped progress bar rendering with dynamic scaling.The
_drawGroupedProgressBarmethod correctly:
- Loops through
groupCountto draw multiple bars side-by-side for each data item (lines 3288-3390).- Applies dynamic scaling to fit bars within the plot area (lines 3302-3320 for horizontal, 3333-3347 for vertical).
- Varies
groupValueslightly for each group for demo purposes (lines 3289-3291).- Draws the label once per data item (group) rather than per individual group bar (lines 3392-3444).
3448-3568: LGTM! Gauge progress bar rendering with needle indicator.The
_drawGaugeProgressBarmethod correctly:
- Calculates gauge radius and grid layout for multiple gauges (lines 3460-3469).
- Draws background arc, tick marks (if enabled), and progress arc (lines 3473-3530).
- Renders a needle indicator from center to the progress position with a red center dot (lines 3532-3545).
- Positions label below the gauge (lines 3547-3567).
3571-3659: LGTM! Concentric progress bar rendering with multiple rings.The
_drawConcentricProgressBarmethod correctly:
- Calculates radii and thicknesses for multiple concentric rings (lines 3583-3587).
- Draws each ring with a varied progress value for demo purposes (lines 3607-3608).
- Uses the theme color palette to assign distinct colors to each ring (lines 3610-3611).
- Positions label below all concentric rings (lines 3638-3658).
example/pubspec.yaml (1)
18-18: Verify if go_router ^14.6.2 is the intended version.The added dependency uses
go_router: ^14.6.2. According to the learnings, version 14.6.2 is a valid, non-breaking release with internal refactors. However, the latest stable version mentioned in the learnings is 16.2.4, which includes additional features and fixes.If you're adding router-based navigation for the first time in the example app, consider whether upgrading to a more recent version (e.g.,
^16.0.0) is appropriate. Otherwise, if 14.6.2 is intentionally chosen for compatibility or stability, this is acceptable.Based on learnings
example/lib/utils/chart_feature_list.dart (1)
104-111: LGTM! New progress bars feature list is accurate and complete.The added case 14 correctly describes the progress-bar features introduced in this PR, including multiple orientations, advanced styles, gradient fills, smooth animations, and label support. The feature descriptions are clear, concise, and align with the new
ProgressGeometryand rendering logic.test/progress_bar_test.dart (9)
8-53: LGTM! Clean unit tests for ProgressGeometry.The tests comprehensively verify default and custom values for all ProgressGeometry properties. Well-structured and clear.
55-160: LGTM! Comprehensive chart API tests.The tests validate the progress chart API with various orientations and styles, including a widget rendering test for striped progress bars. Well-organized.
162-183: LGTM! Enum validation tests.The tests verify enum counts and expected values for ProgressOrientation and ProgressStyle, which helps prevent accidental changes.
185-283: LGTM! Thorough widget rendering tests.The tests verify widget builds without errors, handles empty data gracefully, and supports multiple data types (int, double, string). Excellent coverage for edge cases.
285-326: LGTM! Animation test covers lifecycle.The test verifies the chart animates without crashing by pumping at different animation stages. Adequate coverage for ensuring animations are stable.
328-364: LGTM! Theme integration test.The test verifies custom themes apply to progress charts with categories, ensuring the theming API works correctly.
366-600: LGTM! Comprehensive enhanced styles tests.The tests thoroughly cover advanced progress styles (stacked, grouped, gauge, concentric) with both unit tests for geometry configuration and widget rendering tests. Excellent coverage.
602-697: LGTM! Comprehensive input validation tests.The tests verify that ProgressGeometry rejects invalid inputs with appropriate assertion errors. Covers min/max, thickness, cornerRadius, duration, segments, and radii. The final test ensures valid configurations work. Excellent validation coverage.
699-777: LGTM! Thorough edge case coverage.The tests comprehensively verify edge cases including zero range validation, NaN/Infinity handling, and out-of-range/invalid values (negative, above max, null, invalid strings). The test at lines 739-776 addresses the past review comment. Excellent robustness testing.
example/lib/graphs/striped_progress_example.dart (1)
100-112: LGTM! Clean data generator.The helper function generates varied sample data with reasonable completion values and multiple departments. Well-structured.
example/lib/main.dart (2)
3-3: LGTM! Correct router import.The import adds the necessary AppRouter for the router-based navigation migration.
14-34: LGTM! Clean router migration.The changes correctly migrate from
MaterialApptoMaterialApp.routerwith properrouterConfigwiring. Theme configuration remains intact. This aligns with Navigator 2.0 and go_router best practices.
- Remove colorScale dependency for theme colors in all progress bar types - Use theme.colorPalette directly like concentric rings already do - Simplify color logic by removing unnecessary Gradient type checking - All progress bars now respond immediately to theme changes
- Add progress bars documentation (charts/progress-bars.mdx) - Horizontal, vertical, and circular orientations - Advanced styles: stacked, grouped, gauge, concentric - Interactive features and animations - Real-world examples and troubleshooting - Enhance SEO across all documentation - Add comprehensive metadata with Open Graph and Twitter Cards - Add SEO frontmatter to key pages (index, quickstart, installation, charts) - Improve meta descriptions and keywords for search engines - Update all canonical URLs to docs.cristalyse.com - Add custom 404 error page with helpful navigation - Improve contextual menu copy for better engagement - Add updates.mdx with subscribable RSS feed using Update components - Fix broken links - Remove template files (essentials/images.mdx, essentials/settings.mdx) - Comment out missing bubble chart image - Validate all internal links - Update version history and changelog - Add v1.7.0 to README.md, CHANGELOG.md, installation.mdx, updates.mdx - Document progress bar features and documentation improvements All documentation now optimized for SEO with proper metadata, social sharing, and user engagement.
Summary by CodeRabbit
New Features
Tests
Documentation
Chores