mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 13:58:47 +00:00
Web charts common update (#111)
This commit is contained in:
1
web/charts/common/.gitignore
vendored
Normal file
1
web/charts/common/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
build/
|
||||||
32
web/charts/common/analysis_options.yaml
Normal file
32
web/charts/common/analysis_options.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
include: package:pedantic/analysis_options.yaml
|
||||||
|
|
||||||
|
analyzer:
|
||||||
|
# strong-mode:
|
||||||
|
# implicit-casts: false
|
||||||
|
# implicit-dynamic: false
|
||||||
|
|
||||||
|
linter:
|
||||||
|
rules:
|
||||||
|
- avoid_types_on_closure_parameters
|
||||||
|
- avoid_void_async
|
||||||
|
- await_only_futures
|
||||||
|
- camel_case_types
|
||||||
|
- cancel_subscriptions
|
||||||
|
- close_sinks
|
||||||
|
# TODO(domesticmouse): rename constants
|
||||||
|
# - constant_identifier_names
|
||||||
|
- control_flow_in_finally
|
||||||
|
- empty_statements
|
||||||
|
# TODO(domesticmouse): implement hashCode methods
|
||||||
|
# - hash_and_equals
|
||||||
|
- implementation_imports
|
||||||
|
- non_constant_identifier_names
|
||||||
|
- package_api_docs
|
||||||
|
- package_names
|
||||||
|
- package_prefixed_library_names
|
||||||
|
- test_types_in_equals
|
||||||
|
- throw_in_finally
|
||||||
|
- unnecessary_brace_in_string_interps
|
||||||
|
- unnecessary_getters_setters
|
||||||
|
- unnecessary_new
|
||||||
|
- unnecessary_statements
|
||||||
@@ -37,7 +37,6 @@ class BarChart extends OrdinalCartesianChart {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
SeriesRenderer<String> makeDefaultRenderer() {
|
SeriesRenderer<String> makeDefaultRenderer() {
|
||||||
return new BarRenderer<String>()
|
return BarRenderer<String>()..rendererId = SeriesRenderer.defaultRendererId;
|
||||||
..rendererId = SeriesRenderer.defaultRendererId;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ class BarLabelDecorator<D> extends BarRendererDecorator<D> {
|
|||||||
static const _defaultLabelPadding = 5;
|
static const _defaultLabelPadding = 5;
|
||||||
static const _defaultLabelAnchor = BarLabelAnchor.start;
|
static const _defaultLabelAnchor = BarLabelAnchor.start;
|
||||||
static final _defaultInsideLabelStyle =
|
static final _defaultInsideLabelStyle =
|
||||||
new TextStyleSpec(fontSize: 12, color: Color.white);
|
TextStyleSpec(fontSize: 12, color: Color.white);
|
||||||
static final _defaultOutsideLabelStyle =
|
static final _defaultOutsideLabelStyle =
|
||||||
new TextStyleSpec(fontSize: 12, color: Color.black);
|
TextStyleSpec(fontSize: 12, color: Color.black);
|
||||||
|
|
||||||
/// Configures [TextStyleSpec] for labels placed inside the bars.
|
/// Configures [TextStyleSpec] for labels placed inside the bars.
|
||||||
final TextStyleSpec insideLabelStyleSpec;
|
final TextStyleSpec insideLabelStyleSpec;
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ import 'base_bar_renderer_element.dart' show BaseBarRendererElement;
|
|||||||
///
|
///
|
||||||
/// In grouped stacked mode, this list will contain a combination of domain
|
/// In grouped stacked mode, this list will contain a combination of domain
|
||||||
/// value and series category.
|
/// value and series category.
|
||||||
const domainValuesKey = const AttributeKey<Set>('BarLaneRenderer.domainValues');
|
const domainValuesKey = AttributeKey<Set>('BarLaneRenderer.domainValues');
|
||||||
|
|
||||||
/// Renders series data as a series of bars with lanes.
|
/// Renders series data as a series of bars with lanes.
|
||||||
///
|
///
|
||||||
@@ -63,17 +63,16 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
/// as the data was given to the chart. For the case where both grouping and
|
/// as the data was given to the chart. For the case where both grouping and
|
||||||
/// stacking are disabled, this means that bars for data later in the series
|
/// stacking are disabled, this means that bars for data later in the series
|
||||||
/// will be drawn "on top of" bars earlier in the series.
|
/// will be drawn "on top of" bars earlier in the series.
|
||||||
final _barLaneStackMap = new LinkedHashMap<String, List<AnimatedBar<D>>>();
|
final _barLaneStackMap = LinkedHashMap<String, List<AnimatedBar<D>>>();
|
||||||
|
|
||||||
/// Store a map of flags to track whether all measure values for a given
|
/// Store a map of flags to track whether all measure values for a given
|
||||||
/// domain value are null, for every series on the chart.
|
/// domain value are null, for every series on the chart.
|
||||||
final _allMeasuresForDomainNullMap = new LinkedHashMap<D, bool>();
|
final _allMeasuresForDomainNullMap = LinkedHashMap<D, bool>();
|
||||||
|
|
||||||
factory BarLaneRenderer({BarLaneRendererConfig config, String rendererId}) {
|
factory BarLaneRenderer({BarLaneRendererConfig config, String rendererId}) {
|
||||||
rendererId ??= 'bar';
|
rendererId ??= 'bar';
|
||||||
config ??= new BarLaneRendererConfig();
|
config ??= BarLaneRendererConfig();
|
||||||
return new BarLaneRenderer._internal(
|
return BarLaneRenderer._internal(config: config, rendererId: rendererId);
|
||||||
config: config, rendererId: rendererId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BarLaneRenderer._internal({BarLaneRendererConfig config, String rendererId})
|
BarLaneRenderer._internal({BarLaneRendererConfig config, String rendererId})
|
||||||
@@ -86,11 +85,11 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
|
|
||||||
_allMeasuresForDomainNullMap.clear();
|
_allMeasuresForDomainNullMap.clear();
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
final domainFn = series.domainFn;
|
final domainFn = series.domainFn;
|
||||||
final measureFn = series.rawMeasureFn;
|
final measureFn = series.rawMeasureFn;
|
||||||
|
|
||||||
final domainValues = new Set<D>();
|
final domainValues = Set<D>();
|
||||||
|
|
||||||
for (var barIndex = 0; barIndex < series.data.length; barIndex++) {
|
for (var barIndex = 0; barIndex < series.data.length; barIndex++) {
|
||||||
final domain = domainFn(barIndex);
|
final domain = domainFn(barIndex);
|
||||||
@@ -118,7 +117,7 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
super.update(seriesList, isAnimatingThisDraw);
|
super.update(seriesList, isAnimatingThisDraw);
|
||||||
|
|
||||||
// Add gray bars to render under every bar stack.
|
// Add gray bars to render under every bar stack.
|
||||||
seriesList.forEach((ImmutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
Set<D> domainValues = series.getAttr(domainValuesKey) as Set<D>;
|
Set<D> domainValues = series.getAttr(domainValuesKey) as Set<D>;
|
||||||
|
|
||||||
final domainAxis = series.getAttr(domainAxisKey) as ImmutableAxis<D>;
|
final domainAxis = series.getAttr(domainAxisKey) as ImmutableAxis<D>;
|
||||||
@@ -133,14 +132,14 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
|
|
||||||
// Create a fake series for [BarLabelDecorator] to use when looking up the
|
// Create a fake series for [BarLabelDecorator] to use when looking up the
|
||||||
// index of each datum.
|
// index of each datum.
|
||||||
final laneSeries = new MutableSeries<D>.clone(seriesList[0]);
|
final laneSeries = MutableSeries<D>.clone(seriesList[0]);
|
||||||
laneSeries.data = [];
|
laneSeries.data = [];
|
||||||
|
|
||||||
// Don't render any labels on the swim lanes.
|
// Don't render any labels on the swim lanes.
|
||||||
laneSeries.labelAccessorFn = (int index) => '';
|
laneSeries.labelAccessorFn = (index) => '';
|
||||||
|
|
||||||
var laneSeriesIndex = 0;
|
var laneSeriesIndex = 0;
|
||||||
domainValues.forEach((D domainValue) {
|
domainValues.forEach((domainValue) {
|
||||||
// Skip adding any background bars if they will be covered up by the
|
// Skip adding any background bars if they will be covered up by the
|
||||||
// domain-spanning null bar.
|
// domain-spanning null bar.
|
||||||
if (_allMeasuresForDomainNullMap[domainValue] == true) {
|
if (_allMeasuresForDomainNullMap[domainValue] == true) {
|
||||||
@@ -168,8 +167,7 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
barStackMapKey, () => <AnimatedBar<D>>[]);
|
barStackMapKey, () => <AnimatedBar<D>>[]);
|
||||||
|
|
||||||
// If we already have an AnimatingBar for that index, use it.
|
// If we already have an AnimatingBar for that index, use it.
|
||||||
var animatingBar = barStackList.firstWhere(
|
var animatingBar = barStackList.firstWhere((bar) => bar.key == barKey,
|
||||||
(AnimatedBar bar) => bar.key == barKey,
|
|
||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
|
|
||||||
// If we don't have any existing bar element, create a new bar and have
|
// If we don't have any existing bar element, create a new bar and have
|
||||||
@@ -183,7 +181,7 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
previousBarGroupWeight: previousBarGroupWeight,
|
previousBarGroupWeight: previousBarGroupWeight,
|
||||||
barGroupWeight: barGroupWeight,
|
barGroupWeight: barGroupWeight,
|
||||||
color: (config as BarLaneRendererConfig).backgroundBarColor,
|
color: (config as BarLaneRendererConfig).backgroundBarColor,
|
||||||
details: new BarRendererElement<D>(),
|
details: BarRendererElement<D>(),
|
||||||
domainValue: domainValue,
|
domainValue: domainValue,
|
||||||
domainAxis: domainAxis,
|
domainAxis: domainAxis,
|
||||||
domainWidth: domainAxis.rangeBand.round(),
|
domainWidth: domainAxis.rangeBand.round(),
|
||||||
@@ -212,7 +210,7 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
previousBarGroupWeight: previousBarGroupWeight,
|
previousBarGroupWeight: previousBarGroupWeight,
|
||||||
barGroupWeight: barGroupWeight,
|
barGroupWeight: barGroupWeight,
|
||||||
color: (config as BarLaneRendererConfig).backgroundBarColor,
|
color: (config as BarLaneRendererConfig).backgroundBarColor,
|
||||||
details: new BarRendererElement<D>(),
|
details: BarRendererElement<D>(),
|
||||||
domainValue: domainValue,
|
domainValue: domainValue,
|
||||||
domainAxis: domainAxis,
|
domainAxis: domainAxis,
|
||||||
domainWidth: domainAxis.rangeBand.round(),
|
domainWidth: domainAxis.rangeBand.round(),
|
||||||
@@ -252,15 +250,15 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
// Create a fake series for [BarLabelDecorator] to use when looking up the
|
// Create a fake series for [BarLabelDecorator] to use when looking up the
|
||||||
// index of each datum. We don't care about any other series values for
|
// index of each datum. We don't care about any other series values for
|
||||||
// the merged lanes, so just clone the first series.
|
// the merged lanes, so just clone the first series.
|
||||||
final mergedSeries = new MutableSeries<D>.clone(seriesList[0]);
|
final mergedSeries = MutableSeries<D>.clone(seriesList[0]);
|
||||||
mergedSeries.data = [];
|
mergedSeries.data = [];
|
||||||
|
|
||||||
// Add a label accessor that returns the empty lane label.
|
// Add a label accessor that returns the empty lane label.
|
||||||
mergedSeries.labelAccessorFn =
|
mergedSeries.labelAccessorFn =
|
||||||
(int index) => (config as BarLaneRendererConfig).emptyLaneLabel;
|
(index) => (config as BarLaneRendererConfig).emptyLaneLabel;
|
||||||
|
|
||||||
var mergedSeriesIndex = 0;
|
var mergedSeriesIndex = 0;
|
||||||
_allMeasuresForDomainNullMap.forEach((D domainValue, bool allNull) {
|
_allMeasuresForDomainNullMap.forEach((domainValue, allNull) {
|
||||||
if (allNull) {
|
if (allNull) {
|
||||||
// Add a fake datum to the series for [BarLabelDecorator].
|
// Add a fake datum to the series for [BarLabelDecorator].
|
||||||
final datum = {'index': mergedSeriesIndex};
|
final datum = {'index': mergedSeriesIndex};
|
||||||
@@ -274,8 +272,7 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
barStackMapKey, () => <AnimatedBar<D>>[]);
|
barStackMapKey, () => <AnimatedBar<D>>[]);
|
||||||
|
|
||||||
// If we already have an AnimatingBar for that index, use it.
|
// If we already have an AnimatingBar for that index, use it.
|
||||||
var animatingBar = barStackList.firstWhere(
|
var animatingBar = barStackList.firstWhere((bar) => bar.key == barKey,
|
||||||
(AnimatedBar bar) => bar.key == barKey,
|
|
||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
|
|
||||||
// If we don't have any existing bar element, create a new bar and have
|
// If we don't have any existing bar element, create a new bar and have
|
||||||
@@ -289,7 +286,7 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
previousBarGroupWeight: previousBarGroupWeight,
|
previousBarGroupWeight: previousBarGroupWeight,
|
||||||
barGroupWeight: barGroupWeight,
|
barGroupWeight: barGroupWeight,
|
||||||
color: (config as BarLaneRendererConfig).backgroundBarColor,
|
color: (config as BarLaneRendererConfig).backgroundBarColor,
|
||||||
details: new BarRendererElement<D>(),
|
details: BarRendererElement<D>(),
|
||||||
domainValue: domainValue,
|
domainValue: domainValue,
|
||||||
domainAxis: domainAxis,
|
domainAxis: domainAxis,
|
||||||
domainWidth: domainAxis.rangeBand.round(),
|
domainWidth: domainAxis.rangeBand.round(),
|
||||||
@@ -318,7 +315,7 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
previousBarGroupWeight: previousBarGroupWeight,
|
previousBarGroupWeight: previousBarGroupWeight,
|
||||||
barGroupWeight: barGroupWeight,
|
barGroupWeight: barGroupWeight,
|
||||||
color: (config as BarLaneRendererConfig).backgroundBarColor,
|
color: (config as BarLaneRendererConfig).backgroundBarColor,
|
||||||
details: new BarRendererElement<D>(),
|
details: BarRendererElement<D>(),
|
||||||
domainValue: domainValue,
|
domainValue: domainValue,
|
||||||
domainAxis: domainAxis,
|
domainAxis: domainAxis,
|
||||||
domainWidth: domainAxis.rangeBand.round(),
|
domainWidth: domainAxis.rangeBand.round(),
|
||||||
@@ -352,13 +349,12 @@ class BarLaneRenderer<D> extends BarRenderer<D> {
|
|||||||
/// Paints the current bar data on the canvas.
|
/// Paints the current bar data on the canvas.
|
||||||
@override
|
@override
|
||||||
void paint(ChartCanvas canvas, double animationPercent) {
|
void paint(ChartCanvas canvas, double animationPercent) {
|
||||||
_barLaneStackMap.forEach((String stackKey, List<AnimatedBar<D>> barStack) {
|
_barLaneStackMap.forEach((stackKey, barStack) {
|
||||||
// Turn this into a list so that the getCurrentBar isn't called more than
|
// Turn this into a list so that the getCurrentBar isn't called more than
|
||||||
// once for each animationPercent if the barElements are iterated more
|
// once for each animationPercent if the barElements are iterated more
|
||||||
// than once.
|
// than once.
|
||||||
List<BarRendererElement<D>> barElements = barStack
|
List<BarRendererElement<D>> barElements = barStack
|
||||||
.map((AnimatedBar<D> animatingBar) =>
|
.map((animatingBar) => animatingBar.getCurrentBar(animationPercent))
|
||||||
animatingBar.getCurrentBar(animationPercent))
|
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
paintBar(canvas, animationPercent, barElements);
|
paintBar(canvas, animationPercent, barElements);
|
||||||
|
|||||||
@@ -75,8 +75,7 @@ class BarLaneRendererConfig extends BarRendererConfig<String> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
BarLaneRenderer<String> build() {
|
BarLaneRenderer<String> build() {
|
||||||
return new BarLaneRenderer<String>(
|
return BarLaneRenderer<String>(config: this, rendererId: customRendererId);
|
||||||
config: this, rendererId: customRendererId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ class BarRenderer<D>
|
|||||||
|
|
||||||
factory BarRenderer({BarRendererConfig config, String rendererId}) {
|
factory BarRenderer({BarRendererConfig config, String rendererId}) {
|
||||||
rendererId ??= 'bar';
|
rendererId ??= 'bar';
|
||||||
config ??= new BarRendererConfig();
|
config ??= BarRendererConfig();
|
||||||
return new BarRenderer.internal(config: config, rendererId: rendererId);
|
return BarRenderer.internal(config: config, rendererId: rendererId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This constructor is protected because it is used by child classes, which
|
/// This constructor is protected because it is used by child classes, which
|
||||||
@@ -99,20 +99,20 @@ class BarRenderer<D>
|
|||||||
Point<double> chartPosition;
|
Point<double> chartPosition;
|
||||||
|
|
||||||
if (renderingVertically) {
|
if (renderingVertically) {
|
||||||
chartPosition = new Point<double>(
|
chartPosition = Point<double>(
|
||||||
(bounds.left + (bounds.width / 2)).toDouble(), bounds.top.toDouble());
|
(bounds.left + (bounds.width / 2)).toDouble(), bounds.top.toDouble());
|
||||||
} else {
|
} else {
|
||||||
chartPosition = new Point<double>(
|
chartPosition = Point<double>(
|
||||||
isRtl ? bounds.left.toDouble() : bounds.right.toDouble(),
|
isRtl ? bounds.left.toDouble() : bounds.right.toDouble(),
|
||||||
(bounds.top + (bounds.height / 2)).toDouble());
|
(bounds.top + (bounds.height / 2)).toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DatumDetails.from(details, chartPosition: chartPosition);
|
return DatumDetails.from(details, chartPosition: chartPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BarRendererElement<D> getBaseDetails(dynamic datum, int index) {
|
BarRendererElement<D> getBaseDetails(dynamic datum, int index) {
|
||||||
return new BarRendererElement<D>();
|
return BarRendererElement<D>();
|
||||||
}
|
}
|
||||||
|
|
||||||
CornerStrategy get cornerStrategy {
|
CornerStrategy get cornerStrategy {
|
||||||
@@ -145,7 +145,7 @@ class BarRenderer<D>
|
|||||||
int numBarGroups,
|
int numBarGroups,
|
||||||
bool measureIsNull,
|
bool measureIsNull,
|
||||||
bool measureIsNegative}) {
|
bool measureIsNegative}) {
|
||||||
return new AnimatedBar<D>(
|
return AnimatedBar<D>(
|
||||||
key: key, datum: datum, series: series, domainValue: domainValue)
|
key: key, datum: datum, series: series, domainValue: domainValue)
|
||||||
..setNewTarget(makeBarRendererElement(
|
..setNewTarget(makeBarRendererElement(
|
||||||
color: color,
|
color: color,
|
||||||
@@ -192,7 +192,7 @@ class BarRenderer<D>
|
|||||||
int numBarGroups,
|
int numBarGroups,
|
||||||
bool measureIsNull,
|
bool measureIsNull,
|
||||||
bool measureIsNegative}) {
|
bool measureIsNegative}) {
|
||||||
return new BarRendererElement<D>()
|
return BarRendererElement<D>()
|
||||||
..color = color
|
..color = color
|
||||||
..dashPattern = dashPattern
|
..dashPattern = dashPattern
|
||||||
..fillColor = fillColor
|
..fillColor = fillColor
|
||||||
@@ -238,7 +238,7 @@ class BarRenderer<D>
|
|||||||
|
|
||||||
if (bar != unmodifiedBar) {
|
if (bar != unmodifiedBar) {
|
||||||
bounds = renderingVertically
|
bounds = renderingVertically
|
||||||
? new Rectangle<int>(
|
? Rectangle<int>(
|
||||||
bar.bounds.left,
|
bar.bounds.left,
|
||||||
max(
|
max(
|
||||||
0,
|
0,
|
||||||
@@ -247,7 +247,7 @@ class BarRenderer<D>
|
|||||||
bar.bounds.width,
|
bar.bounds.width,
|
||||||
max(0, bar.bounds.height - _stackedBarPadding),
|
max(0, bar.bounds.height - _stackedBarPadding),
|
||||||
)
|
)
|
||||||
: new Rectangle<int>(
|
: Rectangle<int>(
|
||||||
max(
|
max(
|
||||||
0,
|
0,
|
||||||
bar.bounds.left +
|
bar.bounds.left +
|
||||||
@@ -258,7 +258,7 @@ class BarRenderer<D>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bars.add(new CanvasRect(bounds,
|
bars.add(CanvasRect(bounds,
|
||||||
dashPattern: bar.dashPattern,
|
dashPattern: bar.dashPattern,
|
||||||
fill: bar.fillColor,
|
fill: bar.fillColor,
|
||||||
pattern: bar.fillPattern,
|
pattern: bar.fillPattern,
|
||||||
@@ -292,7 +292,7 @@ class BarRenderer<D>
|
|||||||
roundBottomRight = renderingVertically || isRtl ? false : true;
|
roundBottomRight = renderingVertically || isRtl ? false : true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final barStack = new CanvasBarStack(
|
final barStack = CanvasBarStack(
|
||||||
bars,
|
bars,
|
||||||
radius: cornerStrategy.getRadius(maxBarWidth),
|
radius: cornerStrategy.getRadius(maxBarWidth),
|
||||||
stackedBarPadding: _stackedBarPadding,
|
stackedBarPadding: _stackedBarPadding,
|
||||||
@@ -370,7 +370,7 @@ class BarRenderer<D>
|
|||||||
final width = right - left;
|
final width = right - left;
|
||||||
final height = bottom - top;
|
final height = bottom - top;
|
||||||
|
|
||||||
return new Rectangle(left, top, width, height);
|
return Rectangle(left, top, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a set of bounds that describe a bar.
|
/// Generates a set of bounds that describe a bar.
|
||||||
@@ -442,11 +442,11 @@ class BarRenderer<D>
|
|||||||
Rectangle<int> bounds;
|
Rectangle<int> bounds;
|
||||||
if (this.renderingVertically) {
|
if (this.renderingVertically) {
|
||||||
// Rectangle clamps to zero width/height
|
// Rectangle clamps to zero width/height
|
||||||
bounds = new Rectangle<int>(domainStart, measureEnd,
|
bounds = Rectangle<int>(domainStart, measureEnd, domainEnd - domainStart,
|
||||||
domainEnd - domainStart, measureStart - measureEnd);
|
measureStart - measureEnd);
|
||||||
} else {
|
} else {
|
||||||
// Rectangle clamps to zero width/height
|
// Rectangle clamps to zero width/height
|
||||||
bounds = new Rectangle<int>(min(measureStart, measureEnd), domainStart,
|
bounds = Rectangle<int>(min(measureStart, measureEnd), domainStart,
|
||||||
(measureEnd - measureStart).abs(), domainEnd - domainStart);
|
(measureEnd - measureStart).abs(), domainEnd - domainStart);
|
||||||
}
|
}
|
||||||
return bounds;
|
return bounds;
|
||||||
@@ -511,8 +511,8 @@ class BarRendererElement<D> extends BaseBarRendererElement
|
|||||||
var left = ((targetBounds.left - previousBounds.left) * animationPercent) +
|
var left = ((targetBounds.left - previousBounds.left) * animationPercent) +
|
||||||
previousBounds.left;
|
previousBounds.left;
|
||||||
|
|
||||||
bounds = new Rectangle<int>(left.round(), top.round(),
|
bounds = Rectangle<int>(left.round(), top.round(), (right - left).round(),
|
||||||
(right - left).round(), (bottom - top).round());
|
(bottom - top).round());
|
||||||
|
|
||||||
roundPx = localTarget.roundPx;
|
roundPx = localTarget.roundPx;
|
||||||
|
|
||||||
@@ -533,7 +533,7 @@ class AnimatedBar<D> extends BaseAnimatedBar<D, BarRendererElement<D>> {
|
|||||||
final BarRendererElement localTarget = target;
|
final BarRendererElement localTarget = target;
|
||||||
|
|
||||||
// TODO: Animate out bars in the middle of a stack.
|
// TODO: Animate out bars in the middle of a stack.
|
||||||
localTarget.bounds = new Rectangle<int>(
|
localTarget.bounds = Rectangle<int>(
|
||||||
localTarget.bounds.left + (localTarget.bounds.width / 2).round(),
|
localTarget.bounds.left + (localTarget.bounds.width / 2).round(),
|
||||||
localTarget.measureAxisPosition.round(),
|
localTarget.measureAxisPosition.round(),
|
||||||
0,
|
0,
|
||||||
@@ -552,5 +552,5 @@ class AnimatedBar<D> extends BaseAnimatedBar<D, BarRendererElement<D>> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
BarRendererElement<D> clone(BarRendererElement bar) =>
|
BarRendererElement<D> clone(BarRendererElement bar) =>
|
||||||
new BarRendererElement<D>.clone(bar);
|
BarRendererElement<D>.clone(bar);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class BarRendererConfig<D> extends BaseBarRendererConfig<D> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
BarRenderer<D> build() {
|
BarRenderer<D> build() {
|
||||||
return new BarRenderer<D>(config: this, rendererId: customRendererId);
|
return BarRenderer<D>(config: this, rendererId: customRendererId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ class BarTargetLineRenderer<D> extends BaseBarRenderer<D,
|
|||||||
final _barGroupInnerPadding = 2;
|
final _barGroupInnerPadding = 2;
|
||||||
|
|
||||||
/// Standard color for all bar target lines.
|
/// Standard color for all bar target lines.
|
||||||
final _color = new Color(r: 0, g: 0, b: 0, a: 153);
|
final _color = Color(r: 0, g: 0, b: 0, a: 153);
|
||||||
|
|
||||||
factory BarTargetLineRenderer(
|
factory BarTargetLineRenderer(
|
||||||
{BarTargetLineRendererConfig<D> config,
|
{BarTargetLineRendererConfig<D> config,
|
||||||
String rendererId = 'barTargetLine'}) {
|
String rendererId = 'barTargetLine'}) {
|
||||||
config ??= new BarTargetLineRendererConfig<D>();
|
config ??= BarTargetLineRendererConfig<D>();
|
||||||
return new BarTargetLineRenderer._internal(
|
return BarTargetLineRenderer._internal(
|
||||||
config: config, rendererId: rendererId);
|
config: config, rendererId: rendererId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class BarTargetLineRenderer<D> extends BaseBarRenderer<D,
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void configureSeries(List<MutableSeries<D>> seriesList) {
|
void configureSeries(List<MutableSeries<D>> seriesList) {
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
series.colorFn ??= (_) => _color;
|
series.colorFn ??= (_) => _color;
|
||||||
series.fillColorFn ??= (_) => _color;
|
series.fillColorFn ??= (_) => _color;
|
||||||
});
|
});
|
||||||
@@ -97,21 +97,21 @@ class BarTargetLineRenderer<D> extends BaseBarRenderer<D,
|
|||||||
Point<double> chartPosition;
|
Point<double> chartPosition;
|
||||||
|
|
||||||
if (renderingVertically) {
|
if (renderingVertically) {
|
||||||
chartPosition = new Point<double>(
|
chartPosition = Point<double>(
|
||||||
(points[0].x + (points[1].x - points[0].x) / 2).toDouble(),
|
(points[0].x + (points[1].x - points[0].x) / 2).toDouble(),
|
||||||
points[0].y.toDouble());
|
points[0].y.toDouble());
|
||||||
} else {
|
} else {
|
||||||
chartPosition = new Point<double>(points[0].x.toDouble(),
|
chartPosition = Point<double>(points[0].x.toDouble(),
|
||||||
(points[0].y + (points[1].y - points[0].y) / 2).toDouble());
|
(points[0].y + (points[1].y - points[0].y) / 2).toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DatumDetails.from(details, chartPosition: chartPosition);
|
return DatumDetails.from(details, chartPosition: chartPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_BarTargetLineRendererElement getBaseDetails(dynamic datum, int index) {
|
_BarTargetLineRendererElement getBaseDetails(dynamic datum, int index) {
|
||||||
final BarTargetLineRendererConfig<D> localConfig = config;
|
final BarTargetLineRendererConfig<D> localConfig = config;
|
||||||
return new _BarTargetLineRendererElement()
|
return _BarTargetLineRendererElement()
|
||||||
..roundEndCaps = localConfig.roundEndCaps;
|
..roundEndCaps = localConfig.roundEndCaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ class BarTargetLineRenderer<D> extends BaseBarRenderer<D,
|
|||||||
double strokeWidthPx,
|
double strokeWidthPx,
|
||||||
bool measureIsNull,
|
bool measureIsNull,
|
||||||
bool measureIsNegative}) {
|
bool measureIsNegative}) {
|
||||||
return new _AnimatedBarTargetLine(
|
return _AnimatedBarTargetLine(
|
||||||
key: key, datum: datum, series: series, domainValue: domainValue)
|
key: key, datum: datum, series: series, domainValue: domainValue)
|
||||||
..setNewTarget(makeBarRendererElement(
|
..setNewTarget(makeBarRendererElement(
|
||||||
color: color,
|
color: color,
|
||||||
@@ -188,7 +188,7 @@ class BarTargetLineRenderer<D> extends BaseBarRenderer<D,
|
|||||||
int numBarGroups,
|
int numBarGroups,
|
||||||
bool measureIsNull,
|
bool measureIsNull,
|
||||||
bool measureIsNegative}) {
|
bool measureIsNegative}) {
|
||||||
return new _BarTargetLineRendererElement()
|
return _BarTargetLineRendererElement()
|
||||||
..color = color
|
..color = color
|
||||||
..dashPattern = dashPattern
|
..dashPattern = dashPattern
|
||||||
..fillColor = fillColor
|
..fillColor = fillColor
|
||||||
@@ -217,7 +217,7 @@ class BarTargetLineRenderer<D> extends BaseBarRenderer<D,
|
|||||||
double animationPercent,
|
double animationPercent,
|
||||||
Iterable<_BarTargetLineRendererElement> barElements,
|
Iterable<_BarTargetLineRendererElement> barElements,
|
||||||
) {
|
) {
|
||||||
barElements.forEach((_BarTargetLineRendererElement bar) {
|
barElements.forEach((bar) {
|
||||||
// TODO: Combine common line attributes into
|
// TODO: Combine common line attributes into
|
||||||
// GraphicsFactory.lineStyle or similar.
|
// GraphicsFactory.lineStyle or similar.
|
||||||
canvas.drawLine(
|
canvas.drawLine(
|
||||||
@@ -299,13 +299,13 @@ class BarTargetLineRenderer<D> extends BaseBarRenderer<D,
|
|||||||
List<Point<int>> points;
|
List<Point<int>> points;
|
||||||
if (renderingVertically) {
|
if (renderingVertically) {
|
||||||
points = [
|
points = [
|
||||||
new Point<int>(domainStart, measureStart),
|
Point<int>(domainStart, measureStart),
|
||||||
new Point<int>(domainEnd, measureStart)
|
Point<int>(domainEnd, measureStart)
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
points = [
|
points = [
|
||||||
new Point<int>(measureStart, domainStart),
|
Point<int>(measureStart, domainStart),
|
||||||
new Point<int>(measureStart, domainEnd)
|
Point<int>(measureStart, domainEnd)
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return points;
|
return points;
|
||||||
@@ -318,13 +318,13 @@ class BarTargetLineRenderer<D> extends BaseBarRenderer<D,
|
|||||||
int bottom;
|
int bottom;
|
||||||
int left;
|
int left;
|
||||||
int right;
|
int right;
|
||||||
points.forEach((Point<int> p) {
|
points.forEach((p) {
|
||||||
top = top != null ? min(top, p.y) : p.y;
|
top = top != null ? min(top, p.y) : p.y;
|
||||||
left = left != null ? min(left, p.x) : p.x;
|
left = left != null ? min(left, p.x) : p.x;
|
||||||
bottom = bottom != null ? max(bottom, p.y) : p.y;
|
bottom = bottom != null ? max(bottom, p.y) : p.y;
|
||||||
right = right != null ? max(right, p.x) : p.x;
|
right = right != null ? max(right, p.x) : p.x;
|
||||||
});
|
});
|
||||||
return new Rectangle<int>(left, top, right - left, bottom - top);
|
return Rectangle<int>(left, top, right - left, bottom - top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +336,7 @@ class _BarTargetLineRendererElement extends BaseBarRendererElement {
|
|||||||
|
|
||||||
_BarTargetLineRendererElement.clone(_BarTargetLineRendererElement other)
|
_BarTargetLineRendererElement.clone(_BarTargetLineRendererElement other)
|
||||||
: super.clone(other) {
|
: super.clone(other) {
|
||||||
points = new List<Point<int>>.from(other.points);
|
points = List<Point<int>>.from(other.points);
|
||||||
roundEndCaps = other.roundEndCaps;
|
roundEndCaps = other.roundEndCaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -362,7 +362,7 @@ class _BarTargetLineRendererElement extends BaseBarRendererElement {
|
|||||||
previousPoint = previousPoints[pointIndex];
|
previousPoint = previousPoints[pointIndex];
|
||||||
lastPoint = previousPoint;
|
lastPoint = previousPoint;
|
||||||
} else {
|
} else {
|
||||||
previousPoint = new Point<int>(targetPoint.x, lastPoint.y);
|
previousPoint = Point<int>(targetPoint.x, lastPoint.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
var x = ((targetPoint.x - previousPoint.x) * animationPercent) +
|
var x = ((targetPoint.x - previousPoint.x) * animationPercent) +
|
||||||
@@ -372,9 +372,9 @@ class _BarTargetLineRendererElement extends BaseBarRendererElement {
|
|||||||
previousPoint.y;
|
previousPoint.y;
|
||||||
|
|
||||||
if (points.length - 1 >= pointIndex) {
|
if (points.length - 1 >= pointIndex) {
|
||||||
points[pointIndex] = new Point<int>(x.round(), y.round());
|
points[pointIndex] = Point<int>(x.round(), y.round());
|
||||||
} else {
|
} else {
|
||||||
points.add(new Point<int>(x.round(), y.round()));
|
points.add(Point<int>(x.round(), y.round()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,13 +410,13 @@ class _AnimatedBarTargetLine<D>
|
|||||||
for (var index = 0; index < localTarget.points.length; index++) {
|
for (var index = 0; index < localTarget.points.length; index++) {
|
||||||
final targetPoint = localTarget.points[index];
|
final targetPoint = localTarget.points[index];
|
||||||
|
|
||||||
newPoints.add(new Point<int>(
|
newPoints.add(
|
||||||
targetPoint.x, localTarget.measureAxisPosition.round()));
|
Point<int>(targetPoint.x, localTarget.measureAxisPosition.round()));
|
||||||
}
|
}
|
||||||
localTarget.points = newPoints;
|
localTarget.points = newPoints;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
_BarTargetLineRendererElement clone(_BarTargetLineRendererElement bar) =>
|
_BarTargetLineRendererElement clone(_BarTargetLineRendererElement bar) =>
|
||||||
new _BarTargetLineRendererElement.clone(bar);
|
_BarTargetLineRendererElement.clone(bar);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,14 +57,13 @@ class BarTargetLineRendererConfig<D> extends BaseBarRendererConfig<D> {
|
|||||||
layoutPaintOrder: layoutPaintOrder,
|
layoutPaintOrder: layoutPaintOrder,
|
||||||
minBarLengthPx: minBarLengthPx,
|
minBarLengthPx: minBarLengthPx,
|
||||||
strokeWidthPx: strokeWidthPx,
|
strokeWidthPx: strokeWidthPx,
|
||||||
symbolRenderer: symbolRenderer ?? new LineSymbolRenderer(),
|
symbolRenderer: symbolRenderer ?? LineSymbolRenderer(),
|
||||||
weightPattern: weightPattern,
|
weightPattern: weightPattern,
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BarTargetLineRenderer<D> build() {
|
BarTargetLineRenderer<D> build() {
|
||||||
return new BarTargetLineRenderer<D>(
|
return BarTargetLineRenderer<D>(config: this, rendererId: customRendererId);
|
||||||
config: this, rendererId: customRendererId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -34,20 +34,19 @@ import 'base_bar_renderer_config.dart' show BaseBarRendererConfig;
|
|||||||
import 'base_bar_renderer_element.dart'
|
import 'base_bar_renderer_element.dart'
|
||||||
show BaseAnimatedBar, BaseBarRendererElement;
|
show BaseAnimatedBar, BaseBarRendererElement;
|
||||||
|
|
||||||
const barGroupIndexKey = const AttributeKey<int>('BarRenderer.barGroupIndex');
|
const barGroupIndexKey = AttributeKey<int>('BarRenderer.barGroupIndex');
|
||||||
|
|
||||||
const barGroupCountKey = const AttributeKey<int>('BarRenderer.barGroupCount');
|
const barGroupCountKey = AttributeKey<int>('BarRenderer.barGroupCount');
|
||||||
|
|
||||||
const barGroupWeightKey =
|
const barGroupWeightKey = AttributeKey<double>('BarRenderer.barGroupWeight');
|
||||||
const AttributeKey<double>('BarRenderer.barGroupWeight');
|
|
||||||
|
|
||||||
const previousBarGroupWeightKey =
|
const previousBarGroupWeightKey =
|
||||||
const AttributeKey<double>('BarRenderer.previousBarGroupWeight');
|
AttributeKey<double>('BarRenderer.previousBarGroupWeight');
|
||||||
|
|
||||||
const stackKeyKey = const AttributeKey<String>('BarRenderer.stackKey');
|
const stackKeyKey = AttributeKey<String>('BarRenderer.stackKey');
|
||||||
|
|
||||||
const barElementsKey =
|
const barElementsKey =
|
||||||
const AttributeKey<List<BaseBarRendererElement>>('BarRenderer.elements');
|
AttributeKey<List<BaseBarRendererElement>>('BarRenderer.elements');
|
||||||
|
|
||||||
/// Base class for bar renderers that implements common stacking and grouping
|
/// Base class for bar renderers that implements common stacking and grouping
|
||||||
/// logic.
|
/// logic.
|
||||||
@@ -85,7 +84,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
/// as the data was given to the chart. For the case where both grouping and
|
/// as the data was given to the chart. For the case where both grouping and
|
||||||
/// stacking are disabled, this means that bars for data later in the series
|
/// stacking are disabled, this means that bars for data later in the series
|
||||||
/// will be drawn "on top of" bars earlier in the series.
|
/// will be drawn "on top of" bars earlier in the series.
|
||||||
final _barStackMap = new LinkedHashMap<String, List<B>>();
|
final _barStackMap = LinkedHashMap<String, List<B>>();
|
||||||
|
|
||||||
// Store a list of bar stacks that exist in the series data.
|
// Store a list of bar stacks that exist in the series data.
|
||||||
//
|
//
|
||||||
@@ -95,7 +94,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
final _currentKeys = <String>[];
|
final _currentKeys = <String>[];
|
||||||
|
|
||||||
/// Stores a list of stack keys for each group key.
|
/// Stores a list of stack keys for each group key.
|
||||||
final _currentGroupsStackKeys = new LinkedHashMap<D, Set<String>>();
|
final _currentGroupsStackKeys = LinkedHashMap<D, Set<String>>();
|
||||||
|
|
||||||
/// Optimization for getNearest to avoid scanning all data if possible.
|
/// Optimization for getNearest to avoid scanning all data if possible.
|
||||||
ImmutableAxis<D> _prevDomainAxis;
|
ImmutableAxis<D> _prevDomainAxis;
|
||||||
@@ -105,8 +104,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
: super(
|
: super(
|
||||||
rendererId: rendererId,
|
rendererId: rendererId,
|
||||||
layoutPaintOrder: layoutPaintOrder,
|
layoutPaintOrder: layoutPaintOrder,
|
||||||
symbolRenderer:
|
symbolRenderer: config?.symbolRenderer ?? RoundedRectSymbolRenderer(),
|
||||||
config?.symbolRenderer ?? new RoundedRectSymbolRenderer(),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -126,7 +124,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
|
|
||||||
final orderedSeriesList = getOrderedSeriesList(seriesList);
|
final orderedSeriesList = getOrderedSeriesList(seriesList);
|
||||||
|
|
||||||
orderedSeriesList.forEach((MutableSeries<D> series) {
|
orderedSeriesList.forEach((series) {
|
||||||
var elements = <BaseBarRendererElement>[];
|
var elements = <BaseBarRendererElement>[];
|
||||||
|
|
||||||
var domainFn = series.domainFn;
|
var domainFn = series.domainFn;
|
||||||
@@ -255,7 +253,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
// Compute bar group weights.
|
// Compute bar group weights.
|
||||||
final barWeights = _calculateBarWeights(numBarGroups);
|
final barWeights = _calculateBarWeights(numBarGroups);
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
series.setAttr(barGroupCountKey, numBarGroups);
|
series.setAttr(barGroupCountKey, numBarGroups);
|
||||||
|
|
||||||
if (barWeights.isNotEmpty) {
|
if (barWeights.isNotEmpty) {
|
||||||
@@ -290,7 +288,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
|
|
||||||
if (config.weightPattern != null) {
|
if (config.weightPattern != null) {
|
||||||
if (numBarGroups > config.weightPattern.length) {
|
if (numBarGroups > config.weightPattern.length) {
|
||||||
throw new ArgumentError('Number of series exceeds length of weight '
|
throw ArgumentError('Number of series exceeds length of weight '
|
||||||
'pattern ${config.weightPattern}');
|
'pattern ${config.weightPattern}');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -327,7 +325,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
// Given that charts can only have one domain axis, just grab it from the
|
// Given that charts can only have one domain axis, just grab it from the
|
||||||
// first series.
|
// first series.
|
||||||
final domainAxis = seriesList.first.getAttr(domainAxisKey);
|
final domainAxis = seriesList.first.getAttr(domainAxisKey);
|
||||||
domainAxis.setRangeBandConfig(new RangeBandConfig.styleAssignedPercent());
|
domainAxis.setRangeBandConfig(RangeBandConfig.styleAssignedPercent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +335,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
|
|
||||||
final orderedSeriesList = getOrderedSeriesList(seriesList);
|
final orderedSeriesList = getOrderedSeriesList(seriesList);
|
||||||
|
|
||||||
orderedSeriesList.forEach((final ImmutableSeries<D> series) {
|
orderedSeriesList.forEach((final series) {
|
||||||
final domainAxis = series.getAttr(domainAxisKey) as ImmutableAxis<D>;
|
final domainAxis = series.getAttr(domainAxisKey) as ImmutableAxis<D>;
|
||||||
final domainFn = series.domainFn;
|
final domainFn = series.domainFn;
|
||||||
final measureAxis = series.getAttr(measureAxisKey) as ImmutableAxis<num>;
|
final measureAxis = series.getAttr(measureAxisKey) as ImmutableAxis<num>;
|
||||||
@@ -384,7 +382,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
var barStackList = _barStackMap.putIfAbsent(barStackMapKey, () => []);
|
var barStackList = _barStackMap.putIfAbsent(barStackMapKey, () => []);
|
||||||
|
|
||||||
// If we already have an AnimatingBarfor that index, use it.
|
// If we already have an AnimatingBarfor that index, use it.
|
||||||
var animatingBar = barStackList.firstWhere((B bar) => bar.key == barKey,
|
var animatingBar = barStackList.firstWhere((bar) => bar.key == barKey,
|
||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
|
|
||||||
// If we don't have any existing bar element, create a new bar and have
|
// If we don't have any existing bar element, create a new bar and have
|
||||||
@@ -438,7 +436,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
// Store off stack keys for each bar group to help getNearest identify
|
// Store off stack keys for each bar group to help getNearest identify
|
||||||
// groups of stacks.
|
// groups of stacks.
|
||||||
_currentGroupsStackKeys
|
_currentGroupsStackKeys
|
||||||
.putIfAbsent(domainValue, () => new Set<String>())
|
.putIfAbsent(domainValue, () => <String>{})
|
||||||
.add(barStackMapKey);
|
.add(barStackMapKey);
|
||||||
|
|
||||||
// Get the barElement we are going to setup.
|
// Get the barElement we are going to setup.
|
||||||
@@ -469,7 +467,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Animate out bars that don't exist anymore.
|
// Animate out bars that don't exist anymore.
|
||||||
_barStackMap.forEach((String key, List<B> barStackList) {
|
_barStackMap.forEach((key, barStackList) {
|
||||||
for (var barIndex = 0; barIndex < barStackList.length; barIndex++) {
|
for (var barIndex = 0; barIndex < barStackList.length; barIndex++) {
|
||||||
final bar = barStackList[barIndex];
|
final bar = barStackList[barIndex];
|
||||||
if (_currentKeys.contains(bar.key) != true) {
|
if (_currentKeys.contains(bar.key) != true) {
|
||||||
@@ -541,11 +539,11 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
void paint(ChartCanvas canvas, double animationPercent) {
|
void paint(ChartCanvas canvas, double animationPercent) {
|
||||||
// Clean up the bars that no longer exist.
|
// Clean up the bars that no longer exist.
|
||||||
if (animationPercent == 1.0) {
|
if (animationPercent == 1.0) {
|
||||||
final keysToRemove = new HashSet<String>();
|
final keysToRemove = HashSet<String>();
|
||||||
|
|
||||||
_barStackMap.forEach((String key, List<B> barStackList) {
|
_barStackMap.forEach((key, barStackList) {
|
||||||
barStackList.retainWhere(
|
barStackList.retainWhere(
|
||||||
(B bar) => !bar.animatingOut && !bar.targetBar.measureIsNull);
|
(bar) => !bar.animatingOut && !bar.targetBar.measureIsNull);
|
||||||
|
|
||||||
if (barStackList.isEmpty) {
|
if (barStackList.isEmpty) {
|
||||||
keysToRemove.add(key);
|
keysToRemove.add(key);
|
||||||
@@ -563,12 +561,12 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_barStackMap.forEach((String stackKey, List<B> barStack) {
|
_barStackMap.forEach((stackKey, barStack) {
|
||||||
// Turn this into a list so that the getCurrentBar isn't called more than
|
// Turn this into a list so that the getCurrentBar isn't called more than
|
||||||
// once for each animationPercent if the barElements are iterated more
|
// once for each animationPercent if the barElements are iterated more
|
||||||
// than once.
|
// than once.
|
||||||
final barElements = barStack
|
final barElements = barStack
|
||||||
.map((B animatingBar) => animatingBar.getCurrentBar(animationPercent))
|
.map((animatingBar) => animatingBar.getCurrentBar(animationPercent))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
if (barElements.isNotEmpty) {
|
if (barElements.isNotEmpty) {
|
||||||
@@ -663,7 +661,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
? _currentGroupsStackKeys[domainValue]
|
? _currentGroupsStackKeys[domainValue]
|
||||||
: _currentGroupsStackKeys.values
|
: _currentGroupsStackKeys.values
|
||||||
.reduce((allKeys, keys) => allKeys..addAll(keys));
|
.reduce((allKeys, keys) => allKeys..addAll(keys));
|
||||||
stackKeys?.forEach((String stackKey) {
|
stackKeys?.forEach((stackKey) {
|
||||||
if (where != null) {
|
if (where != null) {
|
||||||
matchingSegments.addAll(_barStackMap[stackKey].where(where));
|
matchingSegments.addAll(_barStackMap[stackKey].where(where));
|
||||||
} else {
|
} else {
|
||||||
@@ -678,23 +676,21 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
// we can't use the optimized comparison for [OrdinalAxis].
|
// we can't use the optimized comparison for [OrdinalAxis].
|
||||||
List<DatumDetails<D>> _getVerticalDetailsForDomainValue(
|
List<DatumDetails<D>> _getVerticalDetailsForDomainValue(
|
||||||
D domainValue, Point<double> chartPoint) {
|
D domainValue, Point<double> chartPoint) {
|
||||||
return new List<DatumDetails<D>>.from(_getSegmentsForDomainValue(
|
return List<DatumDetails<D>>.from(_getSegmentsForDomainValue(domainValue,
|
||||||
domainValue,
|
where: (bar) => !bar.series.overlaySeries).map<DatumDetails<D>>((bar) {
|
||||||
where: (BaseAnimatedBar<D, R> bar) => !bar.series.overlaySeries)
|
|
||||||
.map<DatumDetails<D>>((BaseAnimatedBar<D, R> bar) {
|
|
||||||
final barBounds = getBoundsForBar(bar.currentBar);
|
final barBounds = getBoundsForBar(bar.currentBar);
|
||||||
final segmentDomainDistance =
|
final segmentDomainDistance =
|
||||||
_getDistance(chartPoint.x.round(), barBounds.left, barBounds.right);
|
_getDistance(chartPoint.x.round(), barBounds.left, barBounds.right);
|
||||||
final segmentMeasureDistance =
|
final segmentMeasureDistance =
|
||||||
_getDistance(chartPoint.y.round(), barBounds.top, barBounds.bottom);
|
_getDistance(chartPoint.y.round(), barBounds.top, barBounds.bottom);
|
||||||
|
|
||||||
final nearestPoint = new Point<double>(
|
final nearestPoint = Point<double>(
|
||||||
clamp(chartPoint.x, barBounds.left, barBounds.right).toDouble(),
|
clamp(chartPoint.x, barBounds.left, barBounds.right).toDouble(),
|
||||||
clamp(chartPoint.y, barBounds.top, barBounds.bottom).toDouble());
|
clamp(chartPoint.y, barBounds.top, barBounds.bottom).toDouble());
|
||||||
|
|
||||||
final relativeDistance = chartPoint.distanceTo(nearestPoint);
|
final relativeDistance = chartPoint.distanceTo(nearestPoint);
|
||||||
|
|
||||||
return new DatumDetails<D>(
|
return DatumDetails<D>(
|
||||||
series: bar.series,
|
series: bar.series,
|
||||||
datum: bar.datum,
|
datum: bar.datum,
|
||||||
domain: bar.domainValue,
|
domain: bar.domainValue,
|
||||||
@@ -707,17 +703,15 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
|
|
||||||
List<DatumDetails<D>> _getHorizontalDetailsForDomainValue(
|
List<DatumDetails<D>> _getHorizontalDetailsForDomainValue(
|
||||||
D domainValue, Point<double> chartPoint) {
|
D domainValue, Point<double> chartPoint) {
|
||||||
return new List<DatumDetails<D>>.from(_getSegmentsForDomainValue(
|
return List<DatumDetails<D>>.from(_getSegmentsForDomainValue(domainValue,
|
||||||
domainValue,
|
where: (bar) => !bar.series.overlaySeries).map((bar) {
|
||||||
where: (BaseAnimatedBar<D, R> bar) => !bar.series.overlaySeries)
|
|
||||||
.map((BaseAnimatedBar<D, R> bar) {
|
|
||||||
final barBounds = getBoundsForBar(bar.currentBar);
|
final barBounds = getBoundsForBar(bar.currentBar);
|
||||||
final segmentDomainDistance =
|
final segmentDomainDistance =
|
||||||
_getDistance(chartPoint.y.round(), barBounds.top, barBounds.bottom);
|
_getDistance(chartPoint.y.round(), barBounds.top, barBounds.bottom);
|
||||||
final segmentMeasureDistance =
|
final segmentMeasureDistance =
|
||||||
_getDistance(chartPoint.x.round(), barBounds.left, barBounds.right);
|
_getDistance(chartPoint.x.round(), barBounds.left, barBounds.right);
|
||||||
|
|
||||||
return new DatumDetails<D>(
|
return DatumDetails<D>(
|
||||||
series: bar.series,
|
series: bar.series,
|
||||||
datum: bar.datum,
|
datum: bar.datum,
|
||||||
domain: bar.domainValue,
|
domain: bar.domainValue,
|
||||||
@@ -748,7 +742,7 @@ abstract class BaseBarRenderer<D, R extends BaseBarRendererElement,
|
|||||||
List<S> seriesList) {
|
List<S> seriesList) {
|
||||||
return (renderingVertically && config.stacked)
|
return (renderingVertically && config.stacked)
|
||||||
? config.grouped
|
? config.grouped
|
||||||
? new _ReversedSeriesIterable(seriesList)
|
? _ReversedSeriesIterable(seriesList)
|
||||||
: seriesList.reversed
|
: seriesList.reversed
|
||||||
: seriesList;
|
: seriesList;
|
||||||
}
|
}
|
||||||
@@ -763,7 +757,7 @@ class _ReversedSeriesIterable<S extends ImmutableSeries> extends Iterable<S> {
|
|||||||
_ReversedSeriesIterable(this.seriesList);
|
_ReversedSeriesIterable(this.seriesList);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Iterator<S> get iterator => new _ReversedSeriesIterator(seriesList);
|
Iterator<S> get iterator => _ReversedSeriesIterator(seriesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Iterator that keeps reverse series order but keeps category order.
|
/// Iterator that keeps reverse series order but keeps category order.
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ abstract class BaseBarRendererConfig<D> extends LayoutViewConfig
|
|||||||
/// Not used for stacked bars.
|
/// Not used for stacked bars.
|
||||||
final List<int> weightPattern;
|
final List<int> weightPattern;
|
||||||
|
|
||||||
final rendererAttributes = new RendererAttributes();
|
final rendererAttributes = RendererAttributes();
|
||||||
|
|
||||||
BaseBarRendererConfig(
|
BaseBarRendererConfig(
|
||||||
{this.customRendererId,
|
{this.customRendererId,
|
||||||
@@ -95,7 +95,7 @@ abstract class BaseBarRendererConfig<D> extends LayoutViewConfig
|
|||||||
this.strokeWidthPx = 0.0,
|
this.strokeWidthPx = 0.0,
|
||||||
SymbolRenderer symbolRenderer,
|
SymbolRenderer symbolRenderer,
|
||||||
this.weightPattern})
|
this.weightPattern})
|
||||||
: this.symbolRenderer = symbolRenderer ?? new RoundedRectSymbolRenderer();
|
: this.symbolRenderer = symbolRenderer ?? RoundedRectSymbolRenderer();
|
||||||
|
|
||||||
/// Whether or not the bars should be organized into groups.
|
/// Whether or not the bars should be organized into groups.
|
||||||
bool get grouped =>
|
bool get grouped =>
|
||||||
@@ -112,10 +112,8 @@ abstract class BaseBarRendererConfig<D> extends LayoutViewConfig
|
|||||||
if (identical(this, other)) {
|
if (identical(this, other)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!(other is BaseBarRendererConfig)) {
|
return other is BaseBarRendererConfig &&
|
||||||
return false;
|
other.customRendererId == customRendererId &&
|
||||||
}
|
|
||||||
return other.customRendererId == customRendererId &&
|
|
||||||
other.dashPattern == dashPattern &&
|
other.dashPattern == dashPattern &&
|
||||||
other.fillPattern == fillPattern &&
|
other.fillPattern == fillPattern &&
|
||||||
other.groupingType == groupingType &&
|
other.groupingType == groupingType &&
|
||||||
@@ -123,7 +121,7 @@ abstract class BaseBarRendererConfig<D> extends LayoutViewConfig
|
|||||||
other.stackHorizontalSeparator == stackHorizontalSeparator &&
|
other.stackHorizontalSeparator == stackHorizontalSeparator &&
|
||||||
other.strokeWidthPx == strokeWidthPx &&
|
other.strokeWidthPx == strokeWidthPx &&
|
||||||
other.symbolRenderer == symbolRenderer &&
|
other.symbolRenderer == symbolRenderer &&
|
||||||
new ListEquality().equals(other.weightPattern, weightPattern);
|
ListEquality().equals(other.weightPattern, weightPattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get hashcode {
|
int get hashcode {
|
||||||
|
|||||||
@@ -35,12 +35,11 @@ abstract class BaseBarRendererElement {
|
|||||||
|
|
||||||
BaseBarRendererElement.clone(BaseBarRendererElement other) {
|
BaseBarRendererElement.clone(BaseBarRendererElement other) {
|
||||||
barStackIndex = other.barStackIndex;
|
barStackIndex = other.barStackIndex;
|
||||||
color =
|
color = other.color != null ? Color.fromOther(color: other.color) : null;
|
||||||
other.color != null ? new Color.fromOther(color: other.color) : null;
|
|
||||||
cumulativeTotal = other.cumulativeTotal;
|
cumulativeTotal = other.cumulativeTotal;
|
||||||
dashPattern = other.dashPattern;
|
dashPattern = other.dashPattern;
|
||||||
fillColor = other.fillColor != null
|
fillColor = other.fillColor != null
|
||||||
? new Color.fromOther(color: other.fillColor)
|
? Color.fromOther(color: other.fillColor)
|
||||||
: null;
|
: null;
|
||||||
fillPattern = other.fillPattern;
|
fillPattern = other.fillPattern;
|
||||||
measureAxisPosition = other.measureAxisPosition;
|
measureAxisPosition = other.measureAxisPosition;
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ import 'tick_formatter.dart'
|
|||||||
show TickFormatter, OrdinalTickFormatter, NumericTickFormatter;
|
show TickFormatter, OrdinalTickFormatter, NumericTickFormatter;
|
||||||
import 'tick_provider.dart' show TickProvider;
|
import 'tick_provider.dart' show TickProvider;
|
||||||
|
|
||||||
const measureAxisIdKey = const AttributeKey<String>('Axis.measureAxisId');
|
const measureAxisIdKey = AttributeKey<String>('Axis.measureAxisId');
|
||||||
const measureAxisKey = const AttributeKey<Axis>('Axis.measureAxis');
|
const measureAxisKey = AttributeKey<Axis>('Axis.measureAxis');
|
||||||
const domainAxisKey = const AttributeKey<Axis>('Axis.domainAxis');
|
const domainAxisKey = AttributeKey<Axis>('Axis.domainAxis');
|
||||||
|
|
||||||
/// Orientation of an Axis.
|
/// Orientation of an Axis.
|
||||||
enum AxisOrientation { top, right, bottom, left }
|
enum AxisOrientation { top, right, bottom, left }
|
||||||
@@ -89,14 +89,8 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
/// Previous [Scale] of this axis, used to calculate tick animation.
|
/// Previous [Scale] of this axis, used to calculate tick animation.
|
||||||
MutableScale<D> _previousScale;
|
MutableScale<D> _previousScale;
|
||||||
|
|
||||||
TickProvider<D> _tickProvider;
|
|
||||||
|
|
||||||
/// [TickProvider] for this axis.
|
/// [TickProvider] for this axis.
|
||||||
TickProvider<D> get tickProvider => _tickProvider;
|
TickProvider<D> tickProvider;
|
||||||
|
|
||||||
set tickProvider(TickProvider<D> tickProvider) {
|
|
||||||
_tickProvider = tickProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// [TickFormatter] for this axis.
|
/// [TickFormatter] for this axis.
|
||||||
TickFormatter<D> _tickFormatter;
|
TickFormatter<D> _tickFormatter;
|
||||||
@@ -122,9 +116,12 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
/// If the output range should be reversed.
|
/// If the output range should be reversed.
|
||||||
bool reverseOutputRange = false;
|
bool reverseOutputRange = false;
|
||||||
|
|
||||||
/// Whether or not the axis will configure the viewport to have "niced" ticks
|
/// Configures whether the viewport should be reset back to default values
|
||||||
/// around the domain values.
|
/// when the domain is reset.
|
||||||
bool _autoViewport = true;
|
///
|
||||||
|
/// This should generally be disabled when the viewport will be managed
|
||||||
|
/// externally, e.g. from pan and zoom behaviors.
|
||||||
|
bool autoViewport = true;
|
||||||
|
|
||||||
/// If the axis line should always be drawn.
|
/// If the axis line should always be drawn.
|
||||||
bool forceDrawAxisLine;
|
bool forceDrawAxisLine;
|
||||||
@@ -143,7 +140,7 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
|
|
||||||
Rectangle<int> _componentBounds;
|
Rectangle<int> _componentBounds;
|
||||||
Rectangle<int> _drawAreaBounds;
|
Rectangle<int> _drawAreaBounds;
|
||||||
GraphicsFactory _graphicsFactory;
|
GraphicsFactory graphicsFactory;
|
||||||
|
|
||||||
/// Order for chart layout painting.
|
/// Order for chart layout painting.
|
||||||
///
|
///
|
||||||
@@ -156,7 +153,7 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
TickFormatter<D> tickFormatter,
|
TickFormatter<D> tickFormatter,
|
||||||
MutableScale<D> scale})
|
MutableScale<D> scale})
|
||||||
: this._scale = scale,
|
: this._scale = scale,
|
||||||
this._tickProvider = tickProvider,
|
this.tickProvider = tickProvider,
|
||||||
this._tickFormatter = tickFormatter;
|
this._tickFormatter = tickFormatter;
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -172,17 +169,6 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
@override
|
@override
|
||||||
ScaleOutputExtent get range => _scale.range;
|
ScaleOutputExtent get range => _scale.range;
|
||||||
|
|
||||||
/// Configures whether the viewport should be reset back to default values
|
|
||||||
/// when the domain is reset.
|
|
||||||
///
|
|
||||||
/// This should generally be disabled when the viewport will be managed
|
|
||||||
/// externally, e.g. from pan and zoom behaviors.
|
|
||||||
set autoViewport(bool autoViewport) {
|
|
||||||
_autoViewport = autoViewport;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool get autoViewport => _autoViewport;
|
|
||||||
|
|
||||||
void setRangeBandConfig(RangeBandConfig rangeBandConfig) {
|
void setRangeBandConfig(RangeBandConfig rangeBandConfig) {
|
||||||
mutableScale.rangeBandConfig = rangeBandConfig;
|
mutableScale.rangeBandConfig = rangeBandConfig;
|
||||||
}
|
}
|
||||||
@@ -222,7 +208,7 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
_scale.resetDomain();
|
_scale.resetDomain();
|
||||||
reverseOutputRange = false;
|
reverseOutputRange = false;
|
||||||
|
|
||||||
if (_autoViewport) {
|
if (autoViewport) {
|
||||||
_scale.resetViewportSettings();
|
_scale.resetViewportSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +229,7 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setOutputRange(int start, int end) {
|
void setOutputRange(int start, int end) {
|
||||||
_scale.range = new ScaleOutputExtent(start, end);
|
_scale.range = ScaleOutputExtent(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Request update ticks from tick provider and update the painted ticks.
|
/// Request update ticks from tick provider and update the painted ticks.
|
||||||
@@ -268,7 +254,7 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
formatterValueCache: _formatterValueCache,
|
formatterValueCache: _formatterValueCache,
|
||||||
tickDrawStrategy: tickDrawStrategy,
|
tickDrawStrategy: tickDrawStrategy,
|
||||||
orientation: axisOrientation,
|
orientation: axisOrientation,
|
||||||
viewportExtensionEnabled: _autoViewport);
|
viewportExtensionEnabled: autoViewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Updates the ticks that are actually used for drawing.
|
/// Updates the ticks that are actually used for drawing.
|
||||||
@@ -277,7 +263,7 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final providedTicks = new List.from(_providedTicks ?? []);
|
final providedTicks = List.from(_providedTicks ?? []);
|
||||||
|
|
||||||
for (AxisTicks<D> animatedTick in _axisTicks) {
|
for (AxisTicks<D> animatedTick in _axisTicks) {
|
||||||
final tick = providedTicks?.firstWhere(
|
final tick = providedTicks?.firstWhere(
|
||||||
@@ -302,7 +288,7 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
|
|
||||||
// Add new ticks
|
// Add new ticks
|
||||||
providedTicks?.forEach((tick) {
|
providedTicks?.forEach((tick) {
|
||||||
final animatedTick = new AxisTicks<D>(tick);
|
final animatedTick = AxisTicks<D>(tick);
|
||||||
if (_previousScale != null) {
|
if (_previousScale != null) {
|
||||||
animatedTick.animateInFrom(_previousScale[tick.value].toDouble());
|
animatedTick.animateInFrom(_previousScale[tick.value].toDouble());
|
||||||
}
|
}
|
||||||
@@ -378,15 +364,7 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
//
|
//
|
||||||
|
|
||||||
@override
|
@override
|
||||||
GraphicsFactory get graphicsFactory => _graphicsFactory;
|
LayoutViewConfig get layoutConfig => LayoutViewConfig(
|
||||||
|
|
||||||
@override
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
|
||||||
_graphicsFactory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
LayoutViewConfig get layoutConfig => new LayoutViewConfig(
|
|
||||||
paintOrder: layoutPaintOrder,
|
paintOrder: layoutPaintOrder,
|
||||||
position: _layoutPosition,
|
position: _layoutPosition,
|
||||||
positionOrder: LayoutViewPositionOrder.axis);
|
positionOrder: LayoutViewPositionOrder.axis);
|
||||||
@@ -457,8 +435,8 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
isVertical ? _componentBounds.top : _componentBounds.right;
|
isVertical ? _componentBounds.top : _componentBounds.right;
|
||||||
|
|
||||||
final outputRange = reverseOutputRange
|
final outputRange = reverseOutputRange
|
||||||
? new ScaleOutputExtent(outputEnd, outputStart)
|
? ScaleOutputExtent(outputEnd, outputStart)
|
||||||
: new ScaleOutputExtent(outputStart, outputEnd);
|
: ScaleOutputExtent(outputStart, outputEnd);
|
||||||
|
|
||||||
if (_scale.range != outputRange) {
|
if (_scale.range != outputRange) {
|
||||||
_scale.range = outputRange;
|
_scale.range = outputRange;
|
||||||
@@ -510,9 +488,9 @@ abstract class Axis<D> extends ImmutableAxis<D> implements LayoutView {
|
|||||||
class NumericAxis extends Axis<num> {
|
class NumericAxis extends Axis<num> {
|
||||||
NumericAxis({TickProvider<num> tickProvider})
|
NumericAxis({TickProvider<num> tickProvider})
|
||||||
: super(
|
: super(
|
||||||
tickProvider: tickProvider ?? new NumericTickProvider(),
|
tickProvider: tickProvider ?? NumericTickProvider(),
|
||||||
tickFormatter: new NumericTickFormatter(),
|
tickFormatter: NumericTickFormatter(),
|
||||||
scale: new LinearScale(),
|
scale: LinearScale(),
|
||||||
);
|
);
|
||||||
|
|
||||||
void setScaleViewport(NumericExtents viewport) {
|
void setScaleViewport(NumericExtents viewport) {
|
||||||
@@ -529,7 +507,7 @@ class OrdinalAxis extends Axis<String> {
|
|||||||
}) : super(
|
}) : super(
|
||||||
tickProvider: tickProvider ?? const OrdinalTickProvider(),
|
tickProvider: tickProvider ?? const OrdinalTickProvider(),
|
||||||
tickFormatter: tickFormatter ?? const OrdinalTickFormatter(),
|
tickFormatter: tickFormatter ?? const OrdinalTickFormatter(),
|
||||||
scale: new SimpleOrdinalScale(),
|
scale: SimpleOrdinalScale(),
|
||||||
);
|
);
|
||||||
|
|
||||||
void setScaleViewport(OrdinalViewport viewport) {
|
void setScaleViewport(OrdinalViewport viewport) {
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ abstract class BaseTickDrawStrategy<D> implements TickDrawStrategy<D> {
|
|||||||
CollisionReport collides(List<Tick<D>> ticks, AxisOrientation orientation) {
|
CollisionReport collides(List<Tick<D>> ticks, AxisOrientation orientation) {
|
||||||
// If there are no ticks, they do not collide.
|
// If there are no ticks, they do not collide.
|
||||||
if (ticks == null) {
|
if (ticks == null) {
|
||||||
return new CollisionReport(
|
return CollisionReport(
|
||||||
ticksCollide: false, ticks: ticks, alternateTicksUsed: false);
|
ticksCollide: false, ticks: ticks, alternateTicksUsed: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,12 +228,12 @@ abstract class BaseTickDrawStrategy<D> implements TickDrawStrategy<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (collides) {
|
if (collides) {
|
||||||
return new CollisionReport(
|
return CollisionReport(
|
||||||
ticksCollide: true, ticks: ticks, alternateTicksUsed: false);
|
ticksCollide: true, ticks: ticks, alternateTicksUsed: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new CollisionReport(
|
return CollisionReport(
|
||||||
ticksCollide: false, ticks: ticks, alternateTicksUsed: false);
|
ticksCollide: false, ticks: ticks, alternateTicksUsed: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,13 +245,13 @@ abstract class BaseTickDrawStrategy<D> implements TickDrawStrategy<D> {
|
|||||||
final maxHorizontalSliceWidth = ticks
|
final maxHorizontalSliceWidth = ticks
|
||||||
.fold(
|
.fold(
|
||||||
0.0,
|
0.0,
|
||||||
(double prevMax, tick) => max(
|
(prevMax, tick) => max<double>(
|
||||||
prevMax,
|
prevMax,
|
||||||
tick.textElement.measurement.horizontalSliceWidth +
|
tick.textElement.measurement.horizontalSliceWidth +
|
||||||
labelOffsetFromAxisPx))
|
labelOffsetFromAxisPx))
|
||||||
.round();
|
.round();
|
||||||
|
|
||||||
return new ViewMeasuredSizes(
|
return ViewMeasuredSizes(
|
||||||
preferredWidth: maxHorizontalSliceWidth, preferredHeight: maxHeight);
|
preferredWidth: maxHorizontalSliceWidth, preferredHeight: maxHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,11 +261,11 @@ abstract class BaseTickDrawStrategy<D> implements TickDrawStrategy<D> {
|
|||||||
final maxVerticalSliceWidth = ticks
|
final maxVerticalSliceWidth = ticks
|
||||||
.fold(
|
.fold(
|
||||||
0.0,
|
0.0,
|
||||||
(double prevMax, tick) =>
|
(prevMax, tick) => max<double>(
|
||||||
max(prevMax, tick.textElement.measurement.verticalSliceWidth))
|
prevMax, tick.textElement.measurement.verticalSliceWidth))
|
||||||
.round();
|
.round();
|
||||||
|
|
||||||
return new ViewMeasuredSizes(
|
return ViewMeasuredSizes(
|
||||||
preferredWidth: maxWidth,
|
preferredWidth: maxWidth,
|
||||||
preferredHeight: maxVerticalSliceWidth + labelOffsetFromAxisPx);
|
preferredHeight: maxVerticalSliceWidth + labelOffsetFromAxisPx);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class GridlineRendererSpec<D> extends SmallTickRendererSpec<D> {
|
|||||||
@override
|
@override
|
||||||
TickDrawStrategy<D> createDrawStrategy(
|
TickDrawStrategy<D> createDrawStrategy(
|
||||||
ChartContext context, GraphicsFactory graphicsFactory) =>
|
ChartContext context, GraphicsFactory graphicsFactory) =>
|
||||||
new GridlineTickDrawStrategy<D>(context, graphicsFactory,
|
GridlineTickDrawStrategy<D>(context, graphicsFactory,
|
||||||
tickLengthPx: tickLengthPx,
|
tickLengthPx: tickLengthPx,
|
||||||
lineStyleSpec: lineStyle,
|
lineStyleSpec: lineStyle,
|
||||||
labelStyleSpec: labelStyle,
|
labelStyleSpec: labelStyle,
|
||||||
@@ -125,34 +125,34 @@ class GridlineTickDrawStrategy<D> extends BaseTickDrawStrategy<D> {
|
|||||||
switch (orientation) {
|
switch (orientation) {
|
||||||
case AxisOrientation.top:
|
case AxisOrientation.top:
|
||||||
final x = tick.locationPx;
|
final x = tick.locationPx;
|
||||||
lineStart = new Point(x, axisBounds.bottom - tickLength);
|
lineStart = Point(x, axisBounds.bottom - tickLength);
|
||||||
lineEnd = new Point(x, drawAreaBounds.bottom);
|
lineEnd = Point(x, drawAreaBounds.bottom);
|
||||||
break;
|
break;
|
||||||
case AxisOrientation.bottom:
|
case AxisOrientation.bottom:
|
||||||
final x = tick.locationPx;
|
final x = tick.locationPx;
|
||||||
lineStart = new Point(x, drawAreaBounds.top + tickLength);
|
lineStart = Point(x, drawAreaBounds.top + tickLength);
|
||||||
lineEnd = new Point(x, axisBounds.top);
|
lineEnd = Point(x, axisBounds.top);
|
||||||
break;
|
break;
|
||||||
case AxisOrientation.right:
|
case AxisOrientation.right:
|
||||||
final y = tick.locationPx;
|
final y = tick.locationPx;
|
||||||
if (tickLabelAnchor == TickLabelAnchor.after ||
|
if (tickLabelAnchor == TickLabelAnchor.after ||
|
||||||
tickLabelAnchor == TickLabelAnchor.before) {
|
tickLabelAnchor == TickLabelAnchor.before) {
|
||||||
lineStart = new Point(axisBounds.right, y);
|
lineStart = Point(axisBounds.right, y);
|
||||||
} else {
|
} else {
|
||||||
lineStart = new Point(axisBounds.left + tickLength, y);
|
lineStart = Point(axisBounds.left + tickLength, y);
|
||||||
}
|
}
|
||||||
lineEnd = new Point(drawAreaBounds.left, y);
|
lineEnd = Point(drawAreaBounds.left, y);
|
||||||
break;
|
break;
|
||||||
case AxisOrientation.left:
|
case AxisOrientation.left:
|
||||||
final y = tick.locationPx;
|
final y = tick.locationPx;
|
||||||
|
|
||||||
if (tickLabelAnchor == TickLabelAnchor.after ||
|
if (tickLabelAnchor == TickLabelAnchor.after ||
|
||||||
tickLabelAnchor == TickLabelAnchor.before) {
|
tickLabelAnchor == TickLabelAnchor.before) {
|
||||||
lineStart = new Point(axisBounds.left, y);
|
lineStart = Point(axisBounds.left, y);
|
||||||
} else {
|
} else {
|
||||||
lineStart = new Point(axisBounds.right - tickLength, y);
|
lineStart = Point(axisBounds.right - tickLength, y);
|
||||||
}
|
}
|
||||||
lineEnd = new Point(drawAreaBounds.right, y);
|
lineEnd = Point(drawAreaBounds.right, y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class NoneRenderSpec<D> extends RenderSpec<D> {
|
|||||||
@override
|
@override
|
||||||
TickDrawStrategy<D> createDrawStrategy(
|
TickDrawStrategy<D> createDrawStrategy(
|
||||||
ChartContext context, GraphicsFactory graphicFactory) =>
|
ChartContext context, GraphicsFactory graphicFactory) =>
|
||||||
new NoneDrawStrategy<D>(context, graphicFactory,
|
NoneDrawStrategy<D>(context, graphicFactory,
|
||||||
axisLineStyleSpec: axisLineStyle);
|
axisLineStyleSpec: axisLineStyle);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -68,7 +68,7 @@ class NoneDrawStrategy<D> implements TickDrawStrategy<D> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
CollisionReport collides(List<Tick> ticks, AxisOrientation orientation) =>
|
CollisionReport collides(List<Tick> ticks, AxisOrientation orientation) =>
|
||||||
new CollisionReport(ticksCollide: false, ticks: ticks);
|
CollisionReport(ticksCollide: false, ticks: ticks);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void decorateTicks(List<Tick> ticks) {
|
void decorateTicks(List<Tick> ticks) {
|
||||||
@@ -125,12 +125,12 @@ class NoneDrawStrategy<D> implements TickDrawStrategy<D> {
|
|||||||
@override
|
@override
|
||||||
ViewMeasuredSizes measureHorizontallyDrawnTicks(
|
ViewMeasuredSizes measureHorizontallyDrawnTicks(
|
||||||
List<Tick> ticks, int maxWidth, int maxHeight) {
|
List<Tick> ticks, int maxWidth, int maxHeight) {
|
||||||
return new ViewMeasuredSizes(preferredWidth: 0, preferredHeight: 0);
|
return ViewMeasuredSizes(preferredWidth: 0, preferredHeight: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ViewMeasuredSizes measureVerticallyDrawnTicks(
|
ViewMeasuredSizes measureVerticallyDrawnTicks(
|
||||||
List<Tick> ticks, int maxWidth, int maxHeight) {
|
List<Tick> ticks, int maxWidth, int maxHeight) {
|
||||||
return new ViewMeasuredSizes(preferredWidth: 0, preferredHeight: 0);
|
return ViewMeasuredSizes(preferredWidth: 0, preferredHeight: 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class SmallTickRendererSpec<D> extends BaseRenderSpec<D> {
|
|||||||
@override
|
@override
|
||||||
TickDrawStrategy<D> createDrawStrategy(
|
TickDrawStrategy<D> createDrawStrategy(
|
||||||
ChartContext context, GraphicsFactory graphicsFactory) =>
|
ChartContext context, GraphicsFactory graphicsFactory) =>
|
||||||
new SmallTickDrawStrategy<D>(context, graphicsFactory,
|
SmallTickDrawStrategy<D>(context, graphicsFactory,
|
||||||
tickLengthPx: tickLengthPx,
|
tickLengthPx: tickLengthPx,
|
||||||
lineStyleSpec: lineStyle,
|
lineStyleSpec: lineStyle,
|
||||||
labelStyleSpec: labelStyle,
|
labelStyleSpec: labelStyle,
|
||||||
@@ -128,25 +128,25 @@ class SmallTickDrawStrategy<D> extends BaseTickDrawStrategy<D> {
|
|||||||
switch (orientation) {
|
switch (orientation) {
|
||||||
case AxisOrientation.top:
|
case AxisOrientation.top:
|
||||||
double x = tick.locationPx;
|
double x = tick.locationPx;
|
||||||
tickStart = new Point(x, axisBounds.bottom - tickLength);
|
tickStart = Point(x, axisBounds.bottom - tickLength);
|
||||||
tickEnd = new Point(x, axisBounds.bottom);
|
tickEnd = Point(x, axisBounds.bottom);
|
||||||
break;
|
break;
|
||||||
case AxisOrientation.bottom:
|
case AxisOrientation.bottom:
|
||||||
double x = tick.locationPx;
|
double x = tick.locationPx;
|
||||||
tickStart = new Point(x, axisBounds.top);
|
tickStart = Point(x, axisBounds.top);
|
||||||
tickEnd = new Point(x, axisBounds.top + tickLength);
|
tickEnd = Point(x, axisBounds.top + tickLength);
|
||||||
break;
|
break;
|
||||||
case AxisOrientation.right:
|
case AxisOrientation.right:
|
||||||
double y = tick.locationPx;
|
double y = tick.locationPx;
|
||||||
|
|
||||||
tickStart = new Point(axisBounds.left, y);
|
tickStart = Point(axisBounds.left, y);
|
||||||
tickEnd = new Point(axisBounds.left + tickLength, y);
|
tickEnd = Point(axisBounds.left + tickLength, y);
|
||||||
break;
|
break;
|
||||||
case AxisOrientation.left:
|
case AxisOrientation.left:
|
||||||
double y = tick.locationPx;
|
double y = tick.locationPx;
|
||||||
|
|
||||||
tickStart = new Point(axisBounds.right - tickLength, y);
|
tickStart = Point(axisBounds.right - tickLength, y);
|
||||||
tickEnd = new Point(axisBounds.right, y);
|
tickEnd = Point(axisBounds.right, y);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -54,12 +54,12 @@ class EndPointsTickProvider<D> extends BaseTickProvider<D> {
|
|||||||
final labels = formatter.format([start, end], formatterValueCache,
|
final labels = formatter.format([start, end], formatterValueCache,
|
||||||
stepSize: scale.domainStepSize);
|
stepSize: scale.domainStepSize);
|
||||||
|
|
||||||
ticks.add(new Tick(
|
ticks.add(Tick(
|
||||||
value: start,
|
value: start,
|
||||||
textElement: graphicsFactory.createTextElement(labels[0]),
|
textElement: graphicsFactory.createTextElement(labels[0]),
|
||||||
locationPx: scale[start]));
|
locationPx: scale[start]));
|
||||||
|
|
||||||
ticks.add(new Tick(
|
ticks.add(Tick(
|
||||||
value: end,
|
value: end,
|
||||||
textElement: graphicsFactory.createTextElement(labels[1]),
|
textElement: graphicsFactory.createTextElement(labels[1]),
|
||||||
locationPx: scale[end]));
|
locationPx: scale[end]));
|
||||||
|
|||||||
@@ -48,8 +48,7 @@ class BucketingNumericAxis extends NumericAxis {
|
|||||||
/// [threshold] will be rendered at the baseline of the chart. The
|
/// [threshold] will be rendered at the baseline of the chart. The
|
||||||
bool _showBucket;
|
bool _showBucket;
|
||||||
|
|
||||||
BucketingNumericAxis()
|
BucketingNumericAxis() : super(tickProvider: BucketingNumericTickProvider());
|
||||||
: super(tickProvider: new BucketingNumericTickProvider());
|
|
||||||
|
|
||||||
set threshold(num threshold) {
|
set threshold(num threshold) {
|
||||||
_threshold = threshold;
|
_threshold = threshold;
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ class BucketingNumericTickProvider extends NumericTickProvider {
|
|||||||
throw ('The showBucket flag must be set before getting ticks.');
|
throw ('The showBucket flag must be set before getting ticks.');
|
||||||
}
|
}
|
||||||
|
|
||||||
final localFormatter = new _BucketingFormatter()
|
final localFormatter = _BucketingFormatter()
|
||||||
..threshold = _threshold
|
..threshold = _threshold
|
||||||
..originalFormatter = formatter;
|
..originalFormatter = formatter;
|
||||||
|
|
||||||
@@ -100,7 +100,7 @@ class BucketingNumericTickProvider extends NumericTickProvider {
|
|||||||
assert(scale != null);
|
assert(scale != null);
|
||||||
|
|
||||||
// Create a tick for the threshold.
|
// Create a tick for the threshold.
|
||||||
final thresholdTick = new Tick<num>(
|
final thresholdTick = Tick<num>(
|
||||||
value: _threshold,
|
value: _threshold,
|
||||||
textElement: graphicsFactory
|
textElement: graphicsFactory
|
||||||
.createTextElement(localFormatter.formatValue(_threshold)),
|
.createTextElement(localFormatter.formatValue(_threshold)),
|
||||||
@@ -110,8 +110,8 @@ class BucketingNumericTickProvider extends NumericTickProvider {
|
|||||||
tickDrawStrategy.decorateTicks(<Tick<num>>[thresholdTick]);
|
tickDrawStrategy.decorateTicks(<Tick<num>>[thresholdTick]);
|
||||||
|
|
||||||
// Filter out ticks that sit below the threshold.
|
// Filter out ticks that sit below the threshold.
|
||||||
ticks.removeWhere((Tick<num> tick) =>
|
ticks.removeWhere(
|
||||||
tick.value <= thresholdTick.value && tick.value != 0.0);
|
(tick) => tick.value <= thresholdTick.value && tick.value != 0.0);
|
||||||
|
|
||||||
// Finally, add our threshold tick to the list.
|
// Finally, add our threshold tick to the list.
|
||||||
ticks.add(thresholdTick);
|
ticks.add(thresholdTick);
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ import 'linear_scale_viewport.dart' show LinearScaleViewportSettings;
|
|||||||
class LinearScale implements NumericScale {
|
class LinearScale implements NumericScale {
|
||||||
final LinearScaleDomainInfo _domainInfo;
|
final LinearScaleDomainInfo _domainInfo;
|
||||||
final LinearScaleViewportSettings _viewportSettings;
|
final LinearScaleViewportSettings _viewportSettings;
|
||||||
final LinearScaleFunction _scaleFunction = new LinearScaleFunction();
|
final LinearScaleFunction _scaleFunction = LinearScaleFunction();
|
||||||
|
|
||||||
RangeBandConfig rangeBandConfig = const RangeBandConfig.none();
|
RangeBandConfig rangeBandConfig = const RangeBandConfig.none();
|
||||||
StepSizeConfig stepSizeConfig = const StepSizeConfig.auto();
|
StepSizeConfig stepSizeConfig = const StepSizeConfig.auto();
|
||||||
@@ -57,18 +57,18 @@ class LinearScale implements NumericScale {
|
|||||||
bool _scaleReady = false;
|
bool _scaleReady = false;
|
||||||
|
|
||||||
LinearScale()
|
LinearScale()
|
||||||
: _domainInfo = new LinearScaleDomainInfo(),
|
: _domainInfo = LinearScaleDomainInfo(),
|
||||||
_viewportSettings = new LinearScaleViewportSettings();
|
_viewportSettings = LinearScaleViewportSettings();
|
||||||
|
|
||||||
LinearScale._copy(LinearScale other)
|
LinearScale._copy(LinearScale other)
|
||||||
: _domainInfo = new LinearScaleDomainInfo.copy(other._domainInfo),
|
: _domainInfo = LinearScaleDomainInfo.copy(other._domainInfo),
|
||||||
_viewportSettings =
|
_viewportSettings =
|
||||||
new LinearScaleViewportSettings.copy(other._viewportSettings),
|
LinearScaleViewportSettings.copy(other._viewportSettings),
|
||||||
rangeBandConfig = other.rangeBandConfig,
|
rangeBandConfig = other.rangeBandConfig,
|
||||||
stepSizeConfig = other.stepSizeConfig;
|
stepSizeConfig = other.stepSizeConfig;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
LinearScale copy() => new LinearScale._copy(this);
|
LinearScale copy() => LinearScale._copy(this);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Domain methods
|
// Domain methods
|
||||||
@@ -91,8 +91,8 @@ class LinearScale implements NumericScale {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
NumericExtents get dataExtent => new NumericExtents(
|
NumericExtents get dataExtent =>
|
||||||
_domainInfo.dataDomainStart, _domainInfo.dataDomainEnd);
|
NumericExtents(_domainInfo.dataDomainStart, _domainInfo.dataDomainEnd);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
num get minimumDomainStep => _domainInfo.minimumDetectedDomainStep;
|
num get minimumDomainStep => _domainInfo.minimumDetectedDomainStep;
|
||||||
|
|||||||
@@ -113,6 +113,6 @@ class LinearScaleDomainInfo {
|
|||||||
tmpDomainEnd = _dataDomainEnd.isFinite ? _dataDomainEnd : 1.0;
|
tmpDomainEnd = _dataDomainEnd.isFinite ? _dataDomainEnd : 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NumericExtents(tmpDomainStart, tmpDomainEnd);
|
return NumericExtents(tmpDomainStart, tmpDomainEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ class LinearScaleViewportSettings {
|
|||||||
double viewportStart =
|
double viewportStart =
|
||||||
(-1.0 * translatePx / scaleScalingFactor) + domainInfo.extent.min;
|
(-1.0 * translatePx / scaleScalingFactor) + domainInfo.extent.min;
|
||||||
_domainExtent =
|
_domainExtent =
|
||||||
new NumericExtents(viewportStart, viewportStart + viewportDomainDiff);
|
NumericExtents(viewportStart, viewportStart + viewportDomainDiff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ class NumericExtents implements Extents<num> {
|
|||||||
max = value;
|
max = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new NumericExtents(min, max);
|
return NumericExtents(min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the union of this and other.
|
/// Returns the union of this and other.
|
||||||
@@ -50,13 +50,13 @@ class NumericExtents implements Extents<num> {
|
|||||||
if (max >= other.max) {
|
if (max >= other.max) {
|
||||||
return this;
|
return this;
|
||||||
} else {
|
} else {
|
||||||
return new NumericExtents(min, other.max);
|
return NumericExtents(min, other.max);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (other.max >= max) {
|
if (other.max >= max) {
|
||||||
return other;
|
return other;
|
||||||
} else {
|
} else {
|
||||||
return new NumericExtents(other.min, max);
|
return NumericExtents(other.min, max);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,6 +100,6 @@ class NumericExtents implements Extents<num> {
|
|||||||
String toString() => 'Extent($min, $max)';
|
String toString() => 'Extent($min, $max)';
|
||||||
|
|
||||||
static const NumericExtents unbounded =
|
static const NumericExtents unbounded =
|
||||||
const NumericExtents(double.negativeInfinity, double.infinity);
|
NumericExtents(double.negativeInfinity, double.infinity);
|
||||||
static const NumericExtents empty = const NumericExtents(0.0, 0.0);
|
static const NumericExtents empty = NumericExtents(0.0, 0.0);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class NumericTickProvider extends BaseTickProvider<num> {
|
|||||||
static const MIN_DIPS_BETWEEN_TICKS = 25;
|
static const MIN_DIPS_BETWEEN_TICKS = 25;
|
||||||
|
|
||||||
/// Potential steps available to the baseTen value of the data.
|
/// Potential steps available to the baseTen value of the data.
|
||||||
static const DEFAULT_STEPS = const [
|
static const DEFAULT_STEPS = [
|
||||||
0.01,
|
0.01,
|
||||||
0.02,
|
0.02,
|
||||||
0.025,
|
0.025,
|
||||||
@@ -187,8 +187,8 @@ class NumericTickProvider extends BaseTickProvider<num> {
|
|||||||
assert(steps != null && steps.isNotEmpty);
|
assert(steps != null && steps.isNotEmpty);
|
||||||
steps.sort();
|
steps.sort();
|
||||||
|
|
||||||
final stepSet = new Set.from(steps);
|
final stepSet = Set.from(steps);
|
||||||
_allowedSteps = new List<double>(stepSet.length * 3);
|
_allowedSteps = List<double>(stepSet.length * 3);
|
||||||
int stepIndex = 0;
|
int stepIndex = 0;
|
||||||
for (double step in stepSet) {
|
for (double step in stepSet) {
|
||||||
assert(1.0 <= step && step < 10.0);
|
assert(1.0 <= step && step < 10.0);
|
||||||
@@ -220,7 +220,7 @@ class NumericTickProvider extends BaseTickProvider<num> {
|
|||||||
: (tickHint.start / stepSize).ceil()));
|
: (tickHint.start / stepSize).ceil()));
|
||||||
final tickStart =
|
final tickStart =
|
||||||
(scale.viewportDomain.min / stepSize).ceil() * stepSize + tickZeroShift;
|
(scale.viewportDomain.min / stepSize).ceil() * stepSize + tickZeroShift;
|
||||||
final stepInfo = new _TickStepInfo(stepSize.abs(), tickStart);
|
final stepInfo = _TickStepInfo(stepSize.abs(), tickStart);
|
||||||
final tickValues = _getTickValues(stepInfo, tickHint.tickCount);
|
final tickValues = _getTickValues(stepInfo, tickHint.tickCount);
|
||||||
|
|
||||||
// Create ticks from domain values.
|
// Create ticks from domain values.
|
||||||
@@ -299,8 +299,7 @@ class NumericTickProvider extends BaseTickProvider<num> {
|
|||||||
final tickValues = _getTickValues(stepInfo, tickCount);
|
final tickValues = _getTickValues(stepInfo, tickCount);
|
||||||
|
|
||||||
if (viewportExtensionEnabled) {
|
if (viewportExtensionEnabled) {
|
||||||
mutableScale.viewportDomain =
|
mutableScale.viewportDomain = NumericExtents(firstTick, lastTick);
|
||||||
new NumericExtents(firstTick, lastTick);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create ticks from domain values.
|
// Create ticks from domain values.
|
||||||
@@ -434,7 +433,7 @@ class NumericTickProvider extends BaseTickProvider<num> {
|
|||||||
!(low < 0 &&
|
!(low < 0 &&
|
||||||
high > 0 &&
|
high > 0 &&
|
||||||
(negativeRegionCount == 0 || positiveRegionCount == 0)),
|
(negativeRegionCount == 0 || positiveRegionCount == 0)),
|
||||||
'Numeric tick provider cannot generate ${tickCount} '
|
'Numeric tick provider cannot generate $tickCount '
|
||||||
'ticks when the axis range contains both positive and negative '
|
'ticks when the axis range contains both positive and negative '
|
||||||
'values. A minimum of three ticks are required to include zero.');
|
'values. A minimum of three ticks are required to include zero.');
|
||||||
|
|
||||||
@@ -467,7 +466,7 @@ class NumericTickProvider extends BaseTickProvider<num> {
|
|||||||
double stepStart = negativeRegionCount > 0
|
double stepStart = negativeRegionCount > 0
|
||||||
? (-1 * tmpStepSize * negativeRegionCount)
|
? (-1 * tmpStepSize * negativeRegionCount)
|
||||||
: 0.0;
|
: 0.0;
|
||||||
return new _TickStepInfo(tmpStepSize, stepStart);
|
return _TickStepInfo(tmpStepSize, stepStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -487,16 +486,16 @@ class NumericTickProvider extends BaseTickProvider<num> {
|
|||||||
// But wait until the last step to prevent the cost of the formatter.
|
// But wait until the last step to prevent the cost of the formatter.
|
||||||
double tmpStepStart = _getStepLessThan(low, tmpStepSize);
|
double tmpStepStart = _getStepLessThan(low, tmpStepSize);
|
||||||
if (tmpStepStart + (tmpStepSize * regionCount) >= high) {
|
if (tmpStepStart + (tmpStepSize * regionCount) >= high) {
|
||||||
return new _TickStepInfo(tmpStepSize, tmpStepStart);
|
return _TickStepInfo(tmpStepSize, tmpStepStart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new _TickStepInfo(1.0, low.floorToDouble());
|
return _TickStepInfo(1.0, low.floorToDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
List<double> _getTickValues(_TickStepInfo steps, int tickCount) {
|
List<double> _getTickValues(_TickStepInfo steps, int tickCount) {
|
||||||
final tickValues = new List<double>(tickCount);
|
final tickValues = List<double>(tickCount);
|
||||||
// We have our size and start, assign all the tick values to the given array.
|
// We have our size and start, assign all the tick values to the given array.
|
||||||
for (int i = 0; i < tickCount; i++) {
|
for (int i = 0; i < tickCount; i++) {
|
||||||
tickValues[i] = dataToAxisUnitConverter.invert(
|
tickValues[i] = dataToAxisUnitConverter.invert(
|
||||||
|
|||||||
@@ -27,11 +27,11 @@ class OrdinalExtents extends Extents<String> {
|
|||||||
/// [D] is the domain class type for the elements in the extents.
|
/// [D] is the domain class type for the elements in the extents.
|
||||||
OrdinalExtents(List<String> range) : _range = range {
|
OrdinalExtents(List<String> range) : _range = range {
|
||||||
// This asserts that all elements in [range] are unique.
|
// This asserts that all elements in [range] are unique.
|
||||||
final uniqueValueCount = new HashSet.from(_range).length;
|
final uniqueValueCount = HashSet.from(_range).length;
|
||||||
assert(uniqueValueCount == range.length);
|
assert(uniqueValueCount == range.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory OrdinalExtents.all(List<String> range) => new OrdinalExtents(range);
|
factory OrdinalExtents.all(List<String> range) => OrdinalExtents(range);
|
||||||
|
|
||||||
bool get isEmpty => _range.isEmpty;
|
bool get isEmpty => _range.isEmpty;
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ class OrdinalScaleDomainInfo {
|
|||||||
int _index = 0;
|
int _index = 0;
|
||||||
|
|
||||||
/// A map of domain value and the order it was added.
|
/// A map of domain value and the order it was added.
|
||||||
final _domainsToOrder = new HashMap<String, int>();
|
final _domainsToOrder = HashMap<String, int>();
|
||||||
|
|
||||||
/// A list of domain values kept to support [getDomainAtIndex].
|
/// A list of domain values kept to support [getDomainAtIndex].
|
||||||
final _domainList = <String>[];
|
final _domainList = <String>[];
|
||||||
@@ -33,7 +33,7 @@ class OrdinalScaleDomainInfo {
|
|||||||
OrdinalScaleDomainInfo();
|
OrdinalScaleDomainInfo();
|
||||||
|
|
||||||
OrdinalScaleDomainInfo copy() {
|
OrdinalScaleDomainInfo copy() {
|
||||||
return new OrdinalScaleDomainInfo()
|
return OrdinalScaleDomainInfo()
|
||||||
.._domainsToOrder.addAll(_domainsToOrder)
|
.._domainsToOrder.addAll(_domainsToOrder)
|
||||||
.._index = _index
|
.._index = _index
|
||||||
.._domainList.addAll(_domainList);
|
.._domainList.addAll(_domainList);
|
||||||
@@ -64,7 +64,7 @@ class OrdinalScaleDomainInfo {
|
|||||||
bool get isEmpty => (_index == 0);
|
bool get isEmpty => (_index == 0);
|
||||||
bool get isNotEmpty => !isEmpty;
|
bool get isNotEmpty => !isEmpty;
|
||||||
|
|
||||||
OrdinalExtents get extent => new OrdinalExtents.all(_domainList);
|
OrdinalExtents get extent => OrdinalExtents.all(_domainList);
|
||||||
|
|
||||||
int get size => _index;
|
int get size => _index;
|
||||||
|
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ import 'scale.dart'
|
|||||||
/// width of the bar is [rangeBand] and the position of the bar is retrieved
|
/// width of the bar is [rangeBand] and the position of the bar is retrieved
|
||||||
/// by [[]].
|
/// by [[]].
|
||||||
class SimpleOrdinalScale implements OrdinalScale {
|
class SimpleOrdinalScale implements OrdinalScale {
|
||||||
final _stepSizeConfig = new StepSizeConfig.auto();
|
final _stepSizeConfig = StepSizeConfig.auto();
|
||||||
OrdinalScaleDomainInfo _domain;
|
OrdinalScaleDomainInfo _domain;
|
||||||
ScaleOutputExtent _range = new ScaleOutputExtent(0, 1);
|
ScaleOutputExtent _range = ScaleOutputExtent(0, 1);
|
||||||
double _viewportScale = 1.0;
|
double _viewportScale = 1.0;
|
||||||
double _viewportTranslatePx = 0.0;
|
double _viewportTranslatePx = 0.0;
|
||||||
RangeBandConfig _rangeBandConfig = new RangeBandConfig.styleAssignedPercent();
|
RangeBandConfig _rangeBandConfig = RangeBandConfig.styleAssignedPercent();
|
||||||
|
|
||||||
bool _scaleChanged = true;
|
bool _scaleChanged = true;
|
||||||
double _cachedStepSizePixels;
|
double _cachedStepSizePixels;
|
||||||
@@ -47,11 +47,11 @@ class SimpleOrdinalScale implements OrdinalScale {
|
|||||||
int _viewportDataSize;
|
int _viewportDataSize;
|
||||||
String _viewportStartingDomain;
|
String _viewportStartingDomain;
|
||||||
|
|
||||||
SimpleOrdinalScale() : _domain = new OrdinalScaleDomainInfo();
|
SimpleOrdinalScale() : _domain = OrdinalScaleDomainInfo();
|
||||||
|
|
||||||
SimpleOrdinalScale._copy(SimpleOrdinalScale other)
|
SimpleOrdinalScale._copy(SimpleOrdinalScale other)
|
||||||
: _domain = other._domain.copy(),
|
: _domain = other._domain.copy(),
|
||||||
_range = new ScaleOutputExtent(other._range.start, other._range.end),
|
_range = ScaleOutputExtent(other._range.start, other._range.end),
|
||||||
_viewportScale = other._viewportScale,
|
_viewportScale = other._viewportScale,
|
||||||
_viewportTranslatePx = other._viewportTranslatePx,
|
_viewportTranslatePx = other._viewportTranslatePx,
|
||||||
_rangeBandConfig = other._rangeBandConfig;
|
_rangeBandConfig = other._rangeBandConfig;
|
||||||
@@ -80,12 +80,12 @@ class SimpleOrdinalScale implements OrdinalScale {
|
|||||||
@override
|
@override
|
||||||
set rangeBandConfig(RangeBandConfig barGroupWidthConfig) {
|
set rangeBandConfig(RangeBandConfig barGroupWidthConfig) {
|
||||||
if (barGroupWidthConfig == null) {
|
if (barGroupWidthConfig == null) {
|
||||||
throw new ArgumentError.notNull('RangeBandConfig must not be null.');
|
throw ArgumentError.notNull('RangeBandConfig must not be null.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (barGroupWidthConfig.type == RangeBandType.fixedDomain ||
|
if (barGroupWidthConfig.type == RangeBandType.fixedDomain ||
|
||||||
barGroupWidthConfig.type == RangeBandType.none) {
|
barGroupWidthConfig.type == RangeBandType.none) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'barGroupWidthConfig must not be NONE or FIXED_DOMAIN');
|
'barGroupWidthConfig must not be NONE or FIXED_DOMAIN');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ class SimpleOrdinalScale implements OrdinalScale {
|
|||||||
@override
|
@override
|
||||||
set stepSizeConfig(StepSizeConfig config) {
|
set stepSizeConfig(StepSizeConfig config) {
|
||||||
if (config != null && config.type != StepSizeType.autoDetect) {
|
if (config != null && config.type != StepSizeType.autoDetect) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'Ordinal scales only support StepSizeConfig of type Auto');
|
'Ordinal scales only support StepSizeConfig of type Auto');
|
||||||
}
|
}
|
||||||
// Nothing is set because only auto is supported.
|
// Nothing is set because only auto is supported.
|
||||||
@@ -205,7 +205,7 @@ class SimpleOrdinalScale implements OrdinalScale {
|
|||||||
if (startingDomain != null &&
|
if (startingDomain != null &&
|
||||||
viewportDataSize != null &&
|
viewportDataSize != null &&
|
||||||
viewportDataSize <= 0) {
|
viewportDataSize <= 0) {
|
||||||
throw new ArgumentError('viewportDataSize can' 't be less than 1.');
|
throw ArgumentError('viewportDataSize can' 't be less than 1.');
|
||||||
}
|
}
|
||||||
|
|
||||||
_scaleChanged = true;
|
_scaleChanged = true;
|
||||||
@@ -280,7 +280,7 @@ class SimpleOrdinalScale implements OrdinalScale {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SimpleOrdinalScale copy() => new SimpleOrdinalScale._copy(this);
|
SimpleOrdinalScale copy() => SimpleOrdinalScale._copy(this);
|
||||||
|
|
||||||
void _updateCachedFields(
|
void _updateCachedFields(
|
||||||
double stepSizePixels, double rangeBandPixels, double rangeBandShift) {
|
double stepSizePixels, double rangeBandPixels, double rangeBandShift) {
|
||||||
@@ -335,7 +335,7 @@ class SimpleOrdinalScale implements OrdinalScale {
|
|||||||
case RangeBandType.fixedDomain:
|
case RangeBandType.fixedDomain:
|
||||||
case RangeBandType.none:
|
case RangeBandType.none:
|
||||||
default:
|
default:
|
||||||
throw new StateError('RangeBandType must not be NONE or FIXED_DOMAIN');
|
throw StateError('RangeBandType must not be NONE or FIXED_DOMAIN');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class AxisSpec<D> {
|
|||||||
TickFormatterSpec<D> tickFormatterSpec,
|
TickFormatterSpec<D> tickFormatterSpec,
|
||||||
bool showAxisLine,
|
bool showAxisLine,
|
||||||
}) {
|
}) {
|
||||||
return new AxisSpec(
|
return AxisSpec(
|
||||||
renderSpec: renderSpec ?? other.renderSpec,
|
renderSpec: renderSpec ?? other.renderSpec,
|
||||||
tickProviderSpec: tickProviderSpec ?? other.tickProviderSpec,
|
tickProviderSpec: tickProviderSpec ?? other.tickProviderSpec,
|
||||||
tickFormatterSpec: tickFormatterSpec ?? other.tickFormatterSpec,
|
tickFormatterSpec: tickFormatterSpec ?? other.tickFormatterSpec,
|
||||||
|
|||||||
@@ -80,8 +80,8 @@ class BucketingAxisSpec extends NumericAxisSpec {
|
|||||||
tickProviderSpec:
|
tickProviderSpec:
|
||||||
tickProviderSpec ?? const BucketingNumericTickProviderSpec(),
|
tickProviderSpec ?? const BucketingNumericTickProviderSpec(),
|
||||||
tickFormatterSpec: tickFormatterSpec ??
|
tickFormatterSpec: tickFormatterSpec ??
|
||||||
new BasicNumericTickFormatterSpec.fromNumberFormat(
|
BasicNumericTickFormatterSpec.fromNumberFormat(
|
||||||
new NumberFormat.percentPattern()),
|
NumberFormat.percentPattern()),
|
||||||
showAxisLine: showAxisLine,
|
showAxisLine: showAxisLine,
|
||||||
viewport: viewport ?? const NumericExtents(0.0, 1.0));
|
viewport: viewport ?? const NumericExtents(0.0, 1.0));
|
||||||
|
|
||||||
@@ -104,7 +104,7 @@ class BucketingAxisSpec extends NumericAxisSpec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
BucketingNumericAxis createAxis() => new BucketingNumericAxis();
|
BucketingNumericAxis createAxis() => BucketingNumericAxis();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -155,7 +155,7 @@ class BucketingNumericTickProviderSpec extends BasicNumericTickProviderSpec {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
BucketingNumericTickProvider createTickProvider(ChartContext context) {
|
BucketingNumericTickProvider createTickProvider(ChartContext context) {
|
||||||
final provider = new BucketingNumericTickProvider()
|
final provider = BucketingNumericTickProvider()
|
||||||
..zeroBound = zeroBound
|
..zeroBound = zeroBound
|
||||||
..dataIsInWholeNumbers = dataIsInWholeNumbers;
|
..dataIsInWholeNumbers = dataIsInWholeNumbers;
|
||||||
|
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class DateTimeAxisSpec extends AxisSpec<DateTime> {
|
|||||||
|
|
||||||
/// Creates a [DateTimeAxis]. This should be called in place of createAxis.
|
/// Creates a [DateTimeAxis]. This should be called in place of createAxis.
|
||||||
DateTimeAxis createDateTimeAxis(DateTimeFactory dateTimeFactory) =>
|
DateTimeAxis createDateTimeAxis(DateTimeFactory dateTimeFactory) =>
|
||||||
new DateTimeAxis(dateTimeFactory);
|
DateTimeAxis(dateTimeFactory);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -121,10 +121,10 @@ class AutoDateTimeTickProviderSpec implements DateTimeTickProviderSpec {
|
|||||||
@override
|
@override
|
||||||
AutoAdjustingDateTimeTickProvider createTickProvider(ChartContext context) {
|
AutoAdjustingDateTimeTickProvider createTickProvider(ChartContext context) {
|
||||||
if (includeTime) {
|
if (includeTime) {
|
||||||
return new AutoAdjustingDateTimeTickProvider.createDefault(
|
return AutoAdjustingDateTimeTickProvider.createDefault(
|
||||||
context.dateTimeFactory);
|
context.dateTimeFactory);
|
||||||
} else {
|
} else {
|
||||||
return new AutoAdjustingDateTimeTickProvider.createWithoutTime(
|
return AutoAdjustingDateTimeTickProvider.createWithoutTime(
|
||||||
context.dateTimeFactory);
|
context.dateTimeFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -151,8 +151,8 @@ class DayTickProviderSpec implements DateTimeTickProviderSpec {
|
|||||||
/// when searching for the appropriate tick intervals.
|
/// when searching for the appropriate tick intervals.
|
||||||
@override
|
@override
|
||||||
AutoAdjustingDateTimeTickProvider createTickProvider(ChartContext context) {
|
AutoAdjustingDateTimeTickProvider createTickProvider(ChartContext context) {
|
||||||
return new AutoAdjustingDateTimeTickProvider.createWith([
|
return AutoAdjustingDateTimeTickProvider.createWith([
|
||||||
new TimeRangeTickProviderImpl(new DayTimeStepper(context.dateTimeFactory,
|
TimeRangeTickProviderImpl(DayTimeStepper(context.dateTimeFactory,
|
||||||
allowedTickIncrements: increments))
|
allowedTickIncrements: increments))
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ class DateTimeEndPointsTickProviderSpec implements DateTimeTickProviderSpec {
|
|||||||
/// two end points of the axis range
|
/// two end points of the axis range
|
||||||
@override
|
@override
|
||||||
EndPointsTickProvider<DateTime> createTickProvider(ChartContext context) {
|
EndPointsTickProvider<DateTime> createTickProvider(ChartContext context) {
|
||||||
return new EndPointsTickProvider<DateTime>();
|
return EndPointsTickProvider<DateTime>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -191,7 +191,7 @@ class StaticDateTimeTickProviderSpec implements DateTimeTickProviderSpec {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
StaticTickProvider<DateTime> createTickProvider(ChartContext context) =>
|
StaticTickProvider<DateTime> createTickProvider(ChartContext context) =>
|
||||||
new StaticTickProvider<DateTime>(tickSpecs);
|
StaticTickProvider<DateTime>(tickSpecs);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -285,19 +285,19 @@ class AutoDateTimeTickFormatterSpec implements DateTimeTickFormatterSpec {
|
|||||||
_makeFormatter(year, CalendarField.year, context);
|
_makeFormatter(year, CalendarField.year, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DateTimeTickFormatter(context.dateTimeFactory, overrides: map);
|
return DateTimeTickFormatter(context.dateTimeFactory, overrides: map);
|
||||||
}
|
}
|
||||||
|
|
||||||
TimeTickFormatterImpl _makeFormatter(TimeFormatterSpec spec,
|
TimeTickFormatterImpl _makeFormatter(TimeFormatterSpec spec,
|
||||||
CalendarField transitionField, ChartContext context) {
|
CalendarField transitionField, ChartContext context) {
|
||||||
if (spec.noonFormat != null) {
|
if (spec.noonFormat != null) {
|
||||||
return new HourTickFormatter(
|
return HourTickFormatter(
|
||||||
dateTimeFactory: context.dateTimeFactory,
|
dateTimeFactory: context.dateTimeFactory,
|
||||||
simpleFormat: spec.format,
|
simpleFormat: spec.format,
|
||||||
transitionFormat: spec.transitionFormat,
|
transitionFormat: spec.transitionFormat,
|
||||||
noonFormat: spec.noonFormat);
|
noonFormat: spec.noonFormat);
|
||||||
} else {
|
} else {
|
||||||
return new TimeTickFormatterImpl(
|
return TimeTickFormatterImpl(
|
||||||
dateTimeFactory: context.dateTimeFactory,
|
dateTimeFactory: context.dateTimeFactory,
|
||||||
simpleFormat: spec.format,
|
simpleFormat: spec.format,
|
||||||
transitionFormat: spec.transitionFormat,
|
transitionFormat: spec.transitionFormat,
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class NumericAxisSpec extends AxisSpec<num> {
|
|||||||
bool showAxisLine,
|
bool showAxisLine,
|
||||||
NumericExtents viewport,
|
NumericExtents viewport,
|
||||||
}) {
|
}) {
|
||||||
return new NumericAxisSpec(
|
return NumericAxisSpec(
|
||||||
renderSpec: renderSpec ?? other.renderSpec,
|
renderSpec: renderSpec ?? other.renderSpec,
|
||||||
tickProviderSpec: tickProviderSpec ?? other.tickProviderSpec,
|
tickProviderSpec: tickProviderSpec ?? other.tickProviderSpec,
|
||||||
tickFormatterSpec: tickFormatterSpec ?? other.tickFormatterSpec,
|
tickFormatterSpec: tickFormatterSpec ?? other.tickFormatterSpec,
|
||||||
@@ -88,7 +88,7 @@ class NumericAxisSpec extends AxisSpec<num> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
NumericAxis createAxis() => new NumericAxis();
|
NumericAxis createAxis() => NumericAxis();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -141,7 +141,7 @@ class BasicNumericTickProviderSpec implements NumericTickProviderSpec {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
NumericTickProvider createTickProvider(ChartContext context) {
|
NumericTickProvider createTickProvider(ChartContext context) {
|
||||||
final provider = new NumericTickProvider();
|
final provider = NumericTickProvider();
|
||||||
if (zeroBound != null) {
|
if (zeroBound != null) {
|
||||||
provider.zeroBound = zeroBound;
|
provider.zeroBound = zeroBound;
|
||||||
}
|
}
|
||||||
@@ -188,7 +188,7 @@ class NumericEndPointsTickProviderSpec implements NumericTickProviderSpec {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
EndPointsTickProvider<num> createTickProvider(ChartContext context) {
|
EndPointsTickProvider<num> createTickProvider(ChartContext context) {
|
||||||
return new EndPointsTickProvider<num>();
|
return EndPointsTickProvider<num>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -204,7 +204,7 @@ class StaticNumericTickProviderSpec implements NumericTickProviderSpec {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
StaticTickProvider<num> createTickProvider(ChartContext context) =>
|
StaticTickProvider<num> createTickProvider(ChartContext context) =>
|
||||||
new StaticTickProvider<num>(tickSpecs);
|
StaticTickProvider<num>(tickSpecs);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -232,8 +232,8 @@ class BasicNumericTickFormatterSpec implements NumericTickFormatterSpec {
|
|||||||
@override
|
@override
|
||||||
NumericTickFormatter createTickFormatter(ChartContext context) {
|
NumericTickFormatter createTickFormatter(ChartContext context) {
|
||||||
return numberFormat != null
|
return numberFormat != null
|
||||||
? new NumericTickFormatter.fromNumberFormat(numberFormat)
|
? NumericTickFormatter.fromNumberFormat(numberFormat)
|
||||||
: new NumericTickFormatter(formatter: formatter);
|
: NumericTickFormatter(formatter: formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ class OrdinalAxisSpec extends AxisSpec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
OrdinalAxis createAxis() => new OrdinalAxis();
|
OrdinalAxis createAxis() => OrdinalAxis();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
@@ -94,7 +94,7 @@ class BasicOrdinalTickProviderSpec implements OrdinalTickProviderSpec {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
OrdinalTickProvider createTickProvider(ChartContext context) =>
|
OrdinalTickProvider createTickProvider(ChartContext context) =>
|
||||||
new OrdinalTickProvider();
|
OrdinalTickProvider();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => other is BasicOrdinalTickProviderSpec;
|
bool operator ==(Object other) => other is BasicOrdinalTickProviderSpec;
|
||||||
@@ -112,7 +112,7 @@ class StaticOrdinalTickProviderSpec implements OrdinalTickProviderSpec {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
StaticTickProvider<String> createTickProvider(ChartContext context) =>
|
StaticTickProvider<String> createTickProvider(ChartContext context) =>
|
||||||
new StaticTickProvider<String>(tickSpecs);
|
StaticTickProvider<String>(tickSpecs);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -129,7 +129,7 @@ class BasicOrdinalTickFormatterSpec implements OrdinalTickFormatterSpec {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
OrdinalTickFormatter createTickFormatter(ChartContext context) =>
|
OrdinalTickFormatter createTickFormatter(ChartContext context) =>
|
||||||
new OrdinalTickFormatter();
|
OrdinalTickFormatter();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) => other is BasicOrdinalTickFormatterSpec;
|
bool operator ==(Object other) => other is BasicOrdinalTickFormatterSpec;
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ class PercentAxisSpec extends NumericAxisSpec {
|
|||||||
tickProviderSpec: tickProviderSpec ??
|
tickProviderSpec: tickProviderSpec ??
|
||||||
const BasicNumericTickProviderSpec(dataIsInWholeNumbers: false),
|
const BasicNumericTickProviderSpec(dataIsInWholeNumbers: false),
|
||||||
tickFormatterSpec: tickFormatterSpec ??
|
tickFormatterSpec: tickFormatterSpec ??
|
||||||
new BasicNumericTickFormatterSpec.fromNumberFormat(
|
BasicNumericTickFormatterSpec.fromNumberFormat(
|
||||||
new NumberFormat.percentPattern()),
|
NumberFormat.percentPattern()),
|
||||||
showAxisLine: showAxisLine,
|
showAxisLine: showAxisLine,
|
||||||
viewport: viewport ?? const NumericExtents(0.0, 1.0));
|
viewport: viewport ?? const NumericExtents(0.0, 1.0));
|
||||||
|
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class StaticTickProvider<D> extends TickProvider<D> {
|
|||||||
// We still check if the spec is within the viewport because we do not
|
// We still check if the spec is within the viewport because we do not
|
||||||
// extend the axis for OrdinalScale.
|
// extend the axis for OrdinalScale.
|
||||||
if (scale.compareDomainValueToViewport(spec.value) == 0) {
|
if (scale.compareDomainValueToViewport(spec.value) == 0) {
|
||||||
final tick = new Tick<D>(
|
final tick = Tick<D>(
|
||||||
value: spec.value,
|
value: spec.value,
|
||||||
textElement: graphicsFactory
|
textElement: graphicsFactory
|
||||||
.createTextElement(spec.label ?? formattedValues[i]),
|
.createTextElement(spec.label ?? formattedValues[i]),
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ abstract class SimpleTickFormatterBase<D> implements TickFormatter<D> {
|
|||||||
@override
|
@override
|
||||||
List<String> format(List<D> tickValues, Map<D, String> cache,
|
List<String> format(List<D> tickValues, Map<D, String> cache,
|
||||||
{num stepSize}) =>
|
{num stepSize}) =>
|
||||||
tickValues.map((D value) {
|
tickValues.map((value) {
|
||||||
// Try to use the cached formats first.
|
// Try to use the cached formats first.
|
||||||
String formattedString = cache[value];
|
String formattedString = cache[value];
|
||||||
if (formattedString == null) {
|
if (formattedString == null) {
|
||||||
@@ -75,24 +75,24 @@ class NumericTickFormatter extends SimpleTickFormatterBase<num> {
|
|||||||
/// [formatter] optionally specify a formatter to be used. Defaults to using
|
/// [formatter] optionally specify a formatter to be used. Defaults to using
|
||||||
/// [NumberFormat.decimalPattern] if none is specified.
|
/// [NumberFormat.decimalPattern] if none is specified.
|
||||||
factory NumericTickFormatter({MeasureFormatter formatter}) {
|
factory NumericTickFormatter({MeasureFormatter formatter}) {
|
||||||
formatter ??= _getFormatter(new NumberFormat.decimalPattern());
|
formatter ??= _getFormatter(NumberFormat.decimalPattern());
|
||||||
return new NumericTickFormatter._internal(formatter);
|
return NumericTickFormatter._internal(formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new [NumericTickFormatter] that formats using [numberFormat].
|
/// Constructs a new [NumericTickFormatter] that formats using [numberFormat].
|
||||||
factory NumericTickFormatter.fromNumberFormat(NumberFormat numberFormat) {
|
factory NumericTickFormatter.fromNumberFormat(NumberFormat numberFormat) {
|
||||||
return new NumericTickFormatter._internal(_getFormatter(numberFormat));
|
return NumericTickFormatter._internal(_getFormatter(numberFormat));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs a new formatter that uses [NumberFormat.compactCurrency].
|
/// Constructs a new formatter that uses [NumberFormat.compactCurrency].
|
||||||
factory NumericTickFormatter.compactSimpleCurrency() {
|
factory NumericTickFormatter.compactSimpleCurrency() {
|
||||||
return new NumericTickFormatter._internal(
|
return NumericTickFormatter._internal(
|
||||||
_getFormatter(new NumberFormat.compactCurrency()));
|
_getFormatter(NumberFormat.compactCurrency()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a [MeasureFormatter] that calls format on [numberFormat].
|
/// Returns a [MeasureFormatter] that calls format on [numberFormat].
|
||||||
static MeasureFormatter _getFormatter(NumberFormat numberFormat) {
|
static MeasureFormatter _getFormatter(NumberFormat numberFormat) {
|
||||||
return (num value) => numberFormat.format(value);
|
return (value) => numberFormat.format(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ abstract class BaseTickProvider<D> implements TickProvider<D> {
|
|||||||
|
|
||||||
for (var i = 0; i < domainValues.length; i++) {
|
for (var i = 0; i < domainValues.length; i++) {
|
||||||
final value = domainValues[i];
|
final value = domainValues[i];
|
||||||
final tick = new Tick(
|
final tick = Tick(
|
||||||
value: value,
|
value: value,
|
||||||
textElement: graphicsFactory.createTextElement(labels[i]),
|
textElement: graphicsFactory.createTextElement(labels[i]),
|
||||||
locationPx: scale[value]);
|
locationPx: scale[value]);
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class AutoAdjustingDateTimeTickProvider implements TickProvider<DateTime> {
|
|||||||
/// Creates a default [AutoAdjustingDateTimeTickProvider] for day and time.
|
/// Creates a default [AutoAdjustingDateTimeTickProvider] for day and time.
|
||||||
factory AutoAdjustingDateTimeTickProvider.createDefault(
|
factory AutoAdjustingDateTimeTickProvider.createDefault(
|
||||||
DateTimeFactory dateTimeFactory) {
|
DateTimeFactory dateTimeFactory) {
|
||||||
return new AutoAdjustingDateTimeTickProvider._internal([
|
return AutoAdjustingDateTimeTickProvider._internal([
|
||||||
createYearTickProvider(dateTimeFactory),
|
createYearTickProvider(dateTimeFactory),
|
||||||
createMonthTickProvider(dateTimeFactory),
|
createMonthTickProvider(dateTimeFactory),
|
||||||
createDayTickProvider(dateTimeFactory),
|
createDayTickProvider(dateTimeFactory),
|
||||||
@@ -66,7 +66,7 @@ class AutoAdjustingDateTimeTickProvider implements TickProvider<DateTime> {
|
|||||||
/// Creates a default [AutoAdjustingDateTimeTickProvider] for day only.
|
/// Creates a default [AutoAdjustingDateTimeTickProvider] for day only.
|
||||||
factory AutoAdjustingDateTimeTickProvider.createWithoutTime(
|
factory AutoAdjustingDateTimeTickProvider.createWithoutTime(
|
||||||
DateTimeFactory dateTimeFactory) {
|
DateTimeFactory dateTimeFactory) {
|
||||||
return new AutoAdjustingDateTimeTickProvider._internal([
|
return AutoAdjustingDateTimeTickProvider._internal([
|
||||||
createYearTickProvider(dateTimeFactory),
|
createYearTickProvider(dateTimeFactory),
|
||||||
createMonthTickProvider(dateTimeFactory),
|
createMonthTickProvider(dateTimeFactory),
|
||||||
createDayTickProvider(dateTimeFactory)
|
createDayTickProvider(dateTimeFactory)
|
||||||
@@ -80,11 +80,10 @@ class AutoAdjustingDateTimeTickProvider implements TickProvider<DateTime> {
|
|||||||
factory AutoAdjustingDateTimeTickProvider.createWith(
|
factory AutoAdjustingDateTimeTickProvider.createWith(
|
||||||
List<TimeRangeTickProvider> potentialTickProviders) {
|
List<TimeRangeTickProvider> potentialTickProviders) {
|
||||||
if (potentialTickProviders == null || potentialTickProviders.isEmpty) {
|
if (potentialTickProviders == null || potentialTickProviders.isEmpty) {
|
||||||
throw new ArgumentError('At least one TimeRangeTickProvider is required');
|
throw ArgumentError('At least one TimeRangeTickProvider is required');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AutoAdjustingDateTimeTickProvider._internal(
|
return AutoAdjustingDateTimeTickProvider._internal(potentialTickProviders);
|
||||||
potentialTickProviders);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a list of ticks for the given data which should not collide
|
/// Generates a list of ticks for the given data which should not collide
|
||||||
@@ -157,21 +156,21 @@ class AutoAdjustingDateTimeTickProvider implements TickProvider<DateTime> {
|
|||||||
|
|
||||||
static TimeRangeTickProvider createYearTickProvider(
|
static TimeRangeTickProvider createYearTickProvider(
|
||||||
DateTimeFactory dateTimeFactory) =>
|
DateTimeFactory dateTimeFactory) =>
|
||||||
new TimeRangeTickProviderImpl(new YearTimeStepper(dateTimeFactory));
|
TimeRangeTickProviderImpl(YearTimeStepper(dateTimeFactory));
|
||||||
|
|
||||||
static TimeRangeTickProvider createMonthTickProvider(
|
static TimeRangeTickProvider createMonthTickProvider(
|
||||||
DateTimeFactory dateTimeFactory) =>
|
DateTimeFactory dateTimeFactory) =>
|
||||||
new TimeRangeTickProviderImpl(new MonthTimeStepper(dateTimeFactory));
|
TimeRangeTickProviderImpl(MonthTimeStepper(dateTimeFactory));
|
||||||
|
|
||||||
static TimeRangeTickProvider createDayTickProvider(
|
static TimeRangeTickProvider createDayTickProvider(
|
||||||
DateTimeFactory dateTimeFactory) =>
|
DateTimeFactory dateTimeFactory) =>
|
||||||
new TimeRangeTickProviderImpl(new DayTimeStepper(dateTimeFactory));
|
TimeRangeTickProviderImpl(DayTimeStepper(dateTimeFactory));
|
||||||
|
|
||||||
static TimeRangeTickProvider createHourTickProvider(
|
static TimeRangeTickProvider createHourTickProvider(
|
||||||
DateTimeFactory dateTimeFactory) =>
|
DateTimeFactory dateTimeFactory) =>
|
||||||
new TimeRangeTickProviderImpl(new HourTimeStepper(dateTimeFactory));
|
TimeRangeTickProviderImpl(HourTimeStepper(dateTimeFactory));
|
||||||
|
|
||||||
static TimeRangeTickProvider createMinuteTickProvider(
|
static TimeRangeTickProvider createMinuteTickProvider(
|
||||||
DateTimeFactory dateTimeFactory) =>
|
DateTimeFactory dateTimeFactory) =>
|
||||||
new TimeRangeTickProviderImpl(new MinuteTimeStepper(dateTimeFactory));
|
TimeRangeTickProviderImpl(MinuteTimeStepper(dateTimeFactory));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ abstract class BaseTimeStepper implements TimeStepper {
|
|||||||
// Keep the steps iterable unless time extent changes, so the same iterator
|
// Keep the steps iterable unless time extent changes, so the same iterator
|
||||||
// can be used and reset for different increments.
|
// can be used and reset for different increments.
|
||||||
if (_stepsIterable == null || _stepsIterable.timeExtent != timeExtent) {
|
if (_stepsIterable == null || _stepsIterable.timeExtent != timeExtent) {
|
||||||
_stepsIterable = new _TimeStepIteratorFactoryImpl(timeExtent, this);
|
_stepsIterable = _TimeStepIteratorFactoryImpl(timeExtent, this);
|
||||||
}
|
}
|
||||||
return _stepsIterable;
|
return _stepsIterable;
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ abstract class BaseTimeStepper implements TimeStepper {
|
|||||||
final stepBefore = getStepTimeBeforeInclusive(timeExtent.start, 1);
|
final stepBefore = getStepTimeBeforeInclusive(timeExtent.start, 1);
|
||||||
final stepAfter = getStepTimeAfterInclusive(timeExtent.end, 1);
|
final stepAfter = getStepTimeAfterInclusive(timeExtent.end, 1);
|
||||||
|
|
||||||
return new DateTimeExtents(start: stepBefore, end: stepAfter);
|
return DateTimeExtents(start: stepBefore, end: stepAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime getStepTimeAfterInclusive(DateTime time, int tickIncrement) {
|
DateTime getStepTimeAfterInclusive(DateTime time, int tickIncrement) {
|
||||||
@@ -127,8 +127,8 @@ class _TimeStepIteratorFactoryImpl extends TimeStepIteratorFactory {
|
|||||||
DateTimeExtents timeExtent, BaseTimeStepper stepper) {
|
DateTimeExtents timeExtent, BaseTimeStepper stepper) {
|
||||||
final startTime = timeExtent.start;
|
final startTime = timeExtent.start;
|
||||||
final endTime = timeExtent.end;
|
final endTime = timeExtent.end;
|
||||||
return new _TimeStepIteratorFactoryImpl._internal(
|
return _TimeStepIteratorFactoryImpl._internal(
|
||||||
new _TimeStepIteratorImpl(startTime, endTime, stepper), timeExtent);
|
_TimeStepIteratorImpl(startTime, endTime, stepper), timeExtent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -28,11 +28,10 @@ class DateTimeAxis extends Axis<DateTime> {
|
|||||||
{TickProvider tickProvider, TickFormatter tickFormatter})
|
{TickProvider tickProvider, TickFormatter tickFormatter})
|
||||||
: super(
|
: super(
|
||||||
tickProvider: tickProvider ??
|
tickProvider: tickProvider ??
|
||||||
new AutoAdjustingDateTimeTickProvider.createDefault(
|
AutoAdjustingDateTimeTickProvider.createDefault(dateTimeFactory),
|
||||||
dateTimeFactory),
|
|
||||||
tickFormatter:
|
tickFormatter:
|
||||||
tickFormatter ?? new DateTimeTickFormatter(dateTimeFactory),
|
tickFormatter ?? DateTimeTickFormatter(dateTimeFactory),
|
||||||
scale: new DateTimeScale(dateTimeFactory),
|
scale: DateTimeScale(dateTimeFactory),
|
||||||
);
|
);
|
||||||
|
|
||||||
void setScaleViewport(DateTimeExtents viewport) {
|
void setScaleViewport(DateTimeExtents viewport) {
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ class DateTimeScale extends MutableScale<DateTime> {
|
|||||||
final DateTimeFactory dateTimeFactory;
|
final DateTimeFactory dateTimeFactory;
|
||||||
final LinearScale _linearScale;
|
final LinearScale _linearScale;
|
||||||
|
|
||||||
DateTimeScale(this.dateTimeFactory) : _linearScale = new LinearScale();
|
DateTimeScale(this.dateTimeFactory) : _linearScale = LinearScale();
|
||||||
|
|
||||||
DateTimeScale._copy(DateTimeScale other)
|
DateTimeScale._copy(DateTimeScale other)
|
||||||
: dateTimeFactory = other.dateTimeFactory,
|
: dateTimeFactory = other.dateTimeFactory,
|
||||||
@@ -82,7 +82,7 @@ class DateTimeScale extends MutableScale<DateTime> {
|
|||||||
|
|
||||||
DateTimeExtents get viewportDomain {
|
DateTimeExtents get viewportDomain {
|
||||||
final extents = _linearScale.viewportDomain;
|
final extents = _linearScale.viewportDomain;
|
||||||
return new DateTimeExtents(
|
return DateTimeExtents(
|
||||||
start: dateTimeFactory
|
start: dateTimeFactory
|
||||||
.createDateTimeFromMilliSecondsSinceEpoch(extents.min.toInt()),
|
.createDateTimeFromMilliSecondsSinceEpoch(extents.min.toInt()),
|
||||||
end: dateTimeFactory
|
end: dateTimeFactory
|
||||||
@@ -90,13 +90,13 @@ class DateTimeScale extends MutableScale<DateTime> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
set viewportDomain(DateTimeExtents extents) {
|
set viewportDomain(DateTimeExtents extents) {
|
||||||
_linearScale.viewportDomain = new NumericExtents(
|
_linearScale.viewportDomain = NumericExtents(
|
||||||
extents.start.millisecondsSinceEpoch,
|
extents.start.millisecondsSinceEpoch,
|
||||||
extents.end.millisecondsSinceEpoch);
|
extents.end.millisecondsSinceEpoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
DateTimeScale copy() => new DateTimeScale._copy(this);
|
DateTimeScale copy() => DateTimeScale._copy(this);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
double get viewportTranslatePx => _linearScale.viewportTranslatePx;
|
double get viewportTranslatePx => _linearScale.viewportTranslatePx;
|
||||||
|
|||||||
@@ -56,27 +56,27 @@ class DateTimeTickFormatter implements TickFormatter<DateTime> {
|
|||||||
factory DateTimeTickFormatter(DateTimeFactory dateTimeFactory,
|
factory DateTimeTickFormatter(DateTimeFactory dateTimeFactory,
|
||||||
{Map<int, TimeTickFormatter> overrides}) {
|
{Map<int, TimeTickFormatter> overrides}) {
|
||||||
final Map<int, TimeTickFormatter> map = {
|
final Map<int, TimeTickFormatter> map = {
|
||||||
MINUTE: new TimeTickFormatterImpl(
|
MINUTE: TimeTickFormatterImpl(
|
||||||
dateTimeFactory: dateTimeFactory,
|
dateTimeFactory: dateTimeFactory,
|
||||||
simpleFormat: 'mm',
|
simpleFormat: 'mm',
|
||||||
transitionFormat: 'h mm',
|
transitionFormat: 'h mm',
|
||||||
transitionField: CalendarField.hourOfDay),
|
transitionField: CalendarField.hourOfDay),
|
||||||
HOUR: new HourTickFormatter(
|
HOUR: HourTickFormatter(
|
||||||
dateTimeFactory: dateTimeFactory,
|
dateTimeFactory: dateTimeFactory,
|
||||||
simpleFormat: 'h',
|
simpleFormat: 'h',
|
||||||
transitionFormat: 'MMM d ha',
|
transitionFormat: 'MMM d ha',
|
||||||
noonFormat: 'ha'),
|
noonFormat: 'ha'),
|
||||||
23 * HOUR: new TimeTickFormatterImpl(
|
23 * HOUR: TimeTickFormatterImpl(
|
||||||
dateTimeFactory: dateTimeFactory,
|
dateTimeFactory: dateTimeFactory,
|
||||||
simpleFormat: 'd',
|
simpleFormat: 'd',
|
||||||
transitionFormat: 'MMM d',
|
transitionFormat: 'MMM d',
|
||||||
transitionField: CalendarField.month),
|
transitionField: CalendarField.month),
|
||||||
28 * DAY: new TimeTickFormatterImpl(
|
28 * DAY: TimeTickFormatterImpl(
|
||||||
dateTimeFactory: dateTimeFactory,
|
dateTimeFactory: dateTimeFactory,
|
||||||
simpleFormat: 'MMM',
|
simpleFormat: 'MMM',
|
||||||
transitionFormat: 'MMM yyyy',
|
transitionFormat: 'MMM yyyy',
|
||||||
transitionField: CalendarField.year),
|
transitionField: CalendarField.year),
|
||||||
364 * DAY: new TimeTickFormatterImpl(
|
364 * DAY: TimeTickFormatterImpl(
|
||||||
dateTimeFactory: dateTimeFactory,
|
dateTimeFactory: dateTimeFactory,
|
||||||
simpleFormat: 'yyyy',
|
simpleFormat: 'yyyy',
|
||||||
transitionFormat: 'yyyy',
|
transitionFormat: 'yyyy',
|
||||||
@@ -88,23 +88,23 @@ class DateTimeTickFormatter implements TickFormatter<DateTime> {
|
|||||||
map.addAll(overrides);
|
map.addAll(overrides);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DateTimeTickFormatter._internal(map);
|
return DateTimeTickFormatter._internal(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [DateTimeTickFormatter] without the time component.
|
/// Creates a [DateTimeTickFormatter] without the time component.
|
||||||
factory DateTimeTickFormatter.withoutTime(DateTimeFactory dateTimeFactory) {
|
factory DateTimeTickFormatter.withoutTime(DateTimeFactory dateTimeFactory) {
|
||||||
return new DateTimeTickFormatter._internal({
|
return DateTimeTickFormatter._internal({
|
||||||
23 * HOUR: new TimeTickFormatterImpl(
|
23 * HOUR: TimeTickFormatterImpl(
|
||||||
dateTimeFactory: dateTimeFactory,
|
dateTimeFactory: dateTimeFactory,
|
||||||
simpleFormat: 'd',
|
simpleFormat: 'd',
|
||||||
transitionFormat: 'MMM d',
|
transitionFormat: 'MMM d',
|
||||||
transitionField: CalendarField.month),
|
transitionField: CalendarField.month),
|
||||||
28 * DAY: new TimeTickFormatterImpl(
|
28 * DAY: TimeTickFormatterImpl(
|
||||||
dateTimeFactory: dateTimeFactory,
|
dateTimeFactory: dateTimeFactory,
|
||||||
simpleFormat: 'MMM',
|
simpleFormat: 'MMM',
|
||||||
transitionFormat: 'MMM yyyy',
|
transitionFormat: 'MMM yyyy',
|
||||||
transitionField: CalendarField.year),
|
transitionField: CalendarField.year),
|
||||||
365 * DAY: new TimeTickFormatterImpl(
|
365 * DAY: TimeTickFormatterImpl(
|
||||||
dateTimeFactory: dateTimeFactory,
|
dateTimeFactory: dateTimeFactory,
|
||||||
simpleFormat: 'yyyy',
|
simpleFormat: 'yyyy',
|
||||||
transitionFormat: 'yyyy',
|
transitionFormat: 'yyyy',
|
||||||
@@ -119,7 +119,7 @@ class DateTimeTickFormatter implements TickFormatter<DateTime> {
|
|||||||
///
|
///
|
||||||
/// [formatter] The format for all ticks.
|
/// [formatter] The format for all ticks.
|
||||||
factory DateTimeTickFormatter.uniform(TimeTickFormatter formatter) {
|
factory DateTimeTickFormatter.uniform(TimeTickFormatter formatter) {
|
||||||
return new DateTimeTickFormatter._internal({ANY: formatter});
|
return DateTimeTickFormatter._internal({ANY: formatter});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a [DateTimeTickFormatter] that formats ticks with [formatters].
|
/// Creates a [DateTimeTickFormatter] that formats ticks with [formatters].
|
||||||
@@ -129,10 +129,10 @@ class DateTimeTickFormatter implements TickFormatter<DateTime> {
|
|||||||
Map<int, TimeTickFormatter> formatters) {
|
Map<int, TimeTickFormatter> formatters) {
|
||||||
// Formatters must be non empty.
|
// Formatters must be non empty.
|
||||||
if (formatters == null || formatters.isEmpty) {
|
if (formatters == null || formatters.isEmpty) {
|
||||||
throw new ArgumentError('At least one TimeTickFormatter is required.');
|
throw ArgumentError('At least one TimeTickFormatter is required.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DateTimeTickFormatter._internal(formatters);
|
return DateTimeTickFormatter._internal(formatters);
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTimeTickFormatter._internal(this._timeFormatters) {
|
DateTimeTickFormatter._internal(this._timeFormatters) {
|
||||||
@@ -202,7 +202,7 @@ class DateTimeTickFormatter implements TickFormatter<DateTime> {
|
|||||||
// Only need to check the first value, because the values after are expected
|
// Only need to check the first value, because the values after are expected
|
||||||
// to be greater.
|
// to be greater.
|
||||||
if (prev <= 0) {
|
if (prev <= 0) {
|
||||||
throw new ArgumentError('Formatter keys must be positive');
|
throw ArgumentError('Formatter keys must be positive');
|
||||||
}
|
}
|
||||||
|
|
||||||
while (valuesIterator.moveNext() && isSorted) {
|
while (valuesIterator.moveNext() && isSorted) {
|
||||||
@@ -211,7 +211,7 @@ class DateTimeTickFormatter implements TickFormatter<DateTime> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isSorted) {
|
if (!isSorted) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'Formatters must be sorted with keys in increasing order');
|
'Formatters must be sorted with keys in increasing order');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import 'base_time_stepper.dart' show BaseTimeStepper;
|
|||||||
/// Day stepper.
|
/// Day stepper.
|
||||||
class DayTimeStepper extends BaseTimeStepper {
|
class DayTimeStepper extends BaseTimeStepper {
|
||||||
// TODO: Remove the 14 day increment if we add week stepper.
|
// TODO: Remove the 14 day increment if we add week stepper.
|
||||||
static const _defaultIncrements = const [1, 2, 3, 7, 14];
|
static const _defaultIncrements = [1, 2, 3, 7, 14];
|
||||||
static const _hoursInDay = 24;
|
static const _hoursInDay = 24;
|
||||||
|
|
||||||
final List<int> _allowedTickIncrements;
|
final List<int> _allowedTickIncrements;
|
||||||
@@ -39,7 +39,7 @@ class DayTimeStepper extends BaseTimeStepper {
|
|||||||
// All increments must be > 0.
|
// All increments must be > 0.
|
||||||
assert(allowedTickIncrements.any((increment) => increment <= 0) == false);
|
assert(allowedTickIncrements.any((increment) => increment <= 0) == false);
|
||||||
|
|
||||||
return new DayTimeStepper._internal(dateTimeFactory, allowedTickIncrements);
|
return DayTimeStepper._internal(dateTimeFactory, allowedTickIncrements);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -60,7 +60,7 @@ class DayTimeStepper extends BaseTimeStepper {
|
|||||||
final dayRemainder = (time.day - 1) % tickIncrement;
|
final dayRemainder = (time.day - 1) % tickIncrement;
|
||||||
// Subtract an extra hour in case stepping through a daylight saving change.
|
// Subtract an extra hour in case stepping through a daylight saving change.
|
||||||
final dayBefore = dayRemainder > 0
|
final dayBefore = dayRemainder > 0
|
||||||
? time.subtract(new Duration(hours: (_hoursInDay * dayRemainder) - 1))
|
? time.subtract(Duration(hours: (_hoursInDay * dayRemainder) - 1))
|
||||||
: time;
|
: time;
|
||||||
// Explicitly leaving off hours and beyond to truncate to start of day.
|
// Explicitly leaving off hours and beyond to truncate to start of day.
|
||||||
final stepBefore = dateTimeFactory.createDateTime(
|
final stepBefore = dateTimeFactory.createDateTime(
|
||||||
@@ -73,7 +73,7 @@ class DayTimeStepper extends BaseTimeStepper {
|
|||||||
DateTime getNextStepTime(DateTime time, int tickIncrement) {
|
DateTime getNextStepTime(DateTime time, int tickIncrement) {
|
||||||
// Add an extra hour in case stepping through a daylight saving change.
|
// Add an extra hour in case stepping through a daylight saving change.
|
||||||
final stepAfter =
|
final stepAfter =
|
||||||
time.add(new Duration(hours: (_hoursInDay * tickIncrement) + 1));
|
time.add(Duration(hours: (_hoursInDay * tickIncrement) + 1));
|
||||||
// Explicitly leaving off hours and beyond to truncate to start of day.
|
// Explicitly leaving off hours and beyond to truncate to start of day.
|
||||||
return dateTimeFactory.createDateTime(
|
return dateTimeFactory.createDateTime(
|
||||||
stepAfter.year, stepAfter.month, stepAfter.day);
|
stepAfter.year, stepAfter.month, stepAfter.day);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import 'base_time_stepper.dart' show BaseTimeStepper;
|
|||||||
|
|
||||||
/// Hour stepper.
|
/// Hour stepper.
|
||||||
class HourTimeStepper extends BaseTimeStepper {
|
class HourTimeStepper extends BaseTimeStepper {
|
||||||
static const _defaultIncrements = const [1, 2, 3, 4, 6, 12, 24];
|
static const _defaultIncrements = [1, 2, 3, 4, 6, 12, 24];
|
||||||
static const _hoursInDay = 24;
|
static const _hoursInDay = 24;
|
||||||
static const _millisecondsInHour = 3600 * 1000;
|
static const _millisecondsInHour = 3600 * 1000;
|
||||||
|
|
||||||
@@ -41,8 +41,7 @@ class HourTimeStepper extends BaseTimeStepper {
|
|||||||
.any((increment) => increment <= 0 || increment > 24) ==
|
.any((increment) => increment <= 0 || increment > 24) ==
|
||||||
false);
|
false);
|
||||||
|
|
||||||
return new HourTimeStepper._internal(
|
return HourTimeStepper._internal(dateTimeFactory, allowedTickIncrements);
|
||||||
dateTimeFactory, allowedTickIncrements);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -60,7 +59,7 @@ class HourTimeStepper extends BaseTimeStepper {
|
|||||||
DateTime getStepTimeBeforeInclusive(DateTime time, int tickIncrement) {
|
DateTime getStepTimeBeforeInclusive(DateTime time, int tickIncrement) {
|
||||||
final nextDay = dateTimeFactory
|
final nextDay = dateTimeFactory
|
||||||
.createDateTime(time.year, time.month, time.day)
|
.createDateTime(time.year, time.month, time.day)
|
||||||
.add(new Duration(hours: _hoursInDay + 1));
|
.add(Duration(hours: _hoursInDay + 1));
|
||||||
final nextDayStart = dateTimeFactory.createDateTime(
|
final nextDayStart = dateTimeFactory.createDateTime(
|
||||||
nextDay.year, nextDay.month, nextDay.day);
|
nextDay.year, nextDay.month, nextDay.day);
|
||||||
|
|
||||||
@@ -83,6 +82,6 @@ class HourTimeStepper extends BaseTimeStepper {
|
|||||||
/// [time] is expected to be a [DateTime] with the hour at start of the hour.
|
/// [time] is expected to be a [DateTime] with the hour at start of the hour.
|
||||||
@override
|
@override
|
||||||
DateTime getNextStepTime(DateTime time, int tickIncrement) {
|
DateTime getNextStepTime(DateTime time, int tickIncrement) {
|
||||||
return time.add(new Duration(hours: tickIncrement));
|
return time.add(Duration(hours: tickIncrement));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import 'base_time_stepper.dart';
|
|||||||
|
|
||||||
/// Minute stepper where ticks generated aligns with the hour.
|
/// Minute stepper where ticks generated aligns with the hour.
|
||||||
class MinuteTimeStepper extends BaseTimeStepper {
|
class MinuteTimeStepper extends BaseTimeStepper {
|
||||||
static const _defaultIncrements = const [5, 10, 15, 20, 30];
|
static const _defaultIncrements = [5, 10, 15, 20, 30];
|
||||||
static const _millisecondsInMinute = 60 * 1000;
|
static const _millisecondsInMinute = 60 * 1000;
|
||||||
|
|
||||||
final List<int> _allowedTickIncrements;
|
final List<int> _allowedTickIncrements;
|
||||||
@@ -40,8 +40,7 @@ class MinuteTimeStepper extends BaseTimeStepper {
|
|||||||
.any((increment) => increment <= 0 || increment > 60) ==
|
.any((increment) => increment <= 0 || increment > 60) ==
|
||||||
false);
|
false);
|
||||||
|
|
||||||
return new MinuteTimeStepper._internal(
|
return MinuteTimeStepper._internal(dateTimeFactory, allowedTickIncrements);
|
||||||
dateTimeFactory, allowedTickIncrements);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -73,6 +72,6 @@ class MinuteTimeStepper extends BaseTimeStepper {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
DateTime getNextStepTime(DateTime time, int tickIncrement) {
|
DateTime getNextStepTime(DateTime time, int tickIncrement) {
|
||||||
return time.add(new Duration(minutes: tickIncrement));
|
return time.add(Duration(minutes: tickIncrement));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import 'base_time_stepper.dart' show BaseTimeStepper;
|
|||||||
|
|
||||||
/// Month stepper.
|
/// Month stepper.
|
||||||
class MonthTimeStepper extends BaseTimeStepper {
|
class MonthTimeStepper extends BaseTimeStepper {
|
||||||
static const _defaultIncrements = const [1, 2, 3, 4, 6, 12];
|
static const _defaultIncrements = [1, 2, 3, 4, 6, 12];
|
||||||
|
|
||||||
final List<int> _allowedTickIncrements;
|
final List<int> _allowedTickIncrements;
|
||||||
|
|
||||||
@@ -37,8 +37,7 @@ class MonthTimeStepper extends BaseTimeStepper {
|
|||||||
// All increments must be > 0.
|
// All increments must be > 0.
|
||||||
assert(allowedTickIncrements.any((increment) => increment <= 0) == false);
|
assert(allowedTickIncrements.any((increment) => increment <= 0) == false);
|
||||||
|
|
||||||
return new MonthTimeStepper._internal(
|
return MonthTimeStepper._internal(dateTimeFactory, allowedTickIncrements);
|
||||||
dateTimeFactory, allowedTickIncrements);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import 'base_time_stepper.dart' show BaseTimeStepper;
|
|||||||
|
|
||||||
/// Year stepper.
|
/// Year stepper.
|
||||||
class YearTimeStepper extends BaseTimeStepper {
|
class YearTimeStepper extends BaseTimeStepper {
|
||||||
static const _defaultIncrements = const [1, 2, 5, 10, 50, 100, 500, 1000];
|
static const _defaultIncrements = [1, 2, 5, 10, 50, 100, 500, 1000];
|
||||||
|
|
||||||
final List<int> _allowedTickIncrements;
|
final List<int> _allowedTickIncrements;
|
||||||
|
|
||||||
@@ -37,8 +37,7 @@ class YearTimeStepper extends BaseTimeStepper {
|
|||||||
// All increments must be > 0.
|
// All increments must be > 0.
|
||||||
assert(allowedTickIncrements.any((increment) => increment <= 0) == false);
|
assert(allowedTickIncrements.any((increment) => increment <= 0) == false);
|
||||||
|
|
||||||
return new YearTimeStepper._internal(
|
return YearTimeStepper._internal(dateTimeFactory, allowedTickIncrements);
|
||||||
dateTimeFactory, allowedTickIncrements);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -55,14 +55,14 @@ class NumericCartesianChart extends CartesianChart<num> {
|
|||||||
: super(
|
: super(
|
||||||
vertical: vertical,
|
vertical: vertical,
|
||||||
layoutConfig: layoutConfig,
|
layoutConfig: layoutConfig,
|
||||||
domainAxis: new NumericAxis(),
|
domainAxis: NumericAxis(),
|
||||||
primaryMeasureAxis: primaryMeasureAxis,
|
primaryMeasureAxis: primaryMeasureAxis,
|
||||||
secondaryMeasureAxis: secondaryMeasureAxis,
|
secondaryMeasureAxis: secondaryMeasureAxis,
|
||||||
disjointMeasureAxes: disjointMeasureAxes);
|
disjointMeasureAxes: disjointMeasureAxes);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void initDomainAxis() {
|
void initDomainAxis() {
|
||||||
_domainAxis.tickDrawStrategy = new SmallTickRendererSpec<num>()
|
_domainAxis.tickDrawStrategy = SmallTickRendererSpec<num>()
|
||||||
.createDrawStrategy(context, graphicsFactory);
|
.createDrawStrategy(context, graphicsFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ class OrdinalCartesianChart extends CartesianChart<String> {
|
|||||||
: super(
|
: super(
|
||||||
vertical: vertical,
|
vertical: vertical,
|
||||||
layoutConfig: layoutConfig,
|
layoutConfig: layoutConfig,
|
||||||
domainAxis: new OrdinalAxis(),
|
domainAxis: OrdinalAxis(),
|
||||||
primaryMeasureAxis: primaryMeasureAxis,
|
primaryMeasureAxis: primaryMeasureAxis,
|
||||||
secondaryMeasureAxis: secondaryMeasureAxis,
|
secondaryMeasureAxis: secondaryMeasureAxis,
|
||||||
disjointMeasureAxes: disjointMeasureAxes);
|
disjointMeasureAxes: disjointMeasureAxes);
|
||||||
@@ -85,17 +85,17 @@ class OrdinalCartesianChart extends CartesianChart<String> {
|
|||||||
@protected
|
@protected
|
||||||
void initDomainAxis() {
|
void initDomainAxis() {
|
||||||
_domainAxis
|
_domainAxis
|
||||||
..tickDrawStrategy = new SmallTickRendererSpec<String>()
|
..tickDrawStrategy = SmallTickRendererSpec<String>()
|
||||||
.createDrawStrategy(context, graphicsFactory);
|
.createDrawStrategy(context, graphicsFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class CartesianChart<D> extends BaseChart<D> {
|
abstract class CartesianChart<D> extends BaseChart<D> {
|
||||||
static final _defaultLayoutConfig = new LayoutConfig(
|
static final _defaultLayoutConfig = LayoutConfig(
|
||||||
topSpec: new MarginSpec.fromPixel(minPixel: 20),
|
topSpec: MarginSpec.fromPixel(minPixel: 20),
|
||||||
bottomSpec: new MarginSpec.fromPixel(minPixel: 20),
|
bottomSpec: MarginSpec.fromPixel(minPixel: 20),
|
||||||
leftSpec: new MarginSpec.fromPixel(minPixel: 20),
|
leftSpec: MarginSpec.fromPixel(minPixel: 20),
|
||||||
rightSpec: new MarginSpec.fromPixel(minPixel: 20),
|
rightSpec: MarginSpec.fromPixel(minPixel: 20),
|
||||||
);
|
);
|
||||||
|
|
||||||
bool vertical;
|
bool vertical;
|
||||||
@@ -148,8 +148,8 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
: vertical = vertical ?? true,
|
: vertical = vertical ?? true,
|
||||||
// [domainAxis] will be set to the new axis in [configurationChanged].
|
// [domainAxis] will be set to the new axis in [configurationChanged].
|
||||||
_newDomainAxis = domainAxis,
|
_newDomainAxis = domainAxis,
|
||||||
_primaryMeasureAxis = primaryMeasureAxis ?? new NumericAxis(),
|
_primaryMeasureAxis = primaryMeasureAxis ?? NumericAxis(),
|
||||||
_secondaryMeasureAxis = secondaryMeasureAxis ?? new NumericAxis(),
|
_secondaryMeasureAxis = secondaryMeasureAxis ?? NumericAxis(),
|
||||||
_disjointMeasureAxes = disjointMeasureAxes ?? <String, NumericAxis>{},
|
_disjointMeasureAxes = disjointMeasureAxes ?? <String, NumericAxis>{},
|
||||||
super(layoutConfig: layoutConfig ?? _defaultLayoutConfig) {
|
super(layoutConfig: layoutConfig ?? _defaultLayoutConfig) {
|
||||||
// As a convenience for chart configuration, set the paint order on any axis
|
// As a convenience for chart configuration, set the paint order on any axis
|
||||||
@@ -157,7 +157,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
_primaryMeasureAxis.layoutPaintOrder ??= LayoutViewPaintOrder.measureAxis;
|
_primaryMeasureAxis.layoutPaintOrder ??= LayoutViewPaintOrder.measureAxis;
|
||||||
_secondaryMeasureAxis.layoutPaintOrder ??= LayoutViewPaintOrder.measureAxis;
|
_secondaryMeasureAxis.layoutPaintOrder ??= LayoutViewPaintOrder.measureAxis;
|
||||||
|
|
||||||
_disjointMeasureAxes.forEach((String axisId, NumericAxis axis) {
|
_disjointMeasureAxes.forEach((axisId, axis) {
|
||||||
axis.layoutPaintOrder ??= LayoutViewPaintOrder.measureAxis;
|
axis.layoutPaintOrder ??= LayoutViewPaintOrder.measureAxis;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -166,17 +166,16 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
super.init(context, graphicsFactory);
|
super.init(context, graphicsFactory);
|
||||||
|
|
||||||
_primaryMeasureAxis.context = context;
|
_primaryMeasureAxis.context = context;
|
||||||
_primaryMeasureAxis.tickDrawStrategy = new GridlineRendererSpec<num>()
|
_primaryMeasureAxis.tickDrawStrategy = GridlineRendererSpec<num>()
|
||||||
.createDrawStrategy(context, graphicsFactory);
|
.createDrawStrategy(context, graphicsFactory);
|
||||||
|
|
||||||
_secondaryMeasureAxis.context = context;
|
_secondaryMeasureAxis.context = context;
|
||||||
_secondaryMeasureAxis.tickDrawStrategy = new GridlineRendererSpec<num>()
|
_secondaryMeasureAxis.tickDrawStrategy = GridlineRendererSpec<num>()
|
||||||
.createDrawStrategy(context, graphicsFactory);
|
.createDrawStrategy(context, graphicsFactory);
|
||||||
|
|
||||||
_disjointMeasureAxes.forEach((String axisId, NumericAxis axis) {
|
_disjointMeasureAxes.forEach((axisId, axis) {
|
||||||
axis.context = context;
|
axis.context = context;
|
||||||
axis.tickDrawStrategy =
|
axis.tickDrawStrategy = NoneDrawStrategy<num>(context, graphicsFactory);
|
||||||
new NoneDrawStrategy<num>(context, graphicsFactory);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,7 +276,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
/// A [LinkedHashMap] is used to ensure consistent ordering when painting the
|
/// A [LinkedHashMap] is used to ensure consistent ordering when painting the
|
||||||
/// axes.
|
/// axes.
|
||||||
set disjointMeasureAxisSpecs(LinkedHashMap<String, AxisSpec> axisSpecs) {
|
set disjointMeasureAxisSpecs(LinkedHashMap<String, AxisSpec> axisSpecs) {
|
||||||
axisSpecs.forEach((String axisId, AxisSpec axisSpec) {
|
axisSpecs.forEach((axisId, axisSpec) {
|
||||||
axisSpec.configure(
|
axisSpec.configure(
|
||||||
_disjointMeasureAxes[axisId], context, graphicsFactory);
|
_disjointMeasureAxes[axisId], context, graphicsFactory);
|
||||||
});
|
});
|
||||||
@@ -299,7 +298,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
SeriesRenderer<D> makeDefaultRenderer() {
|
SeriesRenderer<D> makeDefaultRenderer() {
|
||||||
return new BarRenderer()..rendererId = SeriesRenderer.defaultRendererId;
|
return BarRenderer()..rendererId = SeriesRenderer.defaultRendererId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -331,7 +330,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add all disjoint axis views so that their range will be configured.
|
// Add all disjoint axis views so that their range will be configured.
|
||||||
_disjointMeasureAxes.forEach((String axisId, NumericAxis axis) {
|
_disjointMeasureAxes.forEach((axisId, axis) {
|
||||||
addView(axis);
|
addView(axis);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -340,7 +339,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
_primaryMeasureAxis.resetDomains();
|
_primaryMeasureAxis.resetDomains();
|
||||||
_secondaryMeasureAxis.resetDomains();
|
_secondaryMeasureAxis.resetDomains();
|
||||||
|
|
||||||
_disjointMeasureAxes.forEach((String axisId, NumericAxis axis) {
|
_disjointMeasureAxes.forEach((axisId, axis) {
|
||||||
axis.resetDomains();
|
axis.resetDomains();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -363,7 +362,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
: AxisOrientation.right)
|
: AxisOrientation.right)
|
||||||
..reverseOutputRange = flipVerticalAxisOutput;
|
..reverseOutputRange = flipVerticalAxisOutput;
|
||||||
|
|
||||||
_disjointMeasureAxes.forEach((String axisId, NumericAxis axis) {
|
_disjointMeasureAxes.forEach((axisId, axis) {
|
||||||
axis
|
axis
|
||||||
..axisOrientation = (reverseAxisDirection
|
..axisOrientation = (reverseAxisDirection
|
||||||
? AxisOrientation.left
|
? AxisOrientation.left
|
||||||
@@ -385,7 +384,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
..axisOrientation = AxisOrientation.top
|
..axisOrientation = AxisOrientation.top
|
||||||
..reverseOutputRange = reverseAxisDirection;
|
..reverseOutputRange = reverseAxisDirection;
|
||||||
|
|
||||||
_disjointMeasureAxes.forEach((String axisId, NumericAxis axis) {
|
_disjointMeasureAxes.forEach((axisId, axis) {
|
||||||
axis
|
axis
|
||||||
..axisOrientation = AxisOrientation.top
|
..axisOrientation = AxisOrientation.top
|
||||||
..reverseOutputRange = reverseAxisDirection;
|
..reverseOutputRange = reverseAxisDirection;
|
||||||
@@ -394,8 +393,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
|
|
||||||
// Have each renderer configure the axes with their domain and measure
|
// Have each renderer configure the axes with their domain and measure
|
||||||
// values.
|
// values.
|
||||||
rendererToSeriesList
|
rendererToSeriesList.forEach((rendererId, seriesList) {
|
||||||
.forEach((String rendererId, List<MutableSeries<D>> seriesList) {
|
|
||||||
getSeriesRenderer(rendererId).configureDomainAxes(seriesList);
|
getSeriesRenderer(rendererId).configureDomainAxes(seriesList);
|
||||||
getSeriesRenderer(rendererId).configureMeasureAxes(seriesList);
|
getSeriesRenderer(rendererId).configureMeasureAxes(seriesList);
|
||||||
});
|
});
|
||||||
@@ -416,7 +414,7 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
_secondaryMeasureAxis.updateTicks();
|
_secondaryMeasureAxis.updateTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
_disjointMeasureAxes.forEach((String axisId, NumericAxis axis) {
|
_disjointMeasureAxes.forEach((axisId, axis) {
|
||||||
axis.updateTicks();
|
axis.updateTicks();
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -449,11 +447,11 @@ abstract class CartesianChart<D> extends BaseChart<D> {
|
|||||||
final measurePosition =
|
final measurePosition =
|
||||||
series.getAttr(measureAxisKey).getLocation(measure);
|
series.getAttr(measureAxisKey).getLocation(measure);
|
||||||
|
|
||||||
final chartPosition = new Point<double>(
|
final chartPosition = Point<double>(
|
||||||
vertical ? domainPosition : measurePosition,
|
vertical ? domainPosition : measurePosition,
|
||||||
vertical ? measurePosition : domainPosition);
|
vertical ? measurePosition : domainPosition);
|
||||||
|
|
||||||
entries.add(new DatumDetails(
|
entries.add(DatumDetails(
|
||||||
datum: datum,
|
datum: datum,
|
||||||
domain: domain,
|
domain: domain,
|
||||||
measure: measure,
|
measure: measure,
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ abstract class BaseCartesianRenderer<D> extends BaseSeriesRenderer<D>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void configureDomainAxes(List<MutableSeries<D>> seriesList) {
|
void configureDomainAxes(List<MutableSeries<D>> seriesList) {
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
if (series.data.isEmpty) {
|
if (series.data.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -100,7 +100,7 @@ abstract class BaseCartesianRenderer<D> extends BaseSeriesRenderer<D>
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void configureMeasureAxes(List<MutableSeries<D>> seriesList) {
|
void configureMeasureAxes(List<MutableSeries<D>> seriesList) {
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
if (series.data.isEmpty) {
|
if (series.data.isEmpty) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ abstract class BaseChart<D> {
|
|||||||
/// initial draw cycle (e.g. a [Legend] may hide some series).
|
/// initial draw cycle (e.g. a [Legend] may hide some series).
|
||||||
List<MutableSeries<D>> _currentSeriesList;
|
List<MutableSeries<D>> _currentSeriesList;
|
||||||
|
|
||||||
Set<String> _usingRenderers = new Set<String>();
|
Set<String> _usingRenderers = Set<String>();
|
||||||
Map<String, List<MutableSeries<D>>> _rendererToSeriesList;
|
Map<String, List<MutableSeries<D>>> _rendererToSeriesList;
|
||||||
|
|
||||||
final _seriesRenderers = <String, SeriesRenderer<D>>{};
|
final _seriesRenderers = <String, SeriesRenderer<D>>{};
|
||||||
@@ -83,7 +83,7 @@ abstract class BaseChart<D> {
|
|||||||
/// that does something with tap events, such as "click to select data."
|
/// that does something with tap events, such as "click to select data."
|
||||||
bool get isTappable => _behaviorTappableMap.isNotEmpty;
|
bool get isTappable => _behaviorTappableMap.isNotEmpty;
|
||||||
|
|
||||||
final _gestureProxy = new ProxyGestureListener();
|
final _gestureProxy = ProxyGestureListener();
|
||||||
|
|
||||||
final _selectionModels = <SelectionModelType, MutableSelectionModel<D>>{};
|
final _selectionModels = <SelectionModelType, MutableSelectionModel<D>>{};
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ abstract class BaseChart<D> {
|
|||||||
final _lifecycleListeners = <LifecycleListener<D>>[];
|
final _lifecycleListeners = <LifecycleListener<D>>[];
|
||||||
|
|
||||||
BaseChart({LayoutConfig layoutConfig}) {
|
BaseChart({LayoutConfig layoutConfig}) {
|
||||||
_layoutManager = new LayoutManagerImpl(config: layoutConfig);
|
_layoutManager = LayoutManagerImpl(config: layoutConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(ChartContext context, GraphicsFactory graphicsFactory) {
|
void init(ChartContext context, GraphicsFactory graphicsFactory) {
|
||||||
@@ -109,8 +109,8 @@ abstract class BaseChart<D> {
|
|||||||
if (this.graphicsFactory != graphicsFactory) {
|
if (this.graphicsFactory != graphicsFactory) {
|
||||||
this.graphicsFactory = graphicsFactory;
|
this.graphicsFactory = graphicsFactory;
|
||||||
|
|
||||||
_layoutManager.applyToViews(
|
_layoutManager
|
||||||
(LayoutView view) => view.graphicsFactory = graphicsFactory);
|
.applyToViews((view) => view.graphicsFactory = graphicsFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
configurationChanged();
|
configurationChanged();
|
||||||
@@ -154,8 +154,7 @@ abstract class BaseChart<D> {
|
|||||||
/// Returns MutableSelectionModel for the given type. Lazy creates one upon first
|
/// Returns MutableSelectionModel for the given type. Lazy creates one upon first
|
||||||
/// request.
|
/// request.
|
||||||
MutableSelectionModel<D> getSelectionModel(SelectionModelType type) {
|
MutableSelectionModel<D> getSelectionModel(SelectionModelType type) {
|
||||||
return _selectionModels.putIfAbsent(
|
return _selectionModels.putIfAbsent(type, () => MutableSelectionModel<D>());
|
||||||
type, () => new MutableSelectionModel<D>());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of datum details from selection model of [type].
|
/// Returns a list of datum details from selection model of [type].
|
||||||
@@ -206,10 +205,9 @@ abstract class BaseChart<D> {
|
|||||||
SeriesRenderer<D> makeDefaultRenderer();
|
SeriesRenderer<D> makeDefaultRenderer();
|
||||||
|
|
||||||
bool pointWithinRenderer(Point<double> chartPosition) {
|
bool pointWithinRenderer(Point<double> chartPosition) {
|
||||||
return _usingRenderers.any((String rendererId) =>
|
return _usingRenderers.any((rendererId) => getSeriesRenderer(rendererId)
|
||||||
getSeriesRenderer(rendererId)
|
.componentBounds
|
||||||
.componentBounds
|
.containsPoint(chartPosition));
|
||||||
.containsPoint(chartPosition));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the datum details that are nearest to the given [drawAreaPoint].
|
/// Retrieves the datum details that are nearest to the given [drawAreaPoint].
|
||||||
@@ -229,13 +227,13 @@ abstract class BaseChart<D> {
|
|||||||
selectAcrossAllDrawAreaComponents ? drawableLayoutAreaBounds : null;
|
selectAcrossAllDrawAreaComponents ? drawableLayoutAreaBounds : null;
|
||||||
|
|
||||||
final details = <DatumDetails<D>>[];
|
final details = <DatumDetails<D>>[];
|
||||||
_usingRenderers.forEach((String rendererId) {
|
_usingRenderers.forEach((rendererId) {
|
||||||
details.addAll(getSeriesRenderer(rendererId)
|
details.addAll(getSeriesRenderer(rendererId)
|
||||||
.getNearestDatumDetailPerSeries(
|
.getNearestDatumDetailPerSeries(
|
||||||
drawAreaPoint, selectNearestByDomain, boundsOverride));
|
drawAreaPoint, selectNearestByDomain, boundsOverride));
|
||||||
});
|
});
|
||||||
|
|
||||||
details.sort((DatumDetails<D> a, DatumDetails<D> b) {
|
details.sort((a, b) {
|
||||||
// Sort so that the nearest one is first.
|
// Sort so that the nearest one is first.
|
||||||
// Special sort, sort by domain distance first, then by measure distance.
|
// Special sort, sort by domain distance first, then by measure distance.
|
||||||
if (selectNearestByDomain) {
|
if (selectNearestByDomain) {
|
||||||
@@ -356,7 +354,7 @@ abstract class BaseChart<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of behaviors that have been added.
|
/// Returns a list of behaviors that have been added.
|
||||||
List<ChartBehavior<D>> get behaviors => new List.unmodifiable(_behaviorStack);
|
List<ChartBehavior<D>> get behaviors => List.unmodifiable(_behaviorStack);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Layout methods
|
// Layout methods
|
||||||
@@ -423,7 +421,7 @@ abstract class BaseChart<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var processedSeriesList =
|
var processedSeriesList =
|
||||||
new List<MutableSeries<D>>.from(seriesList.map(makeSeries));
|
List<MutableSeries<D>>.from(seriesList.map(makeSeries));
|
||||||
|
|
||||||
// Allow listeners to manipulate the seriesList.
|
// Allow listeners to manipulate the seriesList.
|
||||||
fireOnDraw(processedSeriesList);
|
fireOnDraw(processedSeriesList);
|
||||||
@@ -464,9 +462,8 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
void drawInternal(List<MutableSeries<D>> seriesList,
|
void drawInternal(List<MutableSeries<D>> seriesList,
|
||||||
{bool skipAnimation, bool skipLayout}) {
|
{bool skipAnimation, bool skipLayout}) {
|
||||||
seriesList = seriesList
|
seriesList =
|
||||||
.map((MutableSeries<D> series) => new MutableSeries<D>.clone(series))
|
seriesList.map((series) => MutableSeries<D>.clone(series)).toList();
|
||||||
.toList();
|
|
||||||
|
|
||||||
// TODO: Handle exiting renderers.
|
// TODO: Handle exiting renderers.
|
||||||
_animationsTemporarilyDisabled = skipAnimation;
|
_animationsTemporarilyDisabled = skipAnimation;
|
||||||
@@ -487,7 +484,7 @@ abstract class BaseChart<D> {
|
|||||||
List<MutableSeries<D>> get currentSeriesList => _currentSeriesList;
|
List<MutableSeries<D>> get currentSeriesList => _currentSeriesList;
|
||||||
|
|
||||||
MutableSeries<D> makeSeries(Series<dynamic, D> series) {
|
MutableSeries<D> makeSeries(Series<dynamic, D> series) {
|
||||||
final s = new MutableSeries<D>(series);
|
final s = MutableSeries<D>(series);
|
||||||
|
|
||||||
// Setup the Renderer
|
// Setup the Renderer
|
||||||
final rendererId =
|
final rendererId =
|
||||||
@@ -505,14 +502,13 @@ abstract class BaseChart<D> {
|
|||||||
// Build map of rendererIds to SeriesLists. This map can't be re-used later
|
// Build map of rendererIds to SeriesLists. This map can't be re-used later
|
||||||
// in the preprocessSeries call because some behaviors might alter the
|
// in the preprocessSeries call because some behaviors might alter the
|
||||||
// seriesList.
|
// seriesList.
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
String rendererId = series.getAttr(rendererIdKey);
|
String rendererId = series.getAttr(rendererIdKey);
|
||||||
rendererToSeriesList.putIfAbsent(rendererId, () => []).add(series);
|
rendererToSeriesList.putIfAbsent(rendererId, () => []).add(series);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Have each renderer add missing color functions to their seriesLists.
|
// Have each renderer add missing color functions to their seriesLists.
|
||||||
rendererToSeriesList
|
rendererToSeriesList.forEach((rendererId, seriesList) {
|
||||||
.forEach((String rendererId, List<MutableSeries<D>> seriesList) {
|
|
||||||
getSeriesRenderer(rendererId).configureSeries(seriesList);
|
getSeriesRenderer(rendererId).configureSeries(seriesList);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -525,10 +521,10 @@ abstract class BaseChart<D> {
|
|||||||
Map<String, List<MutableSeries<D>>> rendererToSeriesList = {};
|
Map<String, List<MutableSeries<D>>> rendererToSeriesList = {};
|
||||||
|
|
||||||
var unusedRenderers = _usingRenderers;
|
var unusedRenderers = _usingRenderers;
|
||||||
_usingRenderers = new Set<String>();
|
_usingRenderers = Set<String>();
|
||||||
|
|
||||||
// Build map of rendererIds to SeriesLists.
|
// Build map of rendererIds to SeriesLists.
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
String rendererId = series.getAttr(rendererIdKey);
|
String rendererId = series.getAttr(rendererIdKey);
|
||||||
rendererToSeriesList.putIfAbsent(rendererId, () => []).add(series);
|
rendererToSeriesList.putIfAbsent(rendererId, () => []).add(series);
|
||||||
|
|
||||||
@@ -538,11 +534,10 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
// Allow unused renderers to render out content.
|
// Allow unused renderers to render out content.
|
||||||
unusedRenderers
|
unusedRenderers
|
||||||
.forEach((String rendererId) => rendererToSeriesList[rendererId] = []);
|
.forEach((rendererId) => rendererToSeriesList[rendererId] = []);
|
||||||
|
|
||||||
// Have each renderer preprocess their seriesLists.
|
// Have each renderer preprocess their seriesLists.
|
||||||
rendererToSeriesList
|
rendererToSeriesList.forEach((rendererId, seriesList) {
|
||||||
.forEach((String rendererId, List<MutableSeries<D>> seriesList) {
|
|
||||||
getSeriesRenderer(rendererId).preprocessSeries(seriesList);
|
getSeriesRenderer(rendererId).preprocessSeries(seriesList);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -555,8 +550,7 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
void onPostLayout(Map<String, List<MutableSeries<D>>> rendererToSeriesList) {
|
void onPostLayout(Map<String, List<MutableSeries<D>>> rendererToSeriesList) {
|
||||||
// Update each renderer with
|
// Update each renderer with
|
||||||
rendererToSeriesList
|
rendererToSeriesList.forEach((rendererId, seriesList) {
|
||||||
.forEach((String rendererId, List<MutableSeries<D>> seriesList) {
|
|
||||||
getSeriesRenderer(rendererId).update(seriesList, animatingThisDraw);
|
getSeriesRenderer(rendererId).update(seriesList, animatingThisDraw);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -574,7 +568,7 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
void paint(ChartCanvas canvas) {
|
void paint(ChartCanvas canvas) {
|
||||||
canvas.drawingView = 'BaseView';
|
canvas.drawingView = 'BaseView';
|
||||||
_layoutManager.paintOrderedViews.forEach((LayoutView view) {
|
_layoutManager.paintOrderedViews.forEach((view) {
|
||||||
canvas.drawingView = view.runtimeType.toString();
|
canvas.drawingView = view.runtimeType.toString();
|
||||||
view.paint(canvas, animatingThisDraw ? animationPercent : 1.0);
|
view.paint(canvas, animatingThisDraw ? animationPercent : 1.0);
|
||||||
});
|
});
|
||||||
@@ -594,7 +588,7 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
@protected
|
@protected
|
||||||
fireOnDraw(List<MutableSeries<D>> seriesList) {
|
fireOnDraw(List<MutableSeries<D>> seriesList) {
|
||||||
_lifecycleListeners.forEach((LifecycleListener<D> listener) {
|
_lifecycleListeners.forEach((listener) {
|
||||||
if (listener.onData != null) {
|
if (listener.onData != null) {
|
||||||
listener.onData(seriesList);
|
listener.onData(seriesList);
|
||||||
}
|
}
|
||||||
@@ -603,7 +597,7 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
@protected
|
@protected
|
||||||
fireOnPreprocess(List<MutableSeries<D>> seriesList) {
|
fireOnPreprocess(List<MutableSeries<D>> seriesList) {
|
||||||
_lifecycleListeners.forEach((LifecycleListener<D> listener) {
|
_lifecycleListeners.forEach((listener) {
|
||||||
if (listener.onPreprocess != null) {
|
if (listener.onPreprocess != null) {
|
||||||
listener.onPreprocess(seriesList);
|
listener.onPreprocess(seriesList);
|
||||||
}
|
}
|
||||||
@@ -612,7 +606,7 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
@protected
|
@protected
|
||||||
fireOnPostprocess(List<MutableSeries<D>> seriesList) {
|
fireOnPostprocess(List<MutableSeries<D>> seriesList) {
|
||||||
_lifecycleListeners.forEach((LifecycleListener<D> listener) {
|
_lifecycleListeners.forEach((listener) {
|
||||||
if (listener.onPostprocess != null) {
|
if (listener.onPostprocess != null) {
|
||||||
listener.onPostprocess(seriesList);
|
listener.onPostprocess(seriesList);
|
||||||
}
|
}
|
||||||
@@ -621,7 +615,7 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
@protected
|
@protected
|
||||||
fireOnAxisConfigured() {
|
fireOnAxisConfigured() {
|
||||||
_lifecycleListeners.forEach((LifecycleListener<D> listener) {
|
_lifecycleListeners.forEach((listener) {
|
||||||
if (listener.onAxisConfigured != null) {
|
if (listener.onAxisConfigured != null) {
|
||||||
listener.onAxisConfigured();
|
listener.onAxisConfigured();
|
||||||
}
|
}
|
||||||
@@ -630,7 +624,7 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
@protected
|
@protected
|
||||||
fireOnPostrender(ChartCanvas canvas) {
|
fireOnPostrender(ChartCanvas canvas) {
|
||||||
_lifecycleListeners.forEach((LifecycleListener<D> listener) {
|
_lifecycleListeners.forEach((listener) {
|
||||||
if (listener.onPostrender != null) {
|
if (listener.onPostrender != null) {
|
||||||
listener.onPostrender(canvas);
|
listener.onPostrender(canvas);
|
||||||
}
|
}
|
||||||
@@ -639,7 +633,7 @@ abstract class BaseChart<D> {
|
|||||||
|
|
||||||
@protected
|
@protected
|
||||||
fireOnAnimationComplete() {
|
fireOnAnimationComplete() {
|
||||||
_lifecycleListeners.forEach((LifecycleListener<D> listener) {
|
_lifecycleListeners.forEach((listener) {
|
||||||
if (listener.onAnimationComplete != null) {
|
if (listener.onAnimationComplete != null) {
|
||||||
listener.onAnimationComplete();
|
listener.onAnimationComplete();
|
||||||
}
|
}
|
||||||
@@ -654,8 +648,8 @@ abstract class BaseChart<D> {
|
|||||||
}
|
}
|
||||||
_behaviorStack.clear();
|
_behaviorStack.clear();
|
||||||
_behaviorRoleMap.clear();
|
_behaviorRoleMap.clear();
|
||||||
_selectionModels.values.forEach((MutableSelectionModel selectionModel) =>
|
_selectionModels.values
|
||||||
selectionModel.clearAllListeners());
|
.forEach((selectionModel) => selectionModel.clearAllListeners());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -707,6 +701,7 @@ class LifecycleListener<D> {
|
|||||||
this.onAnimationComplete});
|
this.onAnimationComplete});
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef LifecycleSeriesListCallback<D>(List<MutableSeries<D>> seriesList);
|
typedef LifecycleSeriesListCallback<D> = Function(
|
||||||
typedef LifecycleCanvasCallback(ChartCanvas canvas);
|
List<MutableSeries<D>> seriesList);
|
||||||
typedef LifecycleEmptyCallback();
|
typedef LifecycleCanvasCallback = Function(ChartCanvas canvas);
|
||||||
|
typedef LifecycleEmptyCallback = Function();
|
||||||
|
|||||||
@@ -57,10 +57,10 @@ abstract class A11yExploreBehavior<D> implements ChartBehavior<D> {
|
|||||||
|
|
||||||
switch (exploreModeTrigger) {
|
switch (exploreModeTrigger) {
|
||||||
case ExploreModeTrigger.pressHold:
|
case ExploreModeTrigger.pressHold:
|
||||||
_listener = new GestureListener(onLongPress: _toggleExploreMode);
|
_listener = GestureListener(onLongPress: _toggleExploreMode);
|
||||||
break;
|
break;
|
||||||
case ExploreModeTrigger.tap:
|
case ExploreModeTrigger.tap:
|
||||||
_listener = new GestureListener(onTap: _toggleExploreMode);
|
_listener = GestureListener(onTap: _toggleExploreMode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
|
|
||||||
import 'dart:math' show Rectangle;
|
import 'dart:math' show Rectangle;
|
||||||
|
|
||||||
typedef void OnFocus();
|
typedef OnFocus = void Function();
|
||||||
|
|
||||||
/// Container for accessibility data.
|
/// Container for accessibility data.
|
||||||
class A11yNode {
|
class A11yNode {
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ import 'a11y_explore_behavior.dart'
|
|||||||
import 'a11y_node.dart' show A11yNode, OnFocus;
|
import 'a11y_node.dart' show A11yNode, OnFocus;
|
||||||
|
|
||||||
/// Returns a string for a11y vocalization from a list of series datum.
|
/// Returns a string for a11y vocalization from a list of series datum.
|
||||||
typedef String VocalizationCallback<D>(List<SeriesDatum<D>> seriesDatums);
|
typedef VocalizationCallback<D> = String Function(
|
||||||
|
List<SeriesDatum<D>> seriesDatums);
|
||||||
|
|
||||||
/// A simple vocalization that returns the domain value to string.
|
/// A simple vocalization that returns the domain value to string.
|
||||||
String domainVocalization<D>(List<SeriesDatum<D>> seriesDatums) {
|
String domainVocalization<D>(List<SeriesDatum<D>> seriesDatums) {
|
||||||
@@ -58,8 +59,7 @@ class DomainA11yExploreBehavior<D> extends A11yExploreBehavior<D> {
|
|||||||
minimumWidth: minimumWidth,
|
minimumWidth: minimumWidth,
|
||||||
exploreModeEnabledAnnouncement: exploreModeEnabledAnnouncement,
|
exploreModeEnabledAnnouncement: exploreModeEnabledAnnouncement,
|
||||||
exploreModeDisabledAnnouncement: exploreModeDisabledAnnouncement) {
|
exploreModeDisabledAnnouncement: exploreModeDisabledAnnouncement) {
|
||||||
_lifecycleListener =
|
_lifecycleListener = LifecycleListener<D>(onPostprocess: _updateSeriesList);
|
||||||
new LifecycleListener<D>(onPostprocess: _updateSeriesList);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -77,11 +77,11 @@ class DomainA11yExploreBehavior<D> extends A11yExploreBehavior<D> {
|
|||||||
D domain = series.domainFn(index);
|
D domain = series.domainFn(index);
|
||||||
|
|
||||||
domainSeriesDatum[domain] ??= <SeriesDatum<D>>[];
|
domainSeriesDatum[domain] ??= <SeriesDatum<D>>[];
|
||||||
domainSeriesDatum[domain].add(new SeriesDatum<D>(series, datum));
|
domainSeriesDatum[domain].add(SeriesDatum<D>(series, datum));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
domainSeriesDatum.forEach((D domain, List<SeriesDatum<D>> seriesDatums) {
|
domainSeriesDatum.forEach((domain, seriesDatums) {
|
||||||
final a11yDescription = _vocalizationCallback(seriesDatums);
|
final a11yDescription = _vocalizationCallback(seriesDatums);
|
||||||
|
|
||||||
final firstSeries = seriesDatums.first.series;
|
final firstSeries = seriesDatums.first.series;
|
||||||
@@ -93,7 +93,7 @@ class DomainA11yExploreBehavior<D> extends A11yExploreBehavior<D> {
|
|||||||
? domainAxis.stepSize
|
? domainAxis.stepSize
|
||||||
: minimumWidth;
|
: minimumWidth;
|
||||||
|
|
||||||
nodes.add(new _DomainA11yNode(a11yDescription,
|
nodes.add(_DomainA11yNode(a11yDescription,
|
||||||
location: location,
|
location: location,
|
||||||
stepSize: stepSize,
|
stepSize: stepSize,
|
||||||
chartDrawBounds: _chart.drawAreaBounds,
|
chartDrawBounds: _chart.drawAreaBounds,
|
||||||
@@ -134,7 +134,7 @@ class DomainA11yExploreBehavior<D> extends A11yExploreBehavior<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get role => 'DomainA11yExplore-${exploreModeTrigger}';
|
String get role => 'DomainA11yExplore-$exploreModeTrigger';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A11yNode with domain specific information.
|
/// A11yNode with domain specific information.
|
||||||
@@ -157,16 +157,16 @@ class _DomainA11yNode extends A11yNode implements Comparable<_DomainA11yNode> {
|
|||||||
var top = chartDrawBounds.top;
|
var top = chartDrawBounds.top;
|
||||||
var width = stepSize.round();
|
var width = stepSize.round();
|
||||||
var height = chartDrawBounds.height;
|
var height = chartDrawBounds.height;
|
||||||
boundingBox = new Rectangle(left, top, width, height);
|
boundingBox = Rectangle(left, top, width, height);
|
||||||
} else {
|
} else {
|
||||||
var left = chartDrawBounds.left;
|
var left = chartDrawBounds.left;
|
||||||
var top = (location - stepSize / 2).round();
|
var top = (location - stepSize / 2).round();
|
||||||
var width = chartDrawBounds.width;
|
var width = chartDrawBounds.width;
|
||||||
var height = stepSize.round();
|
var height = stepSize.round();
|
||||||
boundingBox = new Rectangle(left, top, width, height);
|
boundingBox = Rectangle(left, top, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new _DomainA11yNode._internal(label, boundingBox,
|
return _DomainA11yNode._internal(label, boundingBox,
|
||||||
location: location,
|
location: location,
|
||||||
isRtl: isRtl,
|
isRtl: isRtl,
|
||||||
renderVertically: renderVertically,
|
renderVertically: renderVertically,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import '../../behavior/chart_behavior.dart' show ChartBehavior;
|
|||||||
import '../../processed_series.dart' show MutableSeries;
|
import '../../processed_series.dart' show MutableSeries;
|
||||||
|
|
||||||
const percentInjectedKey =
|
const percentInjectedKey =
|
||||||
const AttributeKey<bool>('PercentInjector.percentInjected');
|
AttributeKey<bool>('PercentInjector.percentInjected');
|
||||||
|
|
||||||
/// Chart behavior that can inject series or domain percentages into each datum.
|
/// Chart behavior that can inject series or domain percentages into each datum.
|
||||||
///
|
///
|
||||||
@@ -49,7 +49,7 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
PercentInjector({this.totalType = PercentInjectorTotalType.domain}) {
|
PercentInjector({this.totalType = PercentInjectorTotalType.domain}) {
|
||||||
// Set up chart draw cycle listeners.
|
// Set up chart draw cycle listeners.
|
||||||
_lifecycleListener =
|
_lifecycleListener =
|
||||||
new LifecycleListener<D>(onPreprocess: _preProcess, onData: _onData);
|
LifecycleListener<D>(onPreprocess: _preProcess, onData: _onData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -65,7 +65,7 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
/// Resets the state of the behavior when new data is drawn on the chart.
|
/// Resets the state of the behavior when new data is drawn on the chart.
|
||||||
void _onData(List<MutableSeries<D>> seriesList) {
|
void _onData(List<MutableSeries<D>> seriesList) {
|
||||||
// Reset tracking of percentage injection for new data.
|
// Reset tracking of percentage injection for new data.
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
series.setAttr(percentInjectedKey, false);
|
series.setAttr(percentInjectedKey, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -77,7 +77,7 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
/// the [seriesList] between chart redraws.
|
/// the [seriesList] between chart redraws.
|
||||||
void _preProcess(List<MutableSeries<D>> seriesList) {
|
void _preProcess(List<MutableSeries<D>> seriesList) {
|
||||||
var percentInjected = true;
|
var percentInjected = true;
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
percentInjected = percentInjected && series.getAttr(percentInjectedKey);
|
percentInjected = percentInjected && series.getAttr(percentInjectedKey);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -95,7 +95,7 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
|
|
||||||
// Walk the series and compute the domain total. Series total is
|
// Walk the series and compute the domain total. Series total is
|
||||||
// automatically computed by [MutableSeries].
|
// automatically computed by [MutableSeries].
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
final seriesCategory = series.seriesCategory;
|
final seriesCategory = series.seriesCategory;
|
||||||
final rawMeasureFn = series.rawMeasureFn;
|
final rawMeasureFn = series.rawMeasureFn;
|
||||||
final domainFn = series.domainFn;
|
final domainFn = series.domainFn;
|
||||||
@@ -118,10 +118,10 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Add percent of domain and series accessor functions.
|
// Add percent of domain and series accessor functions.
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
// Replace the default measure accessor with one that computes the
|
// Replace the default measure accessor with one that computes the
|
||||||
// percentage.
|
// percentage.
|
||||||
series.measureFn = (int index) {
|
series.measureFn = (index) {
|
||||||
final measure = series.rawMeasureFn(index);
|
final measure = series.rawMeasureFn(index);
|
||||||
|
|
||||||
if (measure == null || measure == 0.0) {
|
if (measure == null || measure == 0.0) {
|
||||||
@@ -140,7 +140,7 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
// Replace the default measure lower bound accessor with one that
|
// Replace the default measure lower bound accessor with one that
|
||||||
// computes the percentage.
|
// computes the percentage.
|
||||||
if (series.measureLowerBoundFn != null) {
|
if (series.measureLowerBoundFn != null) {
|
||||||
series.measureLowerBoundFn = (int index) {
|
series.measureLowerBoundFn = (index) {
|
||||||
final measureLowerBound = series.rawMeasureLowerBoundFn(index);
|
final measureLowerBound = series.rawMeasureLowerBoundFn(index);
|
||||||
|
|
||||||
if (measureLowerBound == null || measureLowerBound == 0.0) {
|
if (measureLowerBound == null || measureLowerBound == 0.0) {
|
||||||
@@ -160,7 +160,7 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
// Replace the default measure upper bound accessor with one that
|
// Replace the default measure upper bound accessor with one that
|
||||||
// computes the percentage.
|
// computes the percentage.
|
||||||
if (series.measureUpperBoundFn != null) {
|
if (series.measureUpperBoundFn != null) {
|
||||||
series.measureUpperBoundFn = (int index) {
|
series.measureUpperBoundFn = (index) {
|
||||||
final measureUpperBound = series.rawMeasureUpperBoundFn(index);
|
final measureUpperBound = series.rawMeasureUpperBoundFn(index);
|
||||||
|
|
||||||
if (measureUpperBound == null || measureUpperBound == 0.0) {
|
if (measureUpperBound == null || measureUpperBound == 0.0) {
|
||||||
@@ -183,16 +183,16 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PercentInjectorTotalType.series:
|
case PercentInjectorTotalType.series:
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
// Replace the default measure accessor with one that computes the
|
// Replace the default measure accessor with one that computes the
|
||||||
// percentage.
|
// percentage.
|
||||||
series.measureFn = (int index) =>
|
series.measureFn =
|
||||||
series.rawMeasureFn(index) / series.seriesMeasureTotal;
|
(index) => series.rawMeasureFn(index) / series.seriesMeasureTotal;
|
||||||
|
|
||||||
// Replace the default measure lower bound accessor with one that
|
// Replace the default measure lower bound accessor with one that
|
||||||
// computes the percentage.
|
// computes the percentage.
|
||||||
if (series.measureLowerBoundFn != null) {
|
if (series.measureLowerBoundFn != null) {
|
||||||
series.measureLowerBoundFn = (int index) =>
|
series.measureLowerBoundFn = (index) =>
|
||||||
series.rawMeasureLowerBoundFn(index) /
|
series.rawMeasureLowerBoundFn(index) /
|
||||||
series.seriesMeasureTotal;
|
series.seriesMeasureTotal;
|
||||||
}
|
}
|
||||||
@@ -200,7 +200,7 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
// Replace the default measure upper bound accessor with one that
|
// Replace the default measure upper bound accessor with one that
|
||||||
// computes the percentage.
|
// computes the percentage.
|
||||||
if (series.measureUpperBoundFn != null) {
|
if (series.measureUpperBoundFn != null) {
|
||||||
series.measureUpperBoundFn = (int index) =>
|
series.measureUpperBoundFn = (index) =>
|
||||||
series.rawMeasureUpperBoundFn(index) /
|
series.rawMeasureUpperBoundFn(index) /
|
||||||
series.seriesMeasureTotal;
|
series.seriesMeasureTotal;
|
||||||
}
|
}
|
||||||
@@ -211,7 +211,7 @@ class PercentInjector<D> implements ChartBehavior<D> {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new ArgumentError('Unsupported totalType: ${totalType}');
|
throw ArgumentError('Unsupported totalType: $totalType');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,9 +47,9 @@ class ChartTitle<D> implements ChartBehavior<D> {
|
|||||||
static const _defaultTitleDirection = ChartTitleDirection.auto;
|
static const _defaultTitleDirection = ChartTitleDirection.auto;
|
||||||
static const _defaultTitleOutsideJustification = OutsideJustification.middle;
|
static const _defaultTitleOutsideJustification = OutsideJustification.middle;
|
||||||
static final _defaultTitleStyle =
|
static final _defaultTitleStyle =
|
||||||
new TextStyleSpec(fontSize: 18, color: StyleFactory.style.tickColor);
|
TextStyleSpec(fontSize: 18, color: StyleFactory.style.tickColor);
|
||||||
static final _defaultSubTitleStyle =
|
static final _defaultSubTitleStyle =
|
||||||
new TextStyleSpec(fontSize: 14, color: StyleFactory.style.tickColor);
|
TextStyleSpec(fontSize: 14, color: StyleFactory.style.tickColor);
|
||||||
static const _defaultInnerPadding = 10;
|
static const _defaultInnerPadding = 10;
|
||||||
static const _defaultTitlePadding = 18;
|
static const _defaultTitlePadding = 18;
|
||||||
static const _defaultOuterPadding = 10;
|
static const _defaultOuterPadding = 10;
|
||||||
@@ -79,7 +79,7 @@ class ChartTitle<D> implements ChartBehavior<D> {
|
|||||||
TextStyleSpec titleStyleSpec,
|
TextStyleSpec titleStyleSpec,
|
||||||
String subTitle,
|
String subTitle,
|
||||||
TextStyleSpec subTitleStyleSpec}) {
|
TextStyleSpec subTitleStyleSpec}) {
|
||||||
_config = new _ChartTitleConfig()
|
_config = _ChartTitleConfig()
|
||||||
..behaviorPosition = behaviorPosition ?? _defaultBehaviorPosition
|
..behaviorPosition = behaviorPosition ?? _defaultBehaviorPosition
|
||||||
..innerPadding = innerPadding ?? _defaultInnerPadding
|
..innerPadding = innerPadding ?? _defaultInnerPadding
|
||||||
..layoutMinSize = layoutMinSize
|
..layoutMinSize = layoutMinSize
|
||||||
@@ -96,7 +96,7 @@ class ChartTitle<D> implements ChartBehavior<D> {
|
|||||||
..subTitleStyleSpec = subTitleStyleSpec ?? _defaultSubTitleStyle;
|
..subTitleStyleSpec = subTitleStyleSpec ?? _defaultSubTitleStyle;
|
||||||
|
|
||||||
_lifecycleListener =
|
_lifecycleListener =
|
||||||
new LifecycleListener<D>(onAxisConfigured: _updateViewData);
|
LifecycleListener<D>(onAxisConfigured: _updateViewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Layout position for the title.
|
/// Layout position for the title.
|
||||||
@@ -228,7 +228,7 @@ class ChartTitle<D> implements ChartBehavior<D> {
|
|||||||
void attachTo(BaseChart<D> chart) {
|
void attachTo(BaseChart<D> chart) {
|
||||||
_chart = chart;
|
_chart = chart;
|
||||||
|
|
||||||
_view = new _ChartTitleLayoutView<D>(
|
_view = _ChartTitleLayoutView<D>(
|
||||||
layoutPaintOrder: LayoutViewPaintOrder.chartTitle,
|
layoutPaintOrder: LayoutViewPaintOrder.chartTitle,
|
||||||
config: _config,
|
config: _config,
|
||||||
chart: _chart);
|
chart: _chart);
|
||||||
@@ -270,7 +270,7 @@ class _ChartTitleLayoutView<D> extends LayoutView {
|
|||||||
Rectangle<int> _componentBounds;
|
Rectangle<int> _componentBounds;
|
||||||
Rectangle<int> _drawAreaBounds;
|
Rectangle<int> _drawAreaBounds;
|
||||||
|
|
||||||
GraphicsFactory _graphicsFactory;
|
GraphicsFactory graphicsFactory;
|
||||||
|
|
||||||
/// Cached layout element for the title text.
|
/// Cached layout element for the title text.
|
||||||
///
|
///
|
||||||
@@ -292,20 +292,12 @@ class _ChartTitleLayoutView<D> extends LayoutView {
|
|||||||
@required this.chart})
|
@required this.chart})
|
||||||
: this._config = config {
|
: this._config = config {
|
||||||
// Set inside body to resolve [_layoutPosition].
|
// Set inside body to resolve [_layoutPosition].
|
||||||
_layoutConfig = new LayoutViewConfig(
|
_layoutConfig = LayoutViewConfig(
|
||||||
paintOrder: layoutPaintOrder,
|
paintOrder: layoutPaintOrder,
|
||||||
position: _layoutPosition,
|
position: _layoutPosition,
|
||||||
positionOrder: LayoutViewPositionOrder.chartTitle);
|
positionOrder: LayoutViewPositionOrder.chartTitle);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
GraphicsFactory get graphicsFactory => _graphicsFactory;
|
|
||||||
|
|
||||||
@override
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
|
||||||
_graphicsFactory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the configuration for the title behavior.
|
/// Sets the configuration for the title behavior.
|
||||||
set config(_ChartTitleConfig config) {
|
set config(_ChartTitleConfig config) {
|
||||||
_config = config;
|
_config = config;
|
||||||
@@ -415,7 +407,7 @@ class _ChartTitleLayoutView<D> extends LayoutView {
|
|||||||
// Reset the cached text elements used during the paint step.
|
// Reset the cached text elements used during the paint step.
|
||||||
_resetTextElementCache();
|
_resetTextElementCache();
|
||||||
|
|
||||||
return new ViewMeasuredSizes(
|
return ViewMeasuredSizes(
|
||||||
minWidth: minWidth,
|
minWidth: minWidth,
|
||||||
minHeight: minHeight,
|
minHeight: minHeight,
|
||||||
preferredWidth: preferredWidth,
|
preferredWidth: preferredWidth,
|
||||||
@@ -707,7 +699,7 @@ class _ChartTitleLayoutView<D> extends LayoutView {
|
|||||||
labelY = (bounds.bottom - padding).round();
|
labelY = (bounds.bottom - padding).round();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Point<int>(labelX, labelY);
|
return Point<int>(labelX, labelY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the resolved location for a title in the left or right margin.
|
/// Gets the resolved location for a title in the left or right margin.
|
||||||
@@ -780,7 +772,7 @@ class _ChartTitleLayoutView<D> extends LayoutView {
|
|||||||
labelX = (bounds.right - padding).round();
|
labelX = (bounds.right - padding).round();
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Point<int>(labelX, labelY);
|
return Point<int>(labelX, labelY);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function that converts [TextStyleSpec] to [TextStyle].
|
// Helper function that converts [TextStyleSpec] to [TextStyle].
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class DomainHighlighter<D> implements ChartBehavior<D> {
|
|||||||
|
|
||||||
DomainHighlighter([this.selectionModelType = SelectionModelType.info]) {
|
DomainHighlighter([this.selectionModelType = SelectionModelType.info]) {
|
||||||
_lifecycleListener =
|
_lifecycleListener =
|
||||||
new LifecycleListener<D>(onPostprocess: _updateColorFunctions);
|
LifecycleListener<D>(onPostprocess: _updateColorFunctions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _selectionChanged(SelectionModel selectionModel) {
|
void _selectionChanged(SelectionModel selectionModel) {
|
||||||
@@ -45,11 +45,11 @@ class DomainHighlighter<D> implements ChartBehavior<D> {
|
|||||||
void _updateColorFunctions(List<MutableSeries<D>> seriesList) {
|
void _updateColorFunctions(List<MutableSeries<D>> seriesList) {
|
||||||
SelectionModel selectionModel =
|
SelectionModel selectionModel =
|
||||||
_chart.getSelectionModel(selectionModelType);
|
_chart.getSelectionModel(selectionModelType);
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
final origColorFn = series.colorFn;
|
final origColorFn = series.colorFn;
|
||||||
|
|
||||||
if (origColorFn != null) {
|
if (origColorFn != null) {
|
||||||
series.colorFn = (int index) {
|
series.colorFn = (index) {
|
||||||
final origColor = origColorFn(index);
|
final origColor = origColorFn(index);
|
||||||
if (selectionModel.isDatumSelected(series, index)) {
|
if (selectionModel.isDatumSelected(series, index)) {
|
||||||
return origColor.darker;
|
return origColor.darker;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class InitialSelection<D> implements ChartBehavior<D> {
|
|||||||
{this.selectionModelType = SelectionModelType.info,
|
{this.selectionModelType = SelectionModelType.info,
|
||||||
this.selectedDataConfig,
|
this.selectedDataConfig,
|
||||||
this.selectedSeriesConfig}) {
|
this.selectedSeriesConfig}) {
|
||||||
_lifecycleListener = new LifecycleListener<D>(onData: _setInitialSelection);
|
_lifecycleListener = LifecycleListener<D>(onData: _setInitialSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _setInitialSelection(List<MutableSeries<D>> seriesList) {
|
void _setInitialSelection(List<MutableSeries<D>> seriesList) {
|
||||||
@@ -49,7 +49,7 @@ class InitialSelection<D> implements ChartBehavior<D> {
|
|||||||
}
|
}
|
||||||
_firstDraw = false;
|
_firstDraw = false;
|
||||||
|
|
||||||
final immutableModel = new SelectionModel<D>.fromConfig(
|
final immutableModel = SelectionModel<D>.fromConfig(
|
||||||
selectedDataConfig, selectedSeriesConfig, seriesList);
|
selectedDataConfig, selectedSeriesConfig, seriesList);
|
||||||
|
|
||||||
_chart.getSelectionModel(selectionModelType).updateSelection(
|
_chart.getSelectionModel(selectionModelType).updateSelection(
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class DatumLegend<D> extends Legend<D> {
|
|||||||
}) : super(
|
}) : super(
|
||||||
selectionModelType: selectionModelType ?? SelectionModelType.info,
|
selectionModelType: selectionModelType ?? SelectionModelType.info,
|
||||||
legendEntryGenerator:
|
legendEntryGenerator:
|
||||||
legendEntryGenerator ?? new PerDatumLegendEntryGenerator(),
|
legendEntryGenerator ?? PerDatumLegendEntryGenerator(),
|
||||||
entryTextStyle: entryTextStyle) {
|
entryTextStyle: entryTextStyle) {
|
||||||
// Call the setters that include the setting for default.
|
// Call the setters that include the setting for default.
|
||||||
this.showMeasures = showMeasures;
|
this.showMeasures = showMeasures;
|
||||||
|
|||||||
@@ -51,101 +51,28 @@ import 'legend_entry_generator.dart';
|
|||||||
/// Flutter, using widgets).
|
/// Flutter, using widgets).
|
||||||
abstract class Legend<D> implements ChartBehavior<D>, LayoutView {
|
abstract class Legend<D> implements ChartBehavior<D>, LayoutView {
|
||||||
final SelectionModelType selectionModelType;
|
final SelectionModelType selectionModelType;
|
||||||
final legendState = new LegendState<D>();
|
final legendState = LegendState<D>();
|
||||||
final LegendEntryGenerator<D> legendEntryGenerator;
|
final LegendEntryGenerator<D> legendEntryGenerator;
|
||||||
|
|
||||||
String _title;
|
/// Sets title text to display before legend entries.
|
||||||
|
String title;
|
||||||
|
|
||||||
BaseChart _chart;
|
BaseChart _chart;
|
||||||
LifecycleListener<D> _lifecycleListener;
|
LifecycleListener<D> _lifecycleListener;
|
||||||
|
|
||||||
Rectangle<int> _componentBounds;
|
Rectangle<int> _componentBounds;
|
||||||
Rectangle<int> _drawAreaBounds;
|
Rectangle<int> _drawAreaBounds;
|
||||||
GraphicsFactory _graphicsFactory;
|
GraphicsFactory graphicsFactory;
|
||||||
|
|
||||||
BehaviorPosition _behaviorPosition = BehaviorPosition.end;
|
BehaviorPosition behaviorPosition = BehaviorPosition.end;
|
||||||
OutsideJustification _outsideJustification =
|
OutsideJustification outsideJustification =
|
||||||
OutsideJustification.startDrawArea;
|
OutsideJustification.startDrawArea;
|
||||||
InsideJustification _insideJustification = InsideJustification.topStart;
|
InsideJustification insideJustification = InsideJustification.topStart;
|
||||||
LegendCellPadding _cellPadding;
|
LegendCellPadding cellPadding;
|
||||||
LegendCellPadding _legendPadding;
|
LegendCellPadding legendPadding;
|
||||||
|
|
||||||
TextStyleSpec _titleTextStyle;
|
|
||||||
|
|
||||||
LegendTapHandling _legendTapHandling = LegendTapHandling.hide;
|
|
||||||
|
|
||||||
List<MutableSeries<D>> _currentSeriesList;
|
|
||||||
|
|
||||||
/// Save this in order to check if series list have changed and regenerate
|
|
||||||
/// the legend entries.
|
|
||||||
List<MutableSeries<D>> _postProcessSeriesList;
|
|
||||||
|
|
||||||
static final _decimalPattern = new NumberFormat.decimalPattern();
|
|
||||||
|
|
||||||
/// Default measure formatter for legends.
|
|
||||||
@protected
|
|
||||||
String defaultLegendMeasureFormatter(num value) {
|
|
||||||
return (value == null) ? '' : _decimalPattern.format(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
Legend({this.selectionModelType, this.legendEntryGenerator, entryTextStyle}) {
|
|
||||||
_lifecycleListener = new LifecycleListener(
|
|
||||||
onPostprocess: _postProcess, onPreprocess: _preProcess, onData: onData);
|
|
||||||
legendEntryGenerator.entryTextStyle = entryTextStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
String get title => _title;
|
|
||||||
|
|
||||||
/// Sets title text to display before legend entries.
|
|
||||||
set title(String title) {
|
|
||||||
_title = title;
|
|
||||||
}
|
|
||||||
|
|
||||||
BehaviorPosition get behaviorPosition => _behaviorPosition;
|
|
||||||
|
|
||||||
set behaviorPosition(BehaviorPosition behaviorPosition) {
|
|
||||||
_behaviorPosition = behaviorPosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
OutsideJustification get outsideJustification => _outsideJustification;
|
|
||||||
|
|
||||||
set outsideJustification(OutsideJustification outsideJustification) {
|
|
||||||
_outsideJustification = outsideJustification;
|
|
||||||
}
|
|
||||||
|
|
||||||
InsideJustification get insideJustification => _insideJustification;
|
|
||||||
|
|
||||||
set insideJustification(InsideJustification insideJustification) {
|
|
||||||
_insideJustification = insideJustification;
|
|
||||||
}
|
|
||||||
|
|
||||||
LegendCellPadding get cellPadding => _cellPadding;
|
|
||||||
|
|
||||||
set cellPadding(LegendCellPadding cellPadding) {
|
|
||||||
_cellPadding = cellPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
LegendCellPadding get legendPadding => _legendPadding;
|
|
||||||
|
|
||||||
set legendPadding(LegendCellPadding legendPadding) {
|
|
||||||
_legendPadding = legendPadding;
|
|
||||||
}
|
|
||||||
|
|
||||||
LegendTapHandling get legendTapHandling => _legendTapHandling;
|
|
||||||
|
|
||||||
/// Text style of the legend entry text.
|
|
||||||
TextStyleSpec get entryTextStyle => legendEntryGenerator.entryTextStyle;
|
|
||||||
|
|
||||||
set entryTextStyle(TextStyleSpec entryTextStyle) {
|
|
||||||
legendEntryGenerator.entryTextStyle = entryTextStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Text style of the legend title text.
|
/// Text style of the legend title text.
|
||||||
TextStyleSpec get titleTextStyle => _titleTextStyle;
|
TextStyleSpec titleTextStyle;
|
||||||
|
|
||||||
set titleTextStyle(TextStyleSpec titleTextStyle) {
|
|
||||||
_titleTextStyle = titleTextStyle;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures the behavior of the legend when the user taps/clicks on an
|
/// Configures the behavior of the legend when the user taps/clicks on an
|
||||||
/// entry. Defaults to no behavior.
|
/// entry. Defaults to no behavior.
|
||||||
@@ -154,8 +81,33 @@ abstract class Legend<D> implements ChartBehavior<D>, LayoutView {
|
|||||||
/// example, when [LegendTapHandling.hide] is configured, the series or datum
|
/// example, when [LegendTapHandling.hide] is configured, the series or datum
|
||||||
/// associated with that entry will be removed from the chart. Tapping on that
|
/// associated with that entry will be removed from the chart. Tapping on that
|
||||||
/// entry a second time will make the data visible again.
|
/// entry a second time will make the data visible again.
|
||||||
set legendTapHandling(LegendTapHandling legendTapHandling) {
|
LegendTapHandling legendTapHandling = LegendTapHandling.hide;
|
||||||
_legendTapHandling = legendTapHandling;
|
|
||||||
|
List<MutableSeries<D>> _currentSeriesList;
|
||||||
|
|
||||||
|
/// Save this in order to check if series list have changed and regenerate
|
||||||
|
/// the legend entries.
|
||||||
|
List<MutableSeries<D>> _postProcessSeriesList;
|
||||||
|
|
||||||
|
static final _decimalPattern = NumberFormat.decimalPattern();
|
||||||
|
|
||||||
|
/// Default measure formatter for legends.
|
||||||
|
@protected
|
||||||
|
String defaultLegendMeasureFormatter(num value) {
|
||||||
|
return (value == null) ? '' : _decimalPattern.format(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Legend({this.selectionModelType, this.legendEntryGenerator, entryTextStyle}) {
|
||||||
|
_lifecycleListener = LifecycleListener(
|
||||||
|
onPostprocess: _postProcess, onPreprocess: _preProcess, onData: onData);
|
||||||
|
legendEntryGenerator.entryTextStyle = entryTextStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Text style of the legend entry text.
|
||||||
|
TextStyleSpec get entryTextStyle => legendEntryGenerator.entryTextStyle;
|
||||||
|
|
||||||
|
set entryTextStyle(TextStyleSpec entryTextStyle) {
|
||||||
|
legendEntryGenerator.entryTextStyle = entryTextStyle;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resets any hidden series data when new data is drawn on the chart.
|
/// Resets any hidden series data when new data is drawn on the chart.
|
||||||
@@ -164,7 +116,7 @@ abstract class Legend<D> implements ChartBehavior<D>, LayoutView {
|
|||||||
|
|
||||||
/// Store off a copy of the series list for use when we render the legend.
|
/// Store off a copy of the series list for use when we render the legend.
|
||||||
void _preProcess(List<MutableSeries<D>> seriesList) {
|
void _preProcess(List<MutableSeries<D>> seriesList) {
|
||||||
_currentSeriesList = new List.from(seriesList);
|
_currentSeriesList = List.from(seriesList);
|
||||||
preProcessSeriesList(seriesList);
|
preProcessSeriesList(seriesList);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,17 +203,9 @@ abstract class Legend<D> implements ChartBehavior<D>, LayoutView {
|
|||||||
|
|
||||||
bool get isRtl => _chart.context.isRtl;
|
bool get isRtl => _chart.context.isRtl;
|
||||||
|
|
||||||
@override
|
|
||||||
GraphicsFactory get graphicsFactory => _graphicsFactory;
|
|
||||||
|
|
||||||
@override
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
|
||||||
_graphicsFactory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
LayoutViewConfig get layoutConfig {
|
LayoutViewConfig get layoutConfig {
|
||||||
return new LayoutViewConfig(
|
return LayoutViewConfig(
|
||||||
position: _layoutPosition,
|
position: _layoutPosition,
|
||||||
positionOrder: LayoutViewPositionOrder.legend,
|
positionOrder: LayoutViewPositionOrder.legend,
|
||||||
paintOrder: LayoutViewPaintOrder.legend);
|
paintOrder: LayoutViewPaintOrder.legend);
|
||||||
@@ -270,7 +214,7 @@ abstract class Legend<D> implements ChartBehavior<D>, LayoutView {
|
|||||||
/// Get layout position from legend position.
|
/// Get layout position from legend position.
|
||||||
LayoutPosition get _layoutPosition {
|
LayoutPosition get _layoutPosition {
|
||||||
LayoutPosition position;
|
LayoutPosition position;
|
||||||
switch (_behaviorPosition) {
|
switch (behaviorPosition) {
|
||||||
case BehaviorPosition.bottom:
|
case BehaviorPosition.bottom:
|
||||||
position = LayoutPosition.Bottom;
|
position = LayoutPosition.Bottom;
|
||||||
break;
|
break;
|
||||||
@@ -296,7 +240,7 @@ abstract class Legend<D> implements ChartBehavior<D>, LayoutView {
|
|||||||
ViewMeasuredSizes measure(int maxWidth, int maxHeight) {
|
ViewMeasuredSizes measure(int maxWidth, int maxHeight) {
|
||||||
// Native child classes should override this method to return real
|
// Native child classes should override this method to return real
|
||||||
// measurements.
|
// measurements.
|
||||||
return new ViewMeasuredSizes(preferredWidth: 0, preferredHeight: 0);
|
return ViewMeasuredSizes(preferredWidth: 0, preferredHeight: 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -39,8 +39,7 @@ class PerDatumLegendEntryGenerator<D> implements LegendEntryGenerator<D> {
|
|||||||
|
|
||||||
final series = seriesList[0];
|
final series = seriesList[0];
|
||||||
for (var i = 0; i < series.data.length; i++) {
|
for (var i = 0; i < series.data.length; i++) {
|
||||||
legendEntries.add(new LegendEntry<D>(
|
legendEntries.add(LegendEntry<D>(series, series.domainFn(i).toString(),
|
||||||
series, series.domainFn(i).toString(),
|
|
||||||
color: series.colorFn(i),
|
color: series.colorFn(i),
|
||||||
datum: series.data[i],
|
datum: series.data[i],
|
||||||
datumIndex: i,
|
datumIndex: i,
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class PerSeriesLegendEntryGenerator<D> implements LegendEntryGenerator<D> {
|
|||||||
@override
|
@override
|
||||||
List<LegendEntry<D>> getLegendEntries(List<MutableSeries<D>> seriesList) {
|
List<LegendEntry<D>> getLegendEntries(List<MutableSeries<D>> seriesList) {
|
||||||
final legendEntries = seriesList
|
final legendEntries = seriesList
|
||||||
.map((series) => new LegendEntry<D>(series, series.displayName,
|
.map((series) => LegendEntry<D>(series, series.displayName,
|
||||||
color: series.colorFn(0), textStyle: entryTextStyle))
|
color: series.colorFn(0), textStyle: entryTextStyle))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ class PerSeriesLegendEntryGenerator<D> implements LegendEntryGenerator<D> {
|
|||||||
final seriesAndMeasure = <String, num>{};
|
final seriesAndMeasure = <String, num>{};
|
||||||
|
|
||||||
// Hash set of series ID's that use the secondary measure axis
|
// Hash set of series ID's that use the secondary measure axis
|
||||||
final secondaryAxisSeriesIDs = new HashSet<String>();
|
final secondaryAxisSeriesIDs = HashSet<String>();
|
||||||
|
|
||||||
for (SeriesDatum<D> selectedDatum in selectionModel.selectedDatum) {
|
for (SeriesDatum<D> selectedDatum in selectionModel.selectedDatum) {
|
||||||
final series = selectedDatum.series;
|
final series = selectedDatum.series;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import 'per_series_legend_entry_generator.dart';
|
|||||||
/// By default this behavior creates a legend entry per series.
|
/// By default this behavior creates a legend entry per series.
|
||||||
class SeriesLegend<D> extends Legend<D> {
|
class SeriesLegend<D> extends Legend<D> {
|
||||||
/// List of currently hidden series, by ID.
|
/// List of currently hidden series, by ID.
|
||||||
final _hiddenSeriesList = new Set<String>();
|
final _hiddenSeriesList = Set<String>();
|
||||||
|
|
||||||
/// List of series IDs that should be hidden by default.
|
/// List of series IDs that should be hidden by default.
|
||||||
List<String> _defaultHiddenSeries;
|
List<String> _defaultHiddenSeries;
|
||||||
@@ -50,7 +50,7 @@ class SeriesLegend<D> extends Legend<D> {
|
|||||||
}) : super(
|
}) : super(
|
||||||
selectionModelType: selectionModelType ?? SelectionModelType.info,
|
selectionModelType: selectionModelType ?? SelectionModelType.info,
|
||||||
legendEntryGenerator:
|
legendEntryGenerator:
|
||||||
legendEntryGenerator ?? new PerSeriesLegendEntryGenerator(),
|
legendEntryGenerator ?? PerSeriesLegendEntryGenerator(),
|
||||||
entryTextStyle: entryTextStyle) {
|
entryTextStyle: entryTextStyle) {
|
||||||
// Call the setters that include the setting for default.
|
// Call the setters that include the setting for default.
|
||||||
this.showMeasures = showMeasures;
|
this.showMeasures = showMeasures;
|
||||||
@@ -134,14 +134,14 @@ class SeriesLegend<D> extends Legend<D> {
|
|||||||
void onData(List<MutableSeries<D>> seriesList) {
|
void onData(List<MutableSeries<D>> seriesList) {
|
||||||
// If a series was removed from the chart, remove it from our current list
|
// If a series was removed from the chart, remove it from our current list
|
||||||
// of hidden series.
|
// of hidden series.
|
||||||
final seriesIds = seriesList.map((MutableSeries<D> series) => series.id);
|
final seriesIds = seriesList.map((series) => series.id);
|
||||||
|
|
||||||
_hiddenSeriesList.removeWhere((String id) => !seriesIds.contains(id));
|
_hiddenSeriesList.removeWhere((id) => !seriesIds.contains(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void preProcessSeriesList(List<MutableSeries<D>> seriesList) {
|
void preProcessSeriesList(List<MutableSeries<D>> seriesList) {
|
||||||
seriesList.removeWhere((MutableSeries<D> series) {
|
seriesList.removeWhere((series) {
|
||||||
return _hiddenSeriesList.contains(series.id);
|
return _hiddenSeriesList.contains(series.id);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -161,7 +161,7 @@ class SeriesLegend<D> extends Legend<D> {
|
|||||||
/// color if it was previously hidden.
|
/// color if it was previously hidden.
|
||||||
@protected
|
@protected
|
||||||
void showSeries(String seriesId) {
|
void showSeries(String seriesId) {
|
||||||
_hiddenSeriesList.removeWhere((String id) => id == seriesId);
|
_hiddenSeriesList.removeWhere((id) => id == seriesId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns whether or not a given series [seriesId] is currently hidden.
|
/// Returns whether or not a given series [seriesId] is currently hidden.
|
||||||
|
|||||||
@@ -133,16 +133,16 @@ class LinePointHighlighter<D> implements ChartBehavior<D> {
|
|||||||
LinePointHighlighterFollowLineType.nearest,
|
LinePointHighlighterFollowLineType.nearest,
|
||||||
dashPattern = dashPattern ?? [1, 3],
|
dashPattern = dashPattern ?? [1, 3],
|
||||||
drawFollowLinesAcrossChart = drawFollowLinesAcrossChart ?? true,
|
drawFollowLinesAcrossChart = drawFollowLinesAcrossChart ?? true,
|
||||||
symbolRenderer = symbolRenderer ?? new CircleSymbolRenderer() {
|
symbolRenderer = symbolRenderer ?? CircleSymbolRenderer() {
|
||||||
_lifecycleListener =
|
_lifecycleListener =
|
||||||
new LifecycleListener<D>(onAxisConfigured: _updateViewData);
|
LifecycleListener<D>(onAxisConfigured: _updateViewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void attachTo(BaseChart<D> chart) {
|
void attachTo(BaseChart<D> chart) {
|
||||||
_chart = chart;
|
_chart = chart;
|
||||||
|
|
||||||
_view = new _LinePointLayoutView<D>(
|
_view = _LinePointLayoutView<D>(
|
||||||
chart: chart,
|
chart: chart,
|
||||||
layoutPaintOrder: LayoutViewPaintOrder.linePointHighlighter,
|
layoutPaintOrder: LayoutViewPaintOrder.linePointHighlighter,
|
||||||
showHorizontalFollowLine: showHorizontalFollowLine,
|
showHorizontalFollowLine: showHorizontalFollowLine,
|
||||||
@@ -205,7 +205,7 @@ class LinePointHighlighter<D> implements ChartBehavior<D> {
|
|||||||
? detail.radiusPx.toDouble() + radiusPaddingPx
|
? detail.radiusPx.toDouble() + radiusPaddingPx
|
||||||
: defaultRadiusPx;
|
: defaultRadiusPx;
|
||||||
|
|
||||||
final pointKey = '${lineKey}::${detail.domain}';
|
final pointKey = '$lineKey::${detail.domain}';
|
||||||
|
|
||||||
// If we already have a point for that key, use it.
|
// If we already have a point for that key, use it.
|
||||||
_AnimatedPoint<D> animatingPoint;
|
_AnimatedPoint<D> animatingPoint;
|
||||||
@@ -213,16 +213,16 @@ class LinePointHighlighter<D> implements ChartBehavior<D> {
|
|||||||
animatingPoint = _seriesPointMap[pointKey];
|
animatingPoint = _seriesPointMap[pointKey];
|
||||||
} else {
|
} else {
|
||||||
// Create a new point and have it animate in from axis.
|
// Create a new point and have it animate in from axis.
|
||||||
final point = new _DatumPoint<D>(
|
final point = _DatumPoint<D>(
|
||||||
datum: datum,
|
datum: datum,
|
||||||
domain: detail.domain,
|
domain: detail.domain,
|
||||||
series: series,
|
series: series,
|
||||||
x: domainAxis.getLocation(detail.domain),
|
x: domainAxis.getLocation(detail.domain),
|
||||||
y: measureAxis.getLocation(0.0));
|
y: measureAxis.getLocation(0.0));
|
||||||
|
|
||||||
animatingPoint = new _AnimatedPoint<D>(
|
animatingPoint = _AnimatedPoint<D>(
|
||||||
key: pointKey, overlaySeries: series.overlaySeries)
|
key: pointKey, overlaySeries: series.overlaySeries)
|
||||||
..setNewTarget(new _PointRendererElement<D>()
|
..setNewTarget(_PointRendererElement<D>()
|
||||||
..point = point
|
..point = point
|
||||||
..color = detail.color
|
..color = detail.color
|
||||||
..fillColor = detail.fillColor
|
..fillColor = detail.fillColor
|
||||||
@@ -235,7 +235,7 @@ class LinePointHighlighter<D> implements ChartBehavior<D> {
|
|||||||
newSeriesMap[pointKey] = animatingPoint;
|
newSeriesMap[pointKey] = animatingPoint;
|
||||||
|
|
||||||
// Create a new line using the final point locations.
|
// Create a new line using the final point locations.
|
||||||
final point = new _DatumPoint<D>(
|
final point = _DatumPoint<D>(
|
||||||
datum: datum,
|
datum: datum,
|
||||||
domain: detail.domain,
|
domain: detail.domain,
|
||||||
series: series,
|
series: series,
|
||||||
@@ -246,7 +246,7 @@ class LinePointHighlighter<D> implements ChartBehavior<D> {
|
|||||||
_currentKeys.add(pointKey);
|
_currentKeys.add(pointKey);
|
||||||
|
|
||||||
// Get the point element we are going to setup.
|
// Get the point element we are going to setup.
|
||||||
final pointElement = new _PointRendererElement<D>()
|
final pointElement = _PointRendererElement<D>()
|
||||||
..point = point
|
..point = point
|
||||||
..color = detail.color
|
..color = detail.color
|
||||||
..fillColor = detail.fillColor
|
..fillColor = detail.fillColor
|
||||||
@@ -259,7 +259,7 @@ class LinePointHighlighter<D> implements ChartBehavior<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Animate out points that don't exist anymore.
|
// Animate out points that don't exist anymore.
|
||||||
_seriesPointMap.forEach((String key, _AnimatedPoint<D> point) {
|
_seriesPointMap.forEach((key, point) {
|
||||||
if (_currentKeys.contains(point.key) != true) {
|
if (_currentKeys.contains(point.key) != true) {
|
||||||
point.animateOut();
|
point.animateOut();
|
||||||
newSeriesMap[point.key] = point;
|
newSeriesMap[point.key] = point;
|
||||||
@@ -293,7 +293,7 @@ class _LinePointLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
final SymbolRenderer symbolRenderer;
|
final SymbolRenderer symbolRenderer;
|
||||||
|
|
||||||
GraphicsFactory _graphicsFactory;
|
GraphicsFactory graphicsFactory;
|
||||||
|
|
||||||
/// Store a map of series drawn on the chart, mapped by series name.
|
/// Store a map of series drawn on the chart, mapped by series name.
|
||||||
///
|
///
|
||||||
@@ -309,7 +309,7 @@ class _LinePointLayoutView<D> extends LayoutView {
|
|||||||
@required this.symbolRenderer,
|
@required this.symbolRenderer,
|
||||||
this.dashPattern,
|
this.dashPattern,
|
||||||
this.drawFollowLinesAcrossChart,
|
this.drawFollowLinesAcrossChart,
|
||||||
}) : this.layoutConfig = new LayoutViewConfig(
|
}) : this.layoutConfig = LayoutViewConfig(
|
||||||
paintOrder: LayoutViewPaintOrder.linePointHighlighter,
|
paintOrder: LayoutViewPaintOrder.linePointHighlighter,
|
||||||
position: LayoutPosition.DrawArea,
|
position: LayoutPosition.DrawArea,
|
||||||
positionOrder: layoutPaintOrder);
|
positionOrder: layoutPaintOrder);
|
||||||
@@ -318,14 +318,6 @@ class _LinePointLayoutView<D> extends LayoutView {
|
|||||||
_seriesPointMap = value;
|
_seriesPointMap = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
GraphicsFactory get graphicsFactory => _graphicsFactory;
|
|
||||||
|
|
||||||
@override
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
|
||||||
_graphicsFactory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ViewMeasuredSizes measure(int maxWidth, int maxHeight) {
|
ViewMeasuredSizes measure(int maxWidth, int maxHeight) {
|
||||||
return null;
|
return null;
|
||||||
@@ -346,17 +338,17 @@ class _LinePointLayoutView<D> extends LayoutView {
|
|||||||
if (animationPercent == 1.0) {
|
if (animationPercent == 1.0) {
|
||||||
final keysToRemove = <String>[];
|
final keysToRemove = <String>[];
|
||||||
|
|
||||||
_seriesPointMap.forEach((String key, _AnimatedPoint<D> point) {
|
_seriesPointMap.forEach((key, point) {
|
||||||
if (point.animatingOut) {
|
if (point.animatingOut) {
|
||||||
keysToRemove.add(key);
|
keysToRemove.add(key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
keysToRemove.forEach((String key) => _seriesPointMap.remove(key));
|
keysToRemove.forEach((key) => _seriesPointMap.remove(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
final points = <_PointRendererElement<D>>[];
|
final points = <_PointRendererElement<D>>[];
|
||||||
_seriesPointMap.forEach((String key, _AnimatedPoint<D> point) {
|
_seriesPointMap.forEach((key, point) {
|
||||||
points.add(point.getCurrentPoint(animationPercent));
|
points.add(point.getCurrentPoint(animationPercent));
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -449,8 +441,8 @@ class _LinePointLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
canvas.drawLine(
|
canvas.drawLine(
|
||||||
points: [
|
points: [
|
||||||
new Point<num>(leftBound, pointElement.point.y),
|
Point<num>(leftBound, pointElement.point.y),
|
||||||
new Point<num>(rightBound, pointElement.point.y),
|
Point<num>(rightBound, pointElement.point.y),
|
||||||
],
|
],
|
||||||
stroke: StyleFactory.style.linePointHighlighterColor,
|
stroke: StyleFactory.style.linePointHighlighterColor,
|
||||||
strokeWidthPx: 1.0,
|
strokeWidthPx: 1.0,
|
||||||
@@ -473,8 +465,8 @@ class _LinePointLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
canvas.drawLine(
|
canvas.drawLine(
|
||||||
points: [
|
points: [
|
||||||
new Point<num>(pointElement.point.x, topBound),
|
Point<num>(pointElement.point.x, topBound),
|
||||||
new Point<num>(
|
Point<num>(
|
||||||
pointElement.point.x, drawBounds.top + drawBounds.height),
|
pointElement.point.x, drawBounds.top + drawBounds.height),
|
||||||
],
|
],
|
||||||
stroke: StyleFactory.style.linePointHighlighterColor,
|
stroke: StyleFactory.style.linePointHighlighterColor,
|
||||||
@@ -500,7 +492,7 @@ class _LinePointLayoutView<D> extends LayoutView {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final bounds = new Rectangle<double>(
|
final bounds = Rectangle<double>(
|
||||||
pointElement.point.x - pointElement.radiusPx,
|
pointElement.point.x - pointElement.radiusPx,
|
||||||
pointElement.point.y - pointElement.radiusPx,
|
pointElement.point.y - pointElement.radiusPx,
|
||||||
pointElement.radiusPx * 2,
|
pointElement.radiusPx * 2,
|
||||||
@@ -531,7 +523,7 @@ class _DatumPoint<D> extends Point<double> {
|
|||||||
: super(x, y);
|
: super(x, y);
|
||||||
|
|
||||||
factory _DatumPoint.from(_DatumPoint<D> other, [double x, double y]) {
|
factory _DatumPoint.from(_DatumPoint<D> other, [double x, double y]) {
|
||||||
return new _DatumPoint<D>(
|
return _DatumPoint<D>(
|
||||||
datum: other.datum,
|
datum: other.datum,
|
||||||
domain: other.domain,
|
domain: other.domain,
|
||||||
series: other.series,
|
series: other.series,
|
||||||
@@ -550,7 +542,7 @@ class _PointRendererElement<D> {
|
|||||||
SymbolRenderer symbolRenderer;
|
SymbolRenderer symbolRenderer;
|
||||||
|
|
||||||
_PointRendererElement<D> clone() {
|
_PointRendererElement<D> clone() {
|
||||||
return new _PointRendererElement<D>()
|
return _PointRendererElement<D>()
|
||||||
..point = this.point
|
..point = this.point
|
||||||
..color = this.color
|
..color = this.color
|
||||||
..fillColor = this.fillColor
|
..fillColor = this.fillColor
|
||||||
@@ -569,7 +561,7 @@ class _PointRendererElement<D> {
|
|||||||
|
|
||||||
final y = _lerpDouble(previousPoint.y, targetPoint.y, animationPercent);
|
final y = _lerpDouble(previousPoint.y, targetPoint.y, animationPercent);
|
||||||
|
|
||||||
point = new _DatumPoint<D>.from(targetPoint, x, y);
|
point = _DatumPoint<D>.from(targetPoint, x, y);
|
||||||
|
|
||||||
color = getAnimatedColor(previous.color, target.color, animationPercent);
|
color = getAnimatedColor(previous.color, target.color, animationPercent);
|
||||||
|
|
||||||
@@ -625,7 +617,7 @@ class _AnimatedPoint<D> {
|
|||||||
// Set the target measure value to the axis position for all points.
|
// Set the target measure value to the axis position for all points.
|
||||||
final targetPoint = newTarget.point;
|
final targetPoint = newTarget.point;
|
||||||
|
|
||||||
final newPoint = new _DatumPoint<D>.from(targetPoint, targetPoint.x,
|
final newPoint = _DatumPoint<D>.from(targetPoint, targetPoint.x,
|
||||||
newTarget.measureAxisPosition.roundToDouble());
|
newTarget.measureAxisPosition.roundToDouble());
|
||||||
|
|
||||||
newTarget.point = newPoint;
|
newTarget.point = newPoint;
|
||||||
@@ -685,7 +677,7 @@ class LinePointHighlighterTester<D> {
|
|||||||
bool isDatumSelected(D datum) {
|
bool isDatumSelected(D datum) {
|
||||||
var contains = false;
|
var contains = false;
|
||||||
|
|
||||||
behavior._seriesPointMap.forEach((String key, _AnimatedPoint<D> point) {
|
behavior._seriesPointMap.forEach((key, point) {
|
||||||
if (point._currentPoint.point.datum == datum) {
|
if (point._currentPoint.point.datum == datum) {
|
||||||
contains = true;
|
contains = true;
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ class RangeAnnotation<D> implements ChartBehavior<D> {
|
|||||||
static const _defaultLabelPosition = AnnotationLabelPosition.auto;
|
static const _defaultLabelPosition = AnnotationLabelPosition.auto;
|
||||||
static const _defaultLabelPadding = 5;
|
static const _defaultLabelPadding = 5;
|
||||||
static final _defaultLabelStyle =
|
static final _defaultLabelStyle =
|
||||||
new TextStyleSpec(fontSize: 12, color: Color.black);
|
TextStyleSpec(fontSize: 12, color: Color.black);
|
||||||
static const _defaultStrokeWidthPx = 2.0;
|
static const _defaultStrokeWidthPx = 2.0;
|
||||||
|
|
||||||
/// List of annotations to render on the chart.
|
/// List of annotations to render on the chart.
|
||||||
@@ -121,20 +121,20 @@ class RangeAnnotation<D> implements ChartBehavior<D> {
|
|||||||
extendAxis = extendAxis ?? true,
|
extendAxis = extendAxis ?? true,
|
||||||
labelPadding = labelPadding ?? _defaultLabelPadding,
|
labelPadding = labelPadding ?? _defaultLabelPadding,
|
||||||
defaultStrokeWidthPx = defaultStrokeWidthPx ?? _defaultStrokeWidthPx {
|
defaultStrokeWidthPx = defaultStrokeWidthPx ?? _defaultStrokeWidthPx {
|
||||||
_lifecycleListener = new LifecycleListener<D>(
|
_lifecycleListener = LifecycleListener<D>(
|
||||||
onPostprocess: _updateAxisRange, onAxisConfigured: _updateViewData);
|
onPostprocess: _updateAxisRange, onAxisConfigured: _updateViewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void attachTo(BaseChart<D> chart) {
|
void attachTo(BaseChart<D> chart) {
|
||||||
if (!(chart is CartesianChart)) {
|
if (!(chart is CartesianChart)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'RangeAnnotation can only be attached to a CartesianChart');
|
'RangeAnnotation can only be attached to a CartesianChart');
|
||||||
}
|
}
|
||||||
|
|
||||||
_chart = chart;
|
_chart = chart;
|
||||||
|
|
||||||
_view = new _RangeAnnotationLayoutView<D>(
|
_view = _RangeAnnotationLayoutView<D>(
|
||||||
defaultColor: defaultColor, labelPadding: labelPadding, chart: chart);
|
defaultColor: defaultColor, labelPadding: labelPadding, chart: chart);
|
||||||
|
|
||||||
chart.addView(_view);
|
chart.addView(_view);
|
||||||
@@ -155,7 +155,7 @@ class RangeAnnotation<D> implements ChartBehavior<D> {
|
|||||||
if (extendAxis) {
|
if (extendAxis) {
|
||||||
final domainAxis = _chart.domainAxis;
|
final domainAxis = _chart.domainAxis;
|
||||||
|
|
||||||
annotations.forEach((AnnotationSegment annotation) {
|
annotations.forEach((annotation) {
|
||||||
Axis axis;
|
Axis axis;
|
||||||
|
|
||||||
switch (annotation.axisType) {
|
switch (annotation.axisType) {
|
||||||
@@ -182,7 +182,7 @@ class RangeAnnotation<D> implements ChartBehavior<D> {
|
|||||||
void _updateViewData() {
|
void _updateViewData() {
|
||||||
_currentKeys.clear();
|
_currentKeys.clear();
|
||||||
|
|
||||||
annotations.forEach((AnnotationSegment annotation) {
|
annotations.forEach((annotation) {
|
||||||
Axis axis;
|
Axis axis;
|
||||||
|
|
||||||
switch (annotation.axisType) {
|
switch (annotation.axisType) {
|
||||||
@@ -251,8 +251,8 @@ class RangeAnnotation<D> implements ChartBehavior<D> {
|
|||||||
animatingAnnotation = _annotationMap[key];
|
animatingAnnotation = _annotationMap[key];
|
||||||
} else {
|
} else {
|
||||||
// Create a new annotation, positioned at the start and end values.
|
// Create a new annotation, positioned at the start and end values.
|
||||||
animatingAnnotation = new _AnimatedAnnotation<D>(key: key)
|
animatingAnnotation = _AnimatedAnnotation<D>(key: key)
|
||||||
..setNewTarget(new _AnnotationElement<D>()
|
..setNewTarget(_AnnotationElement<D>()
|
||||||
..annotation = annotationDatum
|
..annotation = annotationDatum
|
||||||
..color = color
|
..color = color
|
||||||
..dashPattern = dashPattern
|
..dashPattern = dashPattern
|
||||||
@@ -272,7 +272,7 @@ class RangeAnnotation<D> implements ChartBehavior<D> {
|
|||||||
_currentKeys.add(key);
|
_currentKeys.add(key);
|
||||||
|
|
||||||
// Get the annotation element we are going to setup.
|
// Get the annotation element we are going to setup.
|
||||||
final annotationElement = new _AnnotationElement<D>()
|
final annotationElement = _AnnotationElement<D>()
|
||||||
..annotation = annotationDatum
|
..annotation = annotationDatum
|
||||||
..color = color
|
..color = color
|
||||||
..dashPattern = dashPattern
|
..dashPattern = dashPattern
|
||||||
@@ -289,7 +289,7 @@ class RangeAnnotation<D> implements ChartBehavior<D> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Animate out annotations that don't exist anymore.
|
// Animate out annotations that don't exist anymore.
|
||||||
_annotationMap.forEach((String key, _AnimatedAnnotation<D> annotation) {
|
_annotationMap.forEach((key, annotation) {
|
||||||
if (_currentKeys.contains(annotation.key) != true) {
|
if (_currentKeys.contains(annotation.key) != true) {
|
||||||
annotation.animateOut();
|
annotation.animateOut();
|
||||||
}
|
}
|
||||||
@@ -310,7 +310,7 @@ class RangeAnnotation<D> implements ChartBehavior<D> {
|
|||||||
final startPosition = (axis.getLocation(startValue) * 100).round() / 100;
|
final startPosition = (axis.getLocation(startValue) * 100).round() / 100;
|
||||||
final endPosition = (axis.getLocation(endValue) * 100).round() / 100;
|
final endPosition = (axis.getLocation(endValue) * 100).round() / 100;
|
||||||
|
|
||||||
return new _DatumAnnotation(
|
return _DatumAnnotation(
|
||||||
startPosition: startPosition,
|
startPosition: startPosition,
|
||||||
endPosition: endPosition,
|
endPosition: endPosition,
|
||||||
axisType: axisType);
|
axisType: axisType);
|
||||||
@@ -335,7 +335,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
Rectangle<int> get drawBounds => _drawAreaBounds;
|
Rectangle<int> get drawBounds => _drawAreaBounds;
|
||||||
|
|
||||||
GraphicsFactory _graphicsFactory;
|
GraphicsFactory graphicsFactory;
|
||||||
|
|
||||||
/// Store a map of series drawn on the chart, mapped by series name.
|
/// Store a map of series drawn on the chart, mapped by series name.
|
||||||
///
|
///
|
||||||
@@ -347,7 +347,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
@required this.defaultColor,
|
@required this.defaultColor,
|
||||||
@required this.labelPadding,
|
@required this.labelPadding,
|
||||||
@required this.chart,
|
@required this.chart,
|
||||||
}) : this.layoutConfig = new LayoutViewConfig(
|
}) : this.layoutConfig = LayoutViewConfig(
|
||||||
paintOrder: LayoutViewPaintOrder.rangeAnnotation,
|
paintOrder: LayoutViewPaintOrder.rangeAnnotation,
|
||||||
position: LayoutPosition.DrawArea,
|
position: LayoutPosition.DrawArea,
|
||||||
positionOrder: LayoutViewPositionOrder.drawArea);
|
positionOrder: LayoutViewPositionOrder.drawArea);
|
||||||
@@ -356,14 +356,6 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
_annotationMap = value;
|
_annotationMap = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
GraphicsFactory get graphicsFactory => _graphicsFactory;
|
|
||||||
|
|
||||||
@override
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
|
||||||
_graphicsFactory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ViewMeasuredSizes measure(int maxWidth, int maxHeight) {
|
ViewMeasuredSizes measure(int maxWidth, int maxHeight) {
|
||||||
return null;
|
return null;
|
||||||
@@ -384,16 +376,16 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
if (animationPercent == 1.0) {
|
if (animationPercent == 1.0) {
|
||||||
final keysToRemove = <String>[];
|
final keysToRemove = <String>[];
|
||||||
|
|
||||||
_annotationMap.forEach((String key, _AnimatedAnnotation<D> annotation) {
|
_annotationMap.forEach((key, annotation) {
|
||||||
if (annotation.animatingOut) {
|
if (annotation.animatingOut) {
|
||||||
keysToRemove.add(key);
|
keysToRemove.add(key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
keysToRemove.forEach((String key) => _annotationMap.remove(key));
|
keysToRemove.forEach((key) => _annotationMap.remove(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
_annotationMap.forEach((String key, _AnimatedAnnotation<D> annotation) {
|
_annotationMap.forEach((key, annotation) {
|
||||||
final annotationElement =
|
final annotationElement =
|
||||||
annotation.getCurrentAnnotation(animationPercent);
|
annotation.getCurrentAnnotation(animationPercent);
|
||||||
|
|
||||||
@@ -477,7 +469,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
switch (annotationElement.annotation.axisType) {
|
switch (annotationElement.annotation.axisType) {
|
||||||
case RangeAnnotationAxisType.domain:
|
case RangeAnnotationAxisType.domain:
|
||||||
bounds = new Rectangle<num>(
|
bounds = Rectangle<num>(
|
||||||
annotationElement.annotation.startPosition,
|
annotationElement.annotation.startPosition,
|
||||||
_drawAreaBounds.top,
|
_drawAreaBounds.top,
|
||||||
annotationElement.annotation.endPosition -
|
annotationElement.annotation.endPosition -
|
||||||
@@ -486,7 +478,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RangeAnnotationAxisType.measure:
|
case RangeAnnotationAxisType.measure:
|
||||||
bounds = new Rectangle<num>(
|
bounds = Rectangle<num>(
|
||||||
_drawAreaBounds.left,
|
_drawAreaBounds.left,
|
||||||
annotationElement.annotation.endPosition,
|
annotationElement.annotation.endPosition,
|
||||||
_drawAreaBounds.width,
|
_drawAreaBounds.width,
|
||||||
@@ -505,16 +497,16 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
switch (annotationElement.annotation.axisType) {
|
switch (annotationElement.annotation.axisType) {
|
||||||
case RangeAnnotationAxisType.domain:
|
case RangeAnnotationAxisType.domain:
|
||||||
points.add(new Point<num>(
|
points.add(Point<num>(
|
||||||
annotationElement.annotation.startPosition, _drawAreaBounds.top));
|
annotationElement.annotation.startPosition, _drawAreaBounds.top));
|
||||||
points.add(new Point<num>(
|
points.add(Point<num>(
|
||||||
annotationElement.annotation.endPosition, _drawAreaBounds.bottom));
|
annotationElement.annotation.endPosition, _drawAreaBounds.bottom));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RangeAnnotationAxisType.measure:
|
case RangeAnnotationAxisType.measure:
|
||||||
points.add(new Point<num>(
|
points.add(Point<num>(
|
||||||
_drawAreaBounds.left, annotationElement.annotation.startPosition));
|
_drawAreaBounds.left, annotationElement.annotation.startPosition));
|
||||||
points.add(new Point<num>(
|
points.add(Point<num>(
|
||||||
_drawAreaBounds.right, annotationElement.annotation.endPosition));
|
_drawAreaBounds.right, annotationElement.annotation.endPosition));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -655,7 +647,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
switch (calculatedLabelPosition) {
|
switch (calculatedLabelPosition) {
|
||||||
case AnnotationLabelPosition.margin:
|
case AnnotationLabelPosition.margin:
|
||||||
case AnnotationLabelPosition.auto:
|
case AnnotationLabelPosition.auto:
|
||||||
throw new ArgumentError(_unresolvedAutoMessage);
|
throw ArgumentError(_unresolvedAutoMessage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnnotationLabelPosition.outside:
|
case AnnotationLabelPosition.outside:
|
||||||
@@ -685,7 +677,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Point<int>(labelX.round(), labelY.round());
|
return Point<int>(labelX.round(), labelY.round());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the resolved location for a vertical domain annotation label element.
|
/// Gets the resolved location for a vertical domain annotation label element.
|
||||||
@@ -734,7 +726,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
switch (calculatedLabelPosition) {
|
switch (calculatedLabelPosition) {
|
||||||
case AnnotationLabelPosition.margin:
|
case AnnotationLabelPosition.margin:
|
||||||
case AnnotationLabelPosition.auto:
|
case AnnotationLabelPosition.auto:
|
||||||
throw new ArgumentError(_unresolvedAutoMessage);
|
throw ArgumentError(_unresolvedAutoMessage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnnotationLabelPosition.outside:
|
case AnnotationLabelPosition.outside:
|
||||||
@@ -764,7 +756,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Point<int>(labelX.round(), labelY.round());
|
return Point<int>(labelX.round(), labelY.round());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the resolved location for a measure annotation label element.
|
/// Gets the resolved location for a measure annotation label element.
|
||||||
@@ -834,7 +826,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
switch (calculatedLabelPosition) {
|
switch (calculatedLabelPosition) {
|
||||||
case AnnotationLabelPosition.margin:
|
case AnnotationLabelPosition.margin:
|
||||||
case AnnotationLabelPosition.auto:
|
case AnnotationLabelPosition.auto:
|
||||||
throw new ArgumentError(_unresolvedAutoMessage);
|
throw ArgumentError(_unresolvedAutoMessage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnnotationLabelPosition.outside:
|
case AnnotationLabelPosition.outside:
|
||||||
@@ -858,7 +850,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Point<int>(labelX.round(), labelY.round());
|
return Point<int>(labelX.round(), labelY.round());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the resolved location for a vertical measure annotation label
|
/// Gets the resolved location for a vertical measure annotation label
|
||||||
@@ -920,7 +912,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
switch (calculatedLabelPosition) {
|
switch (calculatedLabelPosition) {
|
||||||
case AnnotationLabelPosition.margin:
|
case AnnotationLabelPosition.margin:
|
||||||
case AnnotationLabelPosition.auto:
|
case AnnotationLabelPosition.auto:
|
||||||
throw new ArgumentError(_unresolvedAutoMessage);
|
throw ArgumentError(_unresolvedAutoMessage);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AnnotationLabelPosition.outside:
|
case AnnotationLabelPosition.outside:
|
||||||
@@ -944,7 +936,7 @@ class _RangeAnnotationLayoutView<D> extends LayoutView {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Point<int>(labelX.round(), labelY.round());
|
return Point<int>(labelX.round(), labelY.round());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resolves [AnnotationLabelPosition.auto] configuration for an annotation
|
/// Resolves [AnnotationLabelPosition.auto] configuration for an annotation
|
||||||
@@ -1014,7 +1006,7 @@ class _DatumAnnotation {
|
|||||||
|
|
||||||
factory _DatumAnnotation.from(_DatumAnnotation other,
|
factory _DatumAnnotation.from(_DatumAnnotation other,
|
||||||
[double startPosition, double endPosition]) {
|
[double startPosition, double endPosition]) {
|
||||||
return new _DatumAnnotation(
|
return _DatumAnnotation(
|
||||||
startPosition: startPosition ?? other.startPosition,
|
startPosition: startPosition ?? other.startPosition,
|
||||||
endPosition: endPosition ?? other.endPosition,
|
endPosition: endPosition ?? other.endPosition,
|
||||||
axisType: other.axisType);
|
axisType: other.axisType);
|
||||||
@@ -1035,9 +1027,9 @@ class _AnnotationElement<D> {
|
|||||||
double strokeWidthPx;
|
double strokeWidthPx;
|
||||||
|
|
||||||
_AnnotationElement<D> clone() {
|
_AnnotationElement<D> clone() {
|
||||||
return new _AnnotationElement<D>()
|
return _AnnotationElement<D>()
|
||||||
..annotation = new _DatumAnnotation.from(annotation)
|
..annotation = _DatumAnnotation.from(annotation)
|
||||||
..color = color != null ? new Color.fromOther(color: color) : null
|
..color = color != null ? Color.fromOther(color: color) : null
|
||||||
..startLabel = this.startLabel
|
..startLabel = this.startLabel
|
||||||
..endLabel = this.endLabel
|
..endLabel = this.endLabel
|
||||||
..isRange = this.isRange
|
..isRange = this.isRange
|
||||||
@@ -1065,7 +1057,7 @@ class _AnnotationElement<D> {
|
|||||||
previousAnnotation.endPosition;
|
previousAnnotation.endPosition;
|
||||||
|
|
||||||
annotation =
|
annotation =
|
||||||
new _DatumAnnotation.from(targetAnnotation, startPosition, endPosition);
|
_DatumAnnotation.from(targetAnnotation, startPosition, endPosition);
|
||||||
|
|
||||||
color = getAnimatedColor(previous.color, target.color, animationPercent);
|
color = getAnimatedColor(previous.color, target.color, animationPercent);
|
||||||
|
|
||||||
@@ -1128,7 +1120,7 @@ class RangeAnnotationTester<D> {
|
|||||||
RangeAnnotationTester(this.behavior);
|
RangeAnnotationTester(this.behavior);
|
||||||
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
set graphicsFactory(GraphicsFactory value) {
|
||||||
behavior._view._graphicsFactory = value;
|
behavior._view.graphicsFactory = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
mockLayout(Rectangle<int> bounds) {
|
mockLayout(Rectangle<int> bounds) {
|
||||||
@@ -1148,7 +1140,7 @@ class RangeAnnotationTester<D> {
|
|||||||
AnnotationLabelPosition labelPosition}) {
|
AnnotationLabelPosition labelPosition}) {
|
||||||
var exists = false;
|
var exists = false;
|
||||||
|
|
||||||
behavior._annotationMap.forEach((String key, _AnimatedAnnotation<D> a) {
|
behavior._annotationMap.forEach((key, a) {
|
||||||
final currentAnnotation = a._currentAnnotation;
|
final currentAnnotation = a._currentAnnotation;
|
||||||
final annotation = currentAnnotation.annotation;
|
final annotation = currentAnnotation.annotation;
|
||||||
|
|
||||||
@@ -1222,7 +1214,7 @@ class RangeAnnotationSegment<D> extends AnnotationSegment<D> {
|
|||||||
labelStyleSpec: labelStyleSpec);
|
labelStyleSpec: labelStyleSpec);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get key => 'r::${axisType}::${axisId}::${startValue}::${endValue}';
|
String get key => 'r::$axisType::$axisId::$startValue::$endValue';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Data for a chart line annotation.
|
/// Data for a chart line annotation.
|
||||||
@@ -1253,7 +1245,7 @@ class LineAnnotationSegment<D> extends AnnotationSegment<D> {
|
|||||||
labelStyleSpec: labelStyleSpec);
|
labelStyleSpec: labelStyleSpec);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get key => 'l::${axisType}::${axisId}::${value}';
|
String get key => 'l::$axisType::$axisId::$value';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Axis type for an annotation.
|
/// Axis type for an annotation.
|
||||||
|
|||||||
@@ -47,11 +47,10 @@ class LockSelection<D> implements ChartBehavior<D> {
|
|||||||
// Setup the appropriate gesture listening.
|
// Setup the appropriate gesture listening.
|
||||||
switch (this.eventTrigger) {
|
switch (this.eventTrigger) {
|
||||||
case SelectionTrigger.tap:
|
case SelectionTrigger.tap:
|
||||||
_listener =
|
_listener = GestureListener(onTapTest: _onTapTest, onTap: _onSelect);
|
||||||
new GestureListener(onTapTest: _onTapTest, onTap: _onSelect);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentError('LockSelection does not support the event '
|
throw ArgumentError('LockSelection does not support the event '
|
||||||
'trigger "${this.eventTrigger}"');
|
'trigger "${this.eventTrigger}"');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,11 +107,10 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
// Setup the appropriate gesture listening.
|
// Setup the appropriate gesture listening.
|
||||||
switch (this.eventTrigger) {
|
switch (this.eventTrigger) {
|
||||||
case SelectionTrigger.tap:
|
case SelectionTrigger.tap:
|
||||||
_listener =
|
_listener = GestureListener(onTapTest: _onTapTest, onTap: _onSelect);
|
||||||
new GestureListener(onTapTest: _onTapTest, onTap: _onSelect);
|
|
||||||
break;
|
break;
|
||||||
case SelectionTrigger.tapAndDrag:
|
case SelectionTrigger.tapAndDrag:
|
||||||
_listener = new GestureListener(
|
_listener = GestureListener(
|
||||||
onTapTest: _onTapTest,
|
onTapTest: _onTapTest,
|
||||||
onTap: _onSelect,
|
onTap: _onSelect,
|
||||||
onDragStart: _onSelect,
|
onDragStart: _onSelect,
|
||||||
@@ -119,7 +118,7 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
case SelectionTrigger.pressHold:
|
case SelectionTrigger.pressHold:
|
||||||
_listener = new GestureListener(
|
_listener = GestureListener(
|
||||||
onTapTest: _onTapTest,
|
onTapTest: _onTapTest,
|
||||||
onLongPress: _onSelect,
|
onLongPress: _onSelect,
|
||||||
onDragStart: _onSelect,
|
onDragStart: _onSelect,
|
||||||
@@ -127,7 +126,7 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
onDragEnd: _onDeselectAll);
|
onDragEnd: _onDeselectAll);
|
||||||
break;
|
break;
|
||||||
case SelectionTrigger.longPressHold:
|
case SelectionTrigger.longPressHold:
|
||||||
_listener = new GestureListener(
|
_listener = GestureListener(
|
||||||
onTapTest: _onTapTest,
|
onTapTest: _onTapTest,
|
||||||
onLongPress: _onLongPressSelect,
|
onLongPress: _onLongPressSelect,
|
||||||
onDragStart: _onSelect,
|
onDragStart: _onSelect,
|
||||||
@@ -136,7 +135,7 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
break;
|
break;
|
||||||
case SelectionTrigger.hover:
|
case SelectionTrigger.hover:
|
||||||
default:
|
default:
|
||||||
_listener = new GestureListener(onHover: _onSelect);
|
_listener = GestureListener(onHover: _onSelect);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,11 +170,10 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
details[0].domainDistance <= maximumDomainDistancePx) {
|
details[0].domainDistance <= maximumDomainDistancePx) {
|
||||||
seriesDatumList = expandToDomain
|
seriesDatumList = expandToDomain
|
||||||
? _expandToDomain(details.first)
|
? _expandToDomain(details.first)
|
||||||
: [new SeriesDatum<D>(details.first.series, details.first.datum)];
|
: [SeriesDatum<D>(details.first.series, details.first.datum)];
|
||||||
|
|
||||||
// Filter out points from overlay series.
|
// Filter out points from overlay series.
|
||||||
seriesDatumList
|
seriesDatumList.removeWhere((datum) => datum.series.overlaySeries);
|
||||||
.removeWhere((SeriesDatum<D> datum) => datum.series.overlaySeries);
|
|
||||||
|
|
||||||
if (selectClosestSeries && seriesList.isEmpty) {
|
if (selectClosestSeries && seriesList.isEmpty) {
|
||||||
if (details.first.series.overlaySeries) {
|
if (details.first.series.overlaySeries) {
|
||||||
@@ -184,7 +182,7 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
// copy of the list by domain distance because we do not want to
|
// copy of the list by domain distance because we do not want to
|
||||||
// re-order the actual return values here.
|
// re-order the actual return values here.
|
||||||
final sortedSeriesDatumList =
|
final sortedSeriesDatumList =
|
||||||
new List<SeriesDatum<D>>.from(seriesDatumList);
|
List<SeriesDatum<D>>.from(seriesDatumList);
|
||||||
sortedSeriesDatumList.sort((a, b) =>
|
sortedSeriesDatumList.sort((a, b) =>
|
||||||
a.datum.domainDistance.compareTo(b.datum.domainDistance));
|
a.datum.domainDistance.compareTo(b.datum.domainDistance));
|
||||||
seriesList.add(sortedSeriesDatumList.first.series);
|
seriesList.add(sortedSeriesDatumList.first.series);
|
||||||
@@ -215,7 +213,7 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
List<SeriesDatum<D>> _expandToDomain(DatumDetails<D> nearestDetails) {
|
List<SeriesDatum<D>> _expandToDomain(DatumDetails<D> nearestDetails) {
|
||||||
// Make sure that the "nearest" datum is at the top of the list.
|
// Make sure that the "nearest" datum is at the top of the list.
|
||||||
final data = <SeriesDatum<D>>[
|
final data = <SeriesDatum<D>>[
|
||||||
new SeriesDatum(nearestDetails.series, nearestDetails.datum)
|
SeriesDatum(nearestDetails.series, nearestDetails.datum)
|
||||||
];
|
];
|
||||||
final nearestDomain = nearestDetails.domain;
|
final nearestDomain = nearestDetails.domain;
|
||||||
|
|
||||||
@@ -236,7 +234,7 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (domain == nearestDomain) {
|
if (domain == nearestDomain) {
|
||||||
data.add(new SeriesDatum(series, datum));
|
data.add(SeriesDatum(series, datum));
|
||||||
} else if (testBounds) {
|
} else if (testBounds) {
|
||||||
final domainLowerBound = domainLowerBoundFn(i);
|
final domainLowerBound = domainLowerBoundFn(i);
|
||||||
final domainUpperBound = domainUpperBoundFn(i);
|
final domainUpperBound = domainUpperBoundFn(i);
|
||||||
@@ -261,7 +259,7 @@ class SelectNearest<D> implements ChartBehavior<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (addDatum) {
|
if (addDatum) {
|
||||||
data.add(new SeriesDatum(series, datum));
|
data.add(SeriesDatum(series, datum));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,9 +153,9 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
this.snapToDatum = false,
|
this.snapToDatum = false,
|
||||||
SliderStyle style,
|
SliderStyle style,
|
||||||
this.layoutPaintOrder = LayoutViewPaintOrder.slider}) {
|
this.layoutPaintOrder = LayoutViewPaintOrder.slider}) {
|
||||||
_handleRenderer = handleRenderer ?? new RectSymbolRenderer();
|
_handleRenderer = handleRenderer ?? RectSymbolRenderer();
|
||||||
_roleId = roleId ?? '';
|
_roleId = roleId ?? '';
|
||||||
_style = style ?? new SliderStyle();
|
_style = style ?? SliderStyle();
|
||||||
|
|
||||||
_domainValue = initialDomainValue;
|
_domainValue = initialDomainValue;
|
||||||
if (_domainValue != null) {
|
if (_domainValue != null) {
|
||||||
@@ -165,7 +165,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
// Setup the appropriate gesture listening.
|
// Setup the appropriate gesture listening.
|
||||||
switch (this.eventTrigger) {
|
switch (this.eventTrigger) {
|
||||||
case SelectionTrigger.tapAndDrag:
|
case SelectionTrigger.tapAndDrag:
|
||||||
_gestureListener = new GestureListener(
|
_gestureListener = GestureListener(
|
||||||
onTapTest: _onTapTest,
|
onTapTest: _onTapTest,
|
||||||
onTap: _onSelect,
|
onTap: _onSelect,
|
||||||
onDragStart: _onSelect,
|
onDragStart: _onSelect,
|
||||||
@@ -173,7 +173,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
onDragEnd: _onDragEnd);
|
onDragEnd: _onDragEnd);
|
||||||
break;
|
break;
|
||||||
case SelectionTrigger.pressHold:
|
case SelectionTrigger.pressHold:
|
||||||
_gestureListener = new GestureListener(
|
_gestureListener = GestureListener(
|
||||||
onTapTest: _onTapTest,
|
onTapTest: _onTapTest,
|
||||||
onLongPress: _onSelect,
|
onLongPress: _onSelect,
|
||||||
onDragStart: _onSelect,
|
onDragStart: _onSelect,
|
||||||
@@ -181,7 +181,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
onDragEnd: _onDragEnd);
|
onDragEnd: _onDragEnd);
|
||||||
break;
|
break;
|
||||||
case SelectionTrigger.longPressHold:
|
case SelectionTrigger.longPressHold:
|
||||||
_gestureListener = new GestureListener(
|
_gestureListener = GestureListener(
|
||||||
onTapTest: _onTapTest,
|
onTapTest: _onTapTest,
|
||||||
onLongPress: _onLongPressSelect,
|
onLongPress: _onLongPressSelect,
|
||||||
onDragStart: _onSelect,
|
onDragStart: _onSelect,
|
||||||
@@ -189,21 +189,20 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
onDragEnd: _onDragEnd);
|
onDragEnd: _onDragEnd);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentError('Slider does not support the event trigger '
|
throw ArgumentError('Slider does not support the event trigger '
|
||||||
'"${this.eventTrigger}"');
|
'"${this.eventTrigger}"');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up chart draw cycle listeners.
|
// Set up chart draw cycle listeners.
|
||||||
_lifecycleListener = new LifecycleListener<D>(
|
_lifecycleListener = LifecycleListener<D>(
|
||||||
onData: _setInitialDragState,
|
onData: _setInitialDragState,
|
||||||
onAxisConfigured: _updateViewData,
|
onAxisConfigured: _updateViewData,
|
||||||
onPostrender: _fireChangeEvent,
|
onPostrender: _fireChangeEvent,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Set up slider event listeners.
|
// Set up slider event listeners.
|
||||||
_sliderEventListener =
|
_sliderEventListener = SliderEventListener<D>(onChange: onChangeCallback);
|
||||||
new SliderEventListener<D>(onChange: onChangeCallback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _onTapTest(Point<double> chartPoint) {
|
bool _onTapTest(Point<double> chartPoint) {
|
||||||
@@ -286,7 +285,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void _updateViewData() {
|
void _updateViewData() {
|
||||||
_sliderHandle ??= new _AnimatedSlider();
|
_sliderHandle ??= _AnimatedSlider();
|
||||||
|
|
||||||
// If not set in the constructor, initial position for the handle is the
|
// If not set in the constructor, initial position for the handle is the
|
||||||
// center of the draw area.
|
// center of the draw area.
|
||||||
@@ -299,10 +298,10 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
_moveSliderToDomain(_domainValue);
|
_moveSliderToDomain(_domainValue);
|
||||||
|
|
||||||
// Move the handle to the current event position.
|
// Move the handle to the current event position.
|
||||||
final element = new _SliderElement()
|
final element = _SliderElement()
|
||||||
..domainCenterPoint =
|
..domainCenterPoint =
|
||||||
new Point<int>(_domainCenterPoint.x, _domainCenterPoint.y)
|
Point<int>(_domainCenterPoint.x, _domainCenterPoint.y)
|
||||||
..buttonBounds = new Rectangle<int>(_handleBounds.left, _handleBounds.top,
|
..buttonBounds = Rectangle<int>(_handleBounds.left, _handleBounds.top,
|
||||||
_handleBounds.width, _handleBounds.height)
|
_handleBounds.width, _handleBounds.height)
|
||||||
..fill = _style.fillColor
|
..fill = _style.fillColor
|
||||||
..stroke = _style.strokeColor
|
..stroke = _style.strokeColor
|
||||||
@@ -342,7 +341,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
|
|
||||||
// Fire the event.
|
// Fire the event.
|
||||||
_sliderEventListener.onChange(
|
_sliderEventListener.onChange(
|
||||||
new Point<int>(_domainCenterPoint.x, _domainCenterPoint.y),
|
Point<int>(_domainCenterPoint.x, _domainCenterPoint.y),
|
||||||
_domainValue,
|
_domainValue,
|
||||||
_roleId,
|
_roleId,
|
||||||
dragState);
|
dragState);
|
||||||
@@ -378,10 +377,9 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
_domainValue = _chart.domainAxis.getDomain(position.toDouble());
|
_domainValue = _chart.domainAxis.getDomain(position.toDouble());
|
||||||
|
|
||||||
if (_domainCenterPoint != null) {
|
if (_domainCenterPoint != null) {
|
||||||
_domainCenterPoint =
|
_domainCenterPoint = Point<int>(position.round(), _domainCenterPoint.y);
|
||||||
new Point<int>(position.round(), _domainCenterPoint.y);
|
|
||||||
} else {
|
} else {
|
||||||
_domainCenterPoint = new Point<int>(
|
_domainCenterPoint = Point<int>(
|
||||||
position.round(), (viewBounds.top + viewBounds.height / 2).round());
|
position.round(), (viewBounds.top + viewBounds.height / 2).round());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,12 +392,12 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
handleReferenceY = viewBounds.top;
|
handleReferenceY = viewBounds.top;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new ArgumentError('Slider does not support the handle position '
|
throw ArgumentError('Slider does not support the handle position '
|
||||||
'"${_style.handlePosition}"');
|
'"${_style.handlePosition}"');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move the slider handle along the domain axis.
|
// Move the slider handle along the domain axis.
|
||||||
_handleBounds = new Rectangle<int>(
|
_handleBounds = Rectangle<int>(
|
||||||
(_domainCenterPoint.x -
|
(_domainCenterPoint.x -
|
||||||
_style.handleSize.width / 2 +
|
_style.handleSize.width / 2 +
|
||||||
_style.handleOffset.x)
|
_style.handleOffset.x)
|
||||||
@@ -432,7 +430,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
bool _moveSliderToDomain(D domain) {
|
bool _moveSliderToDomain(D domain) {
|
||||||
final x = _chart.domainAxis.getLocation(domain);
|
final x = _chart.domainAxis.getLocation(domain);
|
||||||
|
|
||||||
return _moveSliderToPoint(new Point<double>(x, 0.0));
|
return _moveSliderToPoint(Point<double>(x, 0.0));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Programmatically moves the slider to the location of [domain] on the
|
/// Programmatically moves the slider to the location of [domain] on the
|
||||||
@@ -470,8 +468,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
@override
|
@override
|
||||||
void attachTo(BaseChart<D> chart) {
|
void attachTo(BaseChart<D> chart) {
|
||||||
if (!(chart is CartesianChart)) {
|
if (!(chart is CartesianChart)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError('Slider can only be attached to a cartesian chart.');
|
||||||
'Slider can only be attached to a cartesian chart.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_chart = chart as CartesianChart;
|
_chart = chart as CartesianChart;
|
||||||
@@ -479,7 +476,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
// Only vertical rendering is supported by this behavior.
|
// Only vertical rendering is supported by this behavior.
|
||||||
assert(_chart.vertical);
|
assert(_chart.vertical);
|
||||||
|
|
||||||
_view = new _SliderLayoutView<D>(
|
_view = _SliderLayoutView<D>(
|
||||||
layoutPaintOrder: layoutPaintOrder, handleRenderer: _handleRenderer);
|
layoutPaintOrder: layoutPaintOrder, handleRenderer: _handleRenderer);
|
||||||
|
|
||||||
chart.addView(_view);
|
chart.addView(_view);
|
||||||
@@ -496,7 +493,7 @@ class Slider<D> implements ChartBehavior<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String get role => 'Slider-${eventTrigger.toString()}-${_roleId}';
|
String get role => 'Slider-${eventTrigger.toString()}-$_roleId';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Style configuration for a [Slider] behavior.
|
/// Style configuration for a [Slider] behavior.
|
||||||
@@ -572,7 +569,7 @@ class _SliderLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
Rectangle<int> get drawBounds => _drawAreaBounds;
|
Rectangle<int> get drawBounds => _drawAreaBounds;
|
||||||
|
|
||||||
GraphicsFactory _graphicsFactory;
|
GraphicsFactory graphicsFactory;
|
||||||
|
|
||||||
/// Renderer for the handle. Defaults to a rectangle.
|
/// Renderer for the handle. Defaults to a rectangle.
|
||||||
SymbolRenderer _handleRenderer;
|
SymbolRenderer _handleRenderer;
|
||||||
@@ -582,7 +579,7 @@ class _SliderLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
_SliderLayoutView(
|
_SliderLayoutView(
|
||||||
{@required int layoutPaintOrder, @required SymbolRenderer handleRenderer})
|
{@required int layoutPaintOrder, @required SymbolRenderer handleRenderer})
|
||||||
: this.layoutConfig = new LayoutViewConfig(
|
: this.layoutConfig = LayoutViewConfig(
|
||||||
paintOrder: layoutPaintOrder,
|
paintOrder: layoutPaintOrder,
|
||||||
position: LayoutPosition.DrawArea,
|
position: LayoutPosition.DrawArea,
|
||||||
positionOrder: LayoutViewPositionOrder.drawArea),
|
positionOrder: LayoutViewPositionOrder.drawArea),
|
||||||
@@ -592,14 +589,6 @@ class _SliderLayoutView<D> extends LayoutView {
|
|||||||
_sliderHandle = value;
|
_sliderHandle = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
GraphicsFactory get graphicsFactory => _graphicsFactory;
|
|
||||||
|
|
||||||
@override
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
|
||||||
_graphicsFactory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ViewMeasuredSizes measure(int maxWidth, int maxHeight) {
|
ViewMeasuredSizes measure(int maxWidth, int maxHeight) {
|
||||||
return null;
|
return null;
|
||||||
@@ -616,10 +605,8 @@ class _SliderLayoutView<D> extends LayoutView {
|
|||||||
|
|
||||||
canvas.drawLine(
|
canvas.drawLine(
|
||||||
points: [
|
points: [
|
||||||
new Point<num>(
|
Point<num>(sliderElement.domainCenterPoint.x, _drawAreaBounds.top),
|
||||||
sliderElement.domainCenterPoint.x, _drawAreaBounds.top),
|
Point<num>(sliderElement.domainCenterPoint.x, _drawAreaBounds.bottom),
|
||||||
new Point<num>(
|
|
||||||
sliderElement.domainCenterPoint.x, _drawAreaBounds.bottom),
|
|
||||||
],
|
],
|
||||||
stroke: sliderElement.stroke,
|
stroke: sliderElement.stroke,
|
||||||
strokeWidthPx: sliderElement.strokeWidthPx);
|
strokeWidthPx: sliderElement.strokeWidthPx);
|
||||||
@@ -646,7 +633,7 @@ class _SliderElement<D> {
|
|||||||
double strokeWidthPx;
|
double strokeWidthPx;
|
||||||
|
|
||||||
_SliderElement<D> clone() {
|
_SliderElement<D> clone() {
|
||||||
return new _SliderElement<D>()
|
return _SliderElement<D>()
|
||||||
..domainCenterPoint = this.domainCenterPoint
|
..domainCenterPoint = this.domainCenterPoint
|
||||||
..buttonBounds = this.buttonBounds
|
..buttonBounds = this.buttonBounds
|
||||||
..fill = this.fill
|
..fill = this.fill
|
||||||
@@ -668,7 +655,7 @@ class _SliderElement<D> {
|
|||||||
final y = ((targetPoint.y - previousPoint.y) * animationPercent) +
|
final y = ((targetPoint.y - previousPoint.y) * animationPercent) +
|
||||||
previousPoint.y;
|
previousPoint.y;
|
||||||
|
|
||||||
domainCenterPoint = new Point<int>(x.round(), y.round());
|
domainCenterPoint = Point<int>(x.round(), y.round());
|
||||||
|
|
||||||
final previousBounds = localPrevious.buttonBounds;
|
final previousBounds = localPrevious.buttonBounds;
|
||||||
final targetBounds = localTarget.buttonBounds;
|
final targetBounds = localTarget.buttonBounds;
|
||||||
@@ -685,7 +672,7 @@ class _SliderElement<D> {
|
|||||||
((targetBounds.left - previousBounds.left) * animationPercent) +
|
((targetBounds.left - previousBounds.left) * animationPercent) +
|
||||||
previousBounds.left;
|
previousBounds.left;
|
||||||
|
|
||||||
buttonBounds = new Rectangle<int>(left.round(), top.round(),
|
buttonBounds = Rectangle<int>(left.round(), top.round(),
|
||||||
(right - left).round(), (bottom - top).round());
|
(right - left).round(), (bottom - top).round());
|
||||||
|
|
||||||
fill = getAnimatedColor(previous.fill, target.fill, animationPercent);
|
fill = getAnimatedColor(previous.fill, target.fill, animationPercent);
|
||||||
@@ -726,7 +713,7 @@ class _AnimatedSlider<D> {
|
|||||||
final bottom = targetBounds.bottom;
|
final bottom = targetBounds.bottom;
|
||||||
final left = right;
|
final left = right;
|
||||||
|
|
||||||
newTarget.buttonBounds = new Rectangle<int>(left.round(), top.round(),
|
newTarget.buttonBounds = Rectangle<int>(left.round(), top.round(),
|
||||||
(right - left).round(), (bottom - top).round());
|
(right - left).round(), (bottom - top).round());
|
||||||
|
|
||||||
// Animate the stroke width to 0 so that we don't get a lingering line after
|
// Animate the stroke width to 0 so that we don't get a lingering line after
|
||||||
@@ -775,8 +762,8 @@ class SliderEventListener<D> {
|
|||||||
/// [domain] is the domain value at the slider position.
|
/// [domain] is the domain value at the slider position.
|
||||||
///
|
///
|
||||||
/// [dragState] indicates the current state of a drag event.
|
/// [dragState] indicates the current state of a drag event.
|
||||||
typedef SliderListenerCallback<D>(Point<int> point, D domain, String roleId,
|
typedef SliderListenerCallback<D> = Function(Point<int> point, D domain,
|
||||||
SliderListenerDragState dragState);
|
String roleId, SliderListenerDragState dragState);
|
||||||
|
|
||||||
/// Describes the current state of a slider change as a result of a drag event.
|
/// Describes the current state of a slider change as a result of a drag event.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ abstract class InitialHintBehavior<D> implements ChartBehavior<D> {
|
|||||||
@protected
|
@protected
|
||||||
CartesianChart<D> get chart => _chart;
|
CartesianChart<D> get chart => _chart;
|
||||||
|
|
||||||
Duration _hintDuration = new Duration(milliseconds: 3000);
|
Duration _hintDuration = Duration(milliseconds: 3000);
|
||||||
|
|
||||||
/// The amount of time to animate to the desired viewport.
|
/// The amount of time to animate to the desired viewport.
|
||||||
///
|
///
|
||||||
@@ -104,9 +104,9 @@ abstract class InitialHintBehavior<D> implements ChartBehavior<D> {
|
|||||||
double _targetViewportScalingFactor;
|
double _targetViewportScalingFactor;
|
||||||
|
|
||||||
InitialHintBehavior() {
|
InitialHintBehavior() {
|
||||||
_listener = new GestureListener(onTapTest: onTapTest);
|
_listener = GestureListener(onTapTest: onTapTest);
|
||||||
|
|
||||||
_lifecycleListener = new LifecycleListener<D>(
|
_lifecycleListener = LifecycleListener<D>(
|
||||||
onAxisConfigured: _onAxisConfigured,
|
onAxisConfigured: _onAxisConfigured,
|
||||||
onAnimationComplete: _onAnimationComplete);
|
onAnimationComplete: _onAnimationComplete);
|
||||||
}
|
}
|
||||||
@@ -114,7 +114,7 @@ abstract class InitialHintBehavior<D> implements ChartBehavior<D> {
|
|||||||
@override
|
@override
|
||||||
attachTo(BaseChart<D> chart) {
|
attachTo(BaseChart<D> chart) {
|
||||||
if (!(chart is CartesianChart)) {
|
if (!(chart is CartesianChart)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'InitialHintBehavior can only be attached to a CartesianChart');
|
'InitialHintBehavior can only be attached to a CartesianChart');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ abstract class InitialHintBehavior<D> implements ChartBehavior<D> {
|
|||||||
@override
|
@override
|
||||||
removeFrom(BaseChart<D> chart) {
|
removeFrom(BaseChart<D> chart) {
|
||||||
if (!(chart is CartesianChart)) {
|
if (!(chart is CartesianChart)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'InitialHintBehavior can only be removed from a CartesianChart');
|
'InitialHintBehavior can only be removed from a CartesianChart');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class PanBehavior<D> implements ChartBehavior<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PanBehavior() {
|
PanBehavior() {
|
||||||
_listener = new GestureListener(
|
_listener = GestureListener(
|
||||||
onTapTest: onTapTest,
|
onTapTest: onTapTest,
|
||||||
onDragStart: onDragStart,
|
onDragStart: onDragStart,
|
||||||
onDragUpdate: onDragUpdate,
|
onDragUpdate: onDragUpdate,
|
||||||
@@ -79,7 +79,7 @@ class PanBehavior<D> implements ChartBehavior<D> {
|
|||||||
@override
|
@override
|
||||||
attachTo(BaseChart<D> chart) {
|
attachTo(BaseChart<D> chart) {
|
||||||
if (!(chart is CartesianChart)) {
|
if (!(chart is CartesianChart)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'PanBehavior can only be attached to a CartesianChart');
|
'PanBehavior can only be attached to a CartesianChart');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +91,7 @@ class PanBehavior<D> implements ChartBehavior<D> {
|
|||||||
|
|
||||||
// Wrap domain axis tick provider with the panning behavior one.
|
// Wrap domain axis tick provider with the panning behavior one.
|
||||||
_domainAxisTickProvider =
|
_domainAxisTickProvider =
|
||||||
new PanningTickProvider<D>(_chart.domainAxis.tickProvider);
|
PanningTickProvider<D>(_chart.domainAxis.tickProvider);
|
||||||
_chart.domainAxis.tickProvider = _domainAxisTickProvider;
|
_chart.domainAxis.tickProvider = _domainAxisTickProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ class PanBehavior<D> implements ChartBehavior<D> {
|
|||||||
@override
|
@override
|
||||||
removeFrom(BaseChart<D> chart) {
|
removeFrom(BaseChart<D> chart) {
|
||||||
if (!(chart is CartesianChart)) {
|
if (!(chart is CartesianChart)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'PanBehavior can only be attached to a CartesianChart');
|
'PanBehavior can only be attached to a CartesianChart');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -218,4 +218,4 @@ class PanBehavior<D> implements ChartBehavior<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Callback for when panning is completed.
|
/// Callback for when panning is completed.
|
||||||
typedef void PanningCompletedCallback();
|
typedef PanningCompletedCallback = void Function();
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class PanningTickProvider<D> implements TickProvider<D> {
|
|||||||
TickHint<D> tickHint,
|
TickHint<D> tickHint,
|
||||||
}) {
|
}) {
|
||||||
if (_mode == PanningTickProviderMode.stepSizeLocked) {
|
if (_mode == PanningTickProviderMode.stepSizeLocked) {
|
||||||
tickHint = new TickHint(
|
tickHint = TickHint(
|
||||||
_ticks.first.value,
|
_ticks.first.value,
|
||||||
_ticks.last.value,
|
_ticks.last.value,
|
||||||
tickCount: _ticks.length,
|
tickCount: _ticks.length,
|
||||||
|
|||||||
@@ -72,9 +72,9 @@ class CanvasBarStack {
|
|||||||
|
|
||||||
final width = right - left;
|
final width = right - left;
|
||||||
final height = bottom - top;
|
final height = bottom - top;
|
||||||
final fullStackRect = new Rectangle(left, top, width, height);
|
final fullStackRect = Rectangle(left, top, width, height);
|
||||||
|
|
||||||
return new CanvasBarStack._internal(
|
return CanvasBarStack._internal(
|
||||||
segments,
|
segments,
|
||||||
radius: radius,
|
radius: radius,
|
||||||
stackedBarPadding: stackedBarPadding,
|
stackedBarPadding: stackedBarPadding,
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ Color getAnimatedColor(Color previous, Color target, double animationPercent) {
|
|||||||
var b = (((target.b - previous.b) * animationPercent) + previous.b).round();
|
var b = (((target.b - previous.b) * animationPercent) + previous.b).round();
|
||||||
var a = (((target.a - previous.a) * animationPercent) + previous.a).round();
|
var a = (((target.a - previous.a) * animationPercent) + previous.a).round();
|
||||||
|
|
||||||
return new Color(a: a, r: r, g: g, b: b);
|
return Color(a: a, r: r, g: g, b: b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Defines the pattern for a color fill.
|
/// Defines the pattern for a color fill.
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ import '../../common/color.dart' show Color;
|
|||||||
import '../../common/symbol_renderer.dart' show SymbolRenderer;
|
import '../../common/symbol_renderer.dart' show SymbolRenderer;
|
||||||
import 'processed_series.dart' show ImmutableSeries;
|
import 'processed_series.dart' show ImmutableSeries;
|
||||||
|
|
||||||
typedef String DomainFormatter<D>(D domain);
|
typedef DomainFormatter<D> = String Function(D domain);
|
||||||
typedef String MeasureFormatter(num measure);
|
typedef MeasureFormatter = String Function(num measure);
|
||||||
|
|
||||||
/// Represents processed rendering details for a data point from a series.
|
/// Represents processed rendering details for a data point from a series.
|
||||||
class DatumDetails<D> {
|
class DatumDetails<D> {
|
||||||
@@ -183,7 +183,7 @@ class DatumDetails<D> {
|
|||||||
double radiusPx,
|
double radiusPx,
|
||||||
SymbolRenderer symbolRenderer,
|
SymbolRenderer symbolRenderer,
|
||||||
double strokeWidthPx}) {
|
double strokeWidthPx}) {
|
||||||
return new DatumDetails<D>(
|
return DatumDetails<D>(
|
||||||
datum: datum ?? other.datum,
|
datum: datum ?? other.datum,
|
||||||
index: index ?? other.index,
|
index: index ?? other.index,
|
||||||
domain: domain ?? other.domain,
|
domain: domain ?? other.domain,
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class MutableSeries<D> extends ImmutableSeries<D> {
|
|||||||
AccessorFn<TextStyleSpec> insideLabelStyleAccessorFn;
|
AccessorFn<TextStyleSpec> insideLabelStyleAccessorFn;
|
||||||
AccessorFn<TextStyleSpec> outsideLabelStyleAccessorFn;
|
AccessorFn<TextStyleSpec> outsideLabelStyleAccessorFn;
|
||||||
|
|
||||||
final _attrs = new SeriesAttributes();
|
final _attrs = SeriesAttributes();
|
||||||
|
|
||||||
Axis measureAxis;
|
Axis measureAxis;
|
||||||
Axis domainAxis;
|
Axis domainAxis;
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ class SelectionModel<D> {
|
|||||||
|
|
||||||
/// Create a deep copy of the selection model.
|
/// Create a deep copy of the selection model.
|
||||||
SelectionModel.fromOther(SelectionModel<D> other) {
|
SelectionModel.fromOther(SelectionModel<D> other) {
|
||||||
_selectedDatum = new List.from(other._selectedDatum);
|
_selectedDatum = List.from(other._selectedDatum);
|
||||||
_selectedSeries = new List.from(other._selectedSeries);
|
_selectedSeries = List.from(other._selectedSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create selection model from configuration.
|
/// Create selection model from configuration.
|
||||||
@@ -64,8 +64,8 @@ class SelectionModel<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add to list of selected series.
|
// Add to list of selected series.
|
||||||
_selectedSeries.addAll(seriesList.where((ImmutableSeries<D> series) =>
|
_selectedSeries.addAll(seriesList
|
||||||
selectedDataMap.keys.contains(series.id)));
|
.where((series) => selectedDataMap.keys.contains(series.id)));
|
||||||
|
|
||||||
// Add to list of selected data.
|
// Add to list of selected data.
|
||||||
for (ImmutableSeries<D> series in seriesList) {
|
for (ImmutableSeries<D> series in seriesList) {
|
||||||
@@ -76,7 +76,7 @@ class SelectionModel<D> {
|
|||||||
final datum = series.data[i];
|
final datum = series.data[i];
|
||||||
|
|
||||||
if (selectedDataMap[series.id].contains(domainFn(i))) {
|
if (selectedDataMap[series.id].contains(domainFn(i))) {
|
||||||
_selectedDatum.add(new SeriesDatum(series, datum));
|
_selectedDatum.add(SeriesDatum(series, datum));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,11 +86,11 @@ class SelectionModel<D> {
|
|||||||
// Add to list of selected series, if it does not already exist.
|
// Add to list of selected series, if it does not already exist.
|
||||||
if (selectedSeriesConfig != null) {
|
if (selectedSeriesConfig != null) {
|
||||||
final remainingSeriesToAdd = selectedSeriesConfig
|
final remainingSeriesToAdd = selectedSeriesConfig
|
||||||
.where((String seriesId) => !selectedSeries.contains(seriesId))
|
.where((seriesId) => !selectedSeries.contains(seriesId))
|
||||||
.toList();
|
.toList();
|
||||||
|
|
||||||
_selectedSeries.addAll(seriesList.where((ImmutableSeries<D> series) =>
|
_selectedSeries.addAll(seriesList
|
||||||
remainingSeriesToAdd.contains(series.id)));
|
.where((series) => remainingSeriesToAdd.contains(series.id)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,14 +99,13 @@ class SelectionModel<D> {
|
|||||||
|
|
||||||
bool isDatumSelected(ImmutableSeries<D> series, int index) {
|
bool isDatumSelected(ImmutableSeries<D> series, int index) {
|
||||||
final datum = index == null ? null : series.data[index];
|
final datum = index == null ? null : series.data[index];
|
||||||
return _selectedDatum.contains(new SeriesDatum(series, datum));
|
return _selectedDatum.contains(SeriesDatum(series, datum));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the selected [SeriesDatum] for this [SelectionModel].
|
/// Returns the selected [SeriesDatum] for this [SelectionModel].
|
||||||
///
|
///
|
||||||
/// This is empty by default.
|
/// This is empty by default.
|
||||||
List<SeriesDatum<D>> get selectedDatum =>
|
List<SeriesDatum<D>> get selectedDatum => List.unmodifiable(_selectedDatum);
|
||||||
new List.unmodifiable(_selectedDatum);
|
|
||||||
|
|
||||||
/// Returns true if this [SelectionModel] has a selected series.
|
/// Returns true if this [SelectionModel] has a selected series.
|
||||||
bool get hasSeriesSelection => _selectedSeries.isNotEmpty;
|
bool get hasSeriesSelection => _selectedSeries.isNotEmpty;
|
||||||
@@ -115,7 +114,7 @@ class SelectionModel<D> {
|
|||||||
///
|
///
|
||||||
/// This is empty by default.
|
/// This is empty by default.
|
||||||
List<ImmutableSeries<D>> get selectedSeries =>
|
List<ImmutableSeries<D>> get selectedSeries =>
|
||||||
new List.unmodifiable(_selectedSeries);
|
List.unmodifiable(_selectedSeries);
|
||||||
|
|
||||||
/// Returns true if this [SelectionModel] has a selected datum or series.
|
/// Returns true if this [SelectionModel] has a selected datum or series.
|
||||||
bool get hasAnySelection =>
|
bool get hasAnySelection =>
|
||||||
@@ -124,14 +123,14 @@ class SelectionModel<D> {
|
|||||||
@override
|
@override
|
||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
return other is SelectionModel &&
|
return other is SelectionModel &&
|
||||||
new ListEquality().equals(_selectedDatum, other.selectedDatum) &&
|
ListEquality().equals(_selectedDatum, other.selectedDatum) &&
|
||||||
new ListEquality().equals(_selectedSeries, other.selectedSeries);
|
ListEquality().equals(_selectedSeries, other.selectedSeries);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode {
|
int get hashCode {
|
||||||
int hashcode = new ListEquality().hash(_selectedDatum);
|
int hashcode = ListEquality().hash(_selectedDatum);
|
||||||
hashcode = hashcode * 37 + new ListEquality().hash(_selectedSeries);
|
hashcode = hashcode * 37 + ListEquality().hash(_selectedSeries);
|
||||||
return hashcode;
|
return hashcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -168,12 +167,11 @@ class MutableSelectionModel<D> extends SelectionModel<D> {
|
|||||||
_selectedSeries = seriesList;
|
_selectedSeries = seriesList;
|
||||||
|
|
||||||
// Provide a copy, so listeners get an immutable model.
|
// Provide a copy, so listeners get an immutable model.
|
||||||
final copyOfSelectionModel = new SelectionModel.fromOther(this);
|
final copyOfSelectionModel = SelectionModel.fromOther(this);
|
||||||
_updatedListeners.forEach((listener) => listener(copyOfSelectionModel));
|
_updatedListeners.forEach((listener) => listener(copyOfSelectionModel));
|
||||||
|
|
||||||
final changed =
|
final changed = !ListEquality().equals(origSelectedDatum, _selectedDatum) ||
|
||||||
!new ListEquality().equals(origSelectedDatum, _selectedDatum) ||
|
!ListEquality().equals(origSelectedSeries, _selectedSeries);
|
||||||
!new ListEquality().equals(origSelectedSeries, _selectedSeries);
|
|
||||||
if (notifyListeners && changed) {
|
if (notifyListeners && changed) {
|
||||||
_changedListeners.forEach((listener) => listener(copyOfSelectionModel));
|
_changedListeners.forEach((listener) => listener(copyOfSelectionModel));
|
||||||
}
|
}
|
||||||
@@ -220,7 +218,7 @@ class MutableSelectionModel<D> extends SelectionModel<D> {
|
|||||||
|
|
||||||
/// Callback for SelectionModel. It is triggered when the selection state
|
/// Callback for SelectionModel. It is triggered when the selection state
|
||||||
/// changes.
|
/// changes.
|
||||||
typedef SelectionModelListener<D>(SelectionModel<D> model);
|
typedef SelectionModelListener<D> = Function(SelectionModel<D> model);
|
||||||
|
|
||||||
enum SelectionModelType {
|
enum SelectionModelType {
|
||||||
/// Typical Hover or Details event for viewing the details of the selected
|
/// Typical Hover or Details event for viewing the details of the selected
|
||||||
|
|||||||
@@ -41,10 +41,10 @@ import 'series_datum.dart' show SeriesDatum;
|
|||||||
/// [rendererIdKey] can be added as an attribute to user-defined [Series]
|
/// [rendererIdKey] can be added as an attribute to user-defined [Series]
|
||||||
/// objects.
|
/// objects.
|
||||||
const AttributeKey<String> rendererIdKey =
|
const AttributeKey<String> rendererIdKey =
|
||||||
const AttributeKey<String>('SeriesRenderer.rendererId');
|
AttributeKey<String>('SeriesRenderer.rendererId');
|
||||||
|
|
||||||
const AttributeKey<SeriesRenderer> rendererKey =
|
const AttributeKey<SeriesRenderer> rendererKey =
|
||||||
const AttributeKey<SeriesRenderer>('SeriesRenderer.renderer');
|
AttributeKey<SeriesRenderer>('SeriesRenderer.renderer');
|
||||||
|
|
||||||
/// A series renderer draws one or more series of data onto a chart canvas.
|
/// A series renderer draws one or more series of data onto a chart canvas.
|
||||||
abstract class SeriesRenderer<D> extends LayoutView {
|
abstract class SeriesRenderer<D> extends LayoutView {
|
||||||
@@ -142,25 +142,17 @@ abstract class BaseSeriesRenderer<D> implements SeriesRenderer<D> {
|
|||||||
|
|
||||||
Rectangle<int> get drawBounds => _drawAreaBounds;
|
Rectangle<int> get drawBounds => _drawAreaBounds;
|
||||||
|
|
||||||
GraphicsFactory _graphicsFactory;
|
GraphicsFactory graphicsFactory;
|
||||||
|
|
||||||
BaseSeriesRenderer({
|
BaseSeriesRenderer({
|
||||||
@required this.rendererId,
|
@required this.rendererId,
|
||||||
@required int layoutPaintOrder,
|
@required int layoutPaintOrder,
|
||||||
this.symbolRenderer,
|
this.symbolRenderer,
|
||||||
}) : this.layoutConfig = new LayoutViewConfig(
|
}) : this.layoutConfig = LayoutViewConfig(
|
||||||
paintOrder: layoutPaintOrder,
|
paintOrder: layoutPaintOrder,
|
||||||
position: LayoutPosition.DrawArea,
|
position: LayoutPosition.DrawArea,
|
||||||
positionOrder: LayoutViewPositionOrder.drawArea);
|
positionOrder: LayoutViewPositionOrder.drawArea);
|
||||||
|
|
||||||
@override
|
|
||||||
GraphicsFactory get graphicsFactory => _graphicsFactory;
|
|
||||||
|
|
||||||
@override
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
|
||||||
_graphicsFactory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onAttach(BaseChart<D> chart) {}
|
void onAttach(BaseChart<D> chart) {}
|
||||||
|
|
||||||
@@ -185,7 +177,7 @@ abstract class BaseSeriesRenderer<D> implements SeriesRenderer<D> {
|
|||||||
int maxMissing = 0;
|
int maxMissing = 0;
|
||||||
bool hasSpecifiedCategory = false;
|
bool hasSpecifiedCategory = false;
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
if (series.colorFn == null) {
|
if (series.colorFn == null) {
|
||||||
// If there is no category, give it a default category to match logic.
|
// If there is no category, give it a default category to match logic.
|
||||||
String category = series.seriesCategory;
|
String category = series.seriesCategory;
|
||||||
@@ -208,7 +200,7 @@ abstract class BaseSeriesRenderer<D> implements SeriesRenderer<D> {
|
|||||||
if (!emptyCategoryUsesSinglePalette && !hasSpecifiedCategory) {
|
if (!emptyCategoryUsesSinglePalette && !hasSpecifiedCategory) {
|
||||||
final palettes = StyleFactory.style.getOrderedPalettes(maxMissing);
|
final palettes = StyleFactory.style.getOrderedPalettes(maxMissing);
|
||||||
int index = 0;
|
int index = 0;
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
if (series.colorFn == null) {
|
if (series.colorFn == null) {
|
||||||
final color = palettes[index % palettes.length].shadeDefault;
|
final color = palettes[index % palettes.length].shadeDefault;
|
||||||
index++;
|
index++;
|
||||||
@@ -227,7 +219,7 @@ abstract class BaseSeriesRenderer<D> implements SeriesRenderer<D> {
|
|||||||
// the max for any category to ensure that the gradients look appropriate.
|
// the max for any category to ensure that the gradients look appropriate.
|
||||||
final colorsByCategory = <String, List<Color>>{};
|
final colorsByCategory = <String, List<Color>>{};
|
||||||
int index = 0;
|
int index = 0;
|
||||||
missingColorCountPerCategory.keys.forEach((String category) {
|
missingColorCountPerCategory.keys.forEach((category) {
|
||||||
colorsByCategory[category] =
|
colorsByCategory[category] =
|
||||||
colorPalettes[index % colorPalettes.length].makeShades(maxMissing);
|
colorPalettes[index % colorPalettes.length].makeShades(maxMissing);
|
||||||
index++;
|
index++;
|
||||||
@@ -236,7 +228,7 @@ abstract class BaseSeriesRenderer<D> implements SeriesRenderer<D> {
|
|||||||
missingColorCountPerCategory[category] = 0;
|
missingColorCountPerCategory[category] = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
if (series.colorFn == null) {
|
if (series.colorFn == null) {
|
||||||
final category = series.seriesCategory ?? defaultCategory;
|
final category = series.seriesCategory ?? defaultCategory;
|
||||||
|
|
||||||
@@ -249,12 +241,12 @@ abstract class BaseSeriesRenderer<D> implements SeriesRenderer<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Fill color defaults to the series color if no accessor is provided.
|
// Fill color defaults to the series color if no accessor is provided.
|
||||||
series.fillColorFn ??= (int index) => series.colorFn(index);
|
series.fillColorFn ??= (index) => series.colorFn(index);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
// Fill color defaults to the series color if no accessor is provided.
|
// Fill color defaults to the series color if no accessor is provided.
|
||||||
series.fillColorFn ??= (int index) => series.colorFn(index);
|
series.fillColorFn ??= (index) => series.colorFn(index);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -346,7 +338,7 @@ abstract class BaseSeriesRenderer<D> implements SeriesRenderer<D> {
|
|||||||
var strokeWidthPx = strokeWidthPxFn != null ? strokeWidthPxFn(index) : null;
|
var strokeWidthPx = strokeWidthPxFn != null ? strokeWidthPxFn(index) : null;
|
||||||
strokeWidthPx = strokeWidthPx?.toDouble();
|
strokeWidthPx = strokeWidthPx?.toDouble();
|
||||||
|
|
||||||
final details = new DatumDetails<D>(
|
final details = DatumDetails<D>(
|
||||||
datum: seriesDatum.datum,
|
datum: seriesDatum.datum,
|
||||||
index: seriesDatum.index,
|
index: seriesDatum.index,
|
||||||
domain: domainValue,
|
domain: domainValue,
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ class LayoutConfig {
|
|||||||
/// Specs that applies to one margin.
|
/// Specs that applies to one margin.
|
||||||
class MarginSpec {
|
class MarginSpec {
|
||||||
/// [MarginSpec] that has max of 50 percent.
|
/// [MarginSpec] that has max of 50 percent.
|
||||||
static const defaultSpec = const MarginSpec._internal(null, null, null, 50);
|
static const defaultSpec = MarginSpec._internal(null, null, null, 50);
|
||||||
|
|
||||||
final int _minPixel;
|
final int _minPixel;
|
||||||
final int _maxPixel;
|
final int _maxPixel;
|
||||||
@@ -64,7 +64,7 @@ class MarginSpec {
|
|||||||
assert(minPixel <= maxPixel);
|
assert(minPixel <= maxPixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MarginSpec._internal(minPixel, maxPixel, null, null);
|
return MarginSpec._internal(minPixel, maxPixel, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create [MarginSpec] with a fixed pixel size [pixels].
|
/// Create [MarginSpec] with a fixed pixel size [pixels].
|
||||||
@@ -74,7 +74,7 @@ class MarginSpec {
|
|||||||
// Require require or higher setting if set
|
// Require require or higher setting if set
|
||||||
assert(pixels == null || pixels >= 0);
|
assert(pixels == null || pixels >= 0);
|
||||||
|
|
||||||
return new MarginSpec._internal(pixels, pixels, null, null);
|
return MarginSpec._internal(pixels, pixels, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create [MarginSpec] that specifies min/max percentage.
|
/// Create [MarginSpec] that specifies min/max percentage.
|
||||||
@@ -92,7 +92,7 @@ class MarginSpec {
|
|||||||
assert(minPercent <= maxPercent);
|
assert(minPercent <= maxPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MarginSpec._internal(null, null, minPercent, maxPercent);
|
return MarginSpec._internal(null, null, minPercent, maxPercent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the min pixels, given the [totalPixels].
|
/// Get the min pixels, given the [totalPixels].
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
|
|
||||||
/// Create a new [LayoutManager].
|
/// Create a new [LayoutManager].
|
||||||
LayoutManagerImpl({LayoutConfig config})
|
LayoutManagerImpl({LayoutConfig config})
|
||||||
: this.config = config ?? new LayoutConfig();
|
: this.config = config ?? LayoutConfig();
|
||||||
|
|
||||||
/// Add one [LayoutView].
|
/// Add one [LayoutView].
|
||||||
void addView(LayoutView view) {
|
void addView(LayoutView view) {
|
||||||
@@ -79,9 +79,9 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
@override
|
@override
|
||||||
List<LayoutView> get paintOrderedViews {
|
List<LayoutView> get paintOrderedViews {
|
||||||
if (_viewsNeedPaintSort) {
|
if (_viewsNeedPaintSort) {
|
||||||
_paintOrderedViews = new List<LayoutView>.from(_views);
|
_paintOrderedViews = List<LayoutView>.from(_views);
|
||||||
|
|
||||||
_paintOrderedViews.sort((LayoutView v1, LayoutView v2) =>
|
_paintOrderedViews.sort((v1, v2) =>
|
||||||
v1.layoutConfig.paintOrder.compareTo(v2.layoutConfig.paintOrder));
|
v1.layoutConfig.paintOrder.compareTo(v2.layoutConfig.paintOrder));
|
||||||
|
|
||||||
_viewsNeedPaintSort = false;
|
_viewsNeedPaintSort = false;
|
||||||
@@ -93,10 +93,9 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
@override
|
@override
|
||||||
List<LayoutView> get positionOrderedViews {
|
List<LayoutView> get positionOrderedViews {
|
||||||
if (_viewsNeedPositionSort) {
|
if (_viewsNeedPositionSort) {
|
||||||
_positionOrderedViews = new List<LayoutView>.from(_views);
|
_positionOrderedViews = List<LayoutView>.from(_views);
|
||||||
|
|
||||||
_positionOrderedViews.sort((LayoutView v1, LayoutView v2) => v1
|
_positionOrderedViews.sort((v1, v2) => v1.layoutConfig.positionOrder
|
||||||
.layoutConfig.positionOrder
|
|
||||||
.compareTo(v2.layoutConfig.positionOrder));
|
.compareTo(v2.layoutConfig.positionOrder));
|
||||||
|
|
||||||
_viewsNeedPositionSort = false;
|
_viewsNeedPositionSort = false;
|
||||||
@@ -114,8 +113,7 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
Rectangle<int> get drawableLayoutAreaBounds {
|
Rectangle<int> get drawableLayoutAreaBounds {
|
||||||
assert(_drawAreaBoundsOutdated == false);
|
assert(_drawAreaBoundsOutdated == false);
|
||||||
|
|
||||||
final drawableViews =
|
final drawableViews = _views.where((view) => view.isSeriesRenderer);
|
||||||
_views.where((LayoutView view) => view.isSeriesRenderer);
|
|
||||||
|
|
||||||
var componentBounds = drawableViews?.first?.componentBounds;
|
var componentBounds = drawableViews?.first?.componentBounds;
|
||||||
|
|
||||||
@@ -126,7 +124,7 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
componentBounds = new Rectangle(0, 0, 0, 0);
|
componentBounds = Rectangle(0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return componentBounds;
|
return componentBounds;
|
||||||
@@ -226,8 +224,8 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Bounds for the draw area.
|
// Bounds for the draw area.
|
||||||
_drawAreaBounds = new Rectangle(measurements.leftWidth,
|
_drawAreaBounds = Rectangle(measurements.leftWidth, measurements.topHeight,
|
||||||
measurements.topHeight, drawAreaWidth, drawAreaHeight);
|
drawAreaWidth, drawAreaHeight);
|
||||||
_drawAreaBoundsOutdated = false;
|
_drawAreaBoundsOutdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,26 +241,26 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
_viewsForPositions(LayoutPosition.Left, LayoutPosition.FullLeft);
|
_viewsForPositions(LayoutPosition.Left, LayoutPosition.FullLeft);
|
||||||
var drawAreaViews = _viewsForPositions(LayoutPosition.DrawArea);
|
var drawAreaViews = _viewsForPositions(LayoutPosition.DrawArea);
|
||||||
|
|
||||||
final fullBounds = new Rectangle(0, 0, width, height);
|
final fullBounds = Rectangle(0, 0, width, height);
|
||||||
|
|
||||||
// Layout the margins.
|
// Layout the margins.
|
||||||
new LeftMarginLayoutStrategy()
|
LeftMarginLayoutStrategy()
|
||||||
.layout(leftViews, _measurements.leftSizes, fullBounds, drawAreaBounds);
|
.layout(leftViews, _measurements.leftSizes, fullBounds, drawAreaBounds);
|
||||||
new RightMarginLayoutStrategy().layout(
|
RightMarginLayoutStrategy().layout(
|
||||||
rightViews, _measurements.rightSizes, fullBounds, drawAreaBounds);
|
rightViews, _measurements.rightSizes, fullBounds, drawAreaBounds);
|
||||||
new BottomMarginLayoutStrategy().layout(
|
BottomMarginLayoutStrategy().layout(
|
||||||
bottomViews, _measurements.bottomSizes, fullBounds, drawAreaBounds);
|
bottomViews, _measurements.bottomSizes, fullBounds, drawAreaBounds);
|
||||||
new TopMarginLayoutStrategy()
|
TopMarginLayoutStrategy()
|
||||||
.layout(topViews, _measurements.topSizes, fullBounds, drawAreaBounds);
|
.layout(topViews, _measurements.topSizes, fullBounds, drawAreaBounds);
|
||||||
|
|
||||||
// Layout the drawArea.
|
// Layout the drawArea.
|
||||||
drawAreaViews.forEach(
|
drawAreaViews
|
||||||
(LayoutView view) => view.layout(_drawAreaBounds, _drawAreaBounds));
|
.forEach((view) => view.layout(_drawAreaBounds, _drawAreaBounds));
|
||||||
}
|
}
|
||||||
|
|
||||||
Iterable<LayoutView> _viewsForPositions(LayoutPosition p1,
|
Iterable<LayoutView> _viewsForPositions(LayoutPosition p1,
|
||||||
[LayoutPosition p2]) {
|
[LayoutPosition p2]) {
|
||||||
return positionOrderedViews.where((LayoutView view) =>
|
return positionOrderedViews.where((view) =>
|
||||||
(view.layoutConfig.position == p1 ||
|
(view.layoutConfig.position == p1 ||
|
||||||
(p2 != null && view.layoutConfig.position == p2)));
|
(p2 != null && view.layoutConfig.position == p2)));
|
||||||
}
|
}
|
||||||
@@ -297,14 +295,14 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
? height - bottomHeight - topHeight
|
? height - bottomHeight - topHeight
|
||||||
: height;
|
: height;
|
||||||
|
|
||||||
var leftSizes = new LeftMarginLayoutStrategy().measure(leftViews,
|
var leftSizes = LeftMarginLayoutStrategy().measure(leftViews,
|
||||||
maxWidth: useMax ? maxLeftWidth : leftWidth,
|
maxWidth: useMax ? maxLeftWidth : leftWidth,
|
||||||
height: adjustedHeight,
|
height: adjustedHeight,
|
||||||
fullHeight: height);
|
fullHeight: height);
|
||||||
|
|
||||||
leftWidth = max(leftSizes.total, config.leftSpec.getMinPixels(width));
|
leftWidth = max(leftSizes.total, config.leftSpec.getMinPixels(width));
|
||||||
|
|
||||||
var rightSizes = new RightMarginLayoutStrategy().measure(rightViews,
|
var rightSizes = RightMarginLayoutStrategy().measure(rightViews,
|
||||||
maxWidth: useMax ? maxRightWidth : rightWidth,
|
maxWidth: useMax ? maxRightWidth : rightWidth,
|
||||||
height: adjustedHeight,
|
height: adjustedHeight,
|
||||||
fullHeight: height);
|
fullHeight: height);
|
||||||
@@ -312,20 +310,20 @@ class LayoutManagerImpl implements LayoutManager {
|
|||||||
|
|
||||||
final adjustedWidth = width - leftWidth - rightWidth;
|
final adjustedWidth = width - leftWidth - rightWidth;
|
||||||
|
|
||||||
var bottomSizes = new BottomMarginLayoutStrategy().measure(bottomViews,
|
var bottomSizes = BottomMarginLayoutStrategy().measure(bottomViews,
|
||||||
maxHeight: useMax ? maxBottomHeight : bottomHeight,
|
maxHeight: useMax ? maxBottomHeight : bottomHeight,
|
||||||
width: adjustedWidth,
|
width: adjustedWidth,
|
||||||
fullWidth: width);
|
fullWidth: width);
|
||||||
bottomHeight =
|
bottomHeight =
|
||||||
max(bottomSizes.total, config.bottomSpec.getMinPixels(height));
|
max(bottomSizes.total, config.bottomSpec.getMinPixels(height));
|
||||||
|
|
||||||
var topSizes = new TopMarginLayoutStrategy().measure(topViews,
|
var topSizes = TopMarginLayoutStrategy().measure(topViews,
|
||||||
maxHeight: useMax ? maxTopHeight : topHeight,
|
maxHeight: useMax ? maxTopHeight : topHeight,
|
||||||
width: adjustedWidth,
|
width: adjustedWidth,
|
||||||
fullWidth: width);
|
fullWidth: width);
|
||||||
topHeight = max(topSizes.total, config.topSpec.getMinPixels(height));
|
topHeight = max(topSizes.total, config.topSpec.getMinPixels(height));
|
||||||
|
|
||||||
return new _MeasuredSizes(
|
return _MeasuredSizes(
|
||||||
leftWidth: leftWidth,
|
leftWidth: leftWidth,
|
||||||
leftSizes: leftSizes,
|
leftSizes: leftSizes,
|
||||||
rightWidth: rightWidth,
|
rightWidth: rightWidth,
|
||||||
|
|||||||
@@ -39,8 +39,8 @@ class SizeList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _DesiredViewSizes {
|
class _DesiredViewSizes {
|
||||||
final preferredSizes = new SizeList();
|
final preferredSizes = SizeList();
|
||||||
final minimumSizes = new SizeList();
|
final minimumSizes = SizeList();
|
||||||
|
|
||||||
void add(int preferred, int minimum) {
|
void add(int preferred, int minimum) {
|
||||||
preferredSizes.add(preferred);
|
preferredSizes.add(preferred);
|
||||||
@@ -74,10 +74,10 @@ abstract class VerticalMarginStrategy {
|
|||||||
{@required int maxWidth,
|
{@required int maxWidth,
|
||||||
@required int height,
|
@required int height,
|
||||||
@required int fullHeight}) {
|
@required int fullHeight}) {
|
||||||
final measuredWidths = new _DesiredViewSizes();
|
final measuredWidths = _DesiredViewSizes();
|
||||||
int remainingWidth = maxWidth;
|
int remainingWidth = maxWidth;
|
||||||
|
|
||||||
views.forEach((LayoutView view) {
|
views.forEach((view) {
|
||||||
final params = view.layoutConfig;
|
final params = view.layoutConfig;
|
||||||
final viewMargin = params.viewMargin;
|
final viewMargin = params.viewMargin;
|
||||||
|
|
||||||
@@ -118,7 +118,7 @@ class LeftMarginLayoutStrategy extends VerticalMarginStrategy {
|
|||||||
var prevBoundsRight = drawAreaBounds.left;
|
var prevBoundsRight = drawAreaBounds.left;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
views.forEach((LayoutView view) {
|
views.forEach((view) {
|
||||||
final params = view.layoutConfig;
|
final params = view.layoutConfig;
|
||||||
|
|
||||||
final width = measuredSizes[i];
|
final width = measuredSizes[i];
|
||||||
@@ -133,7 +133,7 @@ class LeftMarginLayoutStrategy extends VerticalMarginStrategy {
|
|||||||
prevBoundsRight = left - params.viewMargin.leftPx;
|
prevBoundsRight = left - params.viewMargin.leftPx;
|
||||||
|
|
||||||
// Layout this component.
|
// Layout this component.
|
||||||
view.layout(new Rectangle(left, top, width, height), drawAreaBounds);
|
view.layout(Rectangle(left, top, width, height), drawAreaBounds);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
@@ -148,7 +148,7 @@ class RightMarginLayoutStrategy extends VerticalMarginStrategy {
|
|||||||
var prevBoundsLeft = drawAreaBounds.right;
|
var prevBoundsLeft = drawAreaBounds.right;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
views.forEach((LayoutView view) {
|
views.forEach((view) {
|
||||||
final params = view.layoutConfig;
|
final params = view.layoutConfig;
|
||||||
|
|
||||||
final width = measuredSizes[i];
|
final width = measuredSizes[i];
|
||||||
@@ -163,7 +163,7 @@ class RightMarginLayoutStrategy extends VerticalMarginStrategy {
|
|||||||
prevBoundsLeft = left + width + params.viewMargin.rightPx;
|
prevBoundsLeft = left + width + params.viewMargin.rightPx;
|
||||||
|
|
||||||
// Layout this component.
|
// Layout this component.
|
||||||
view.layout(new Rectangle(left, top, width, height), drawAreaBounds);
|
view.layout(Rectangle(left, top, width, height), drawAreaBounds);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
@@ -174,10 +174,10 @@ class RightMarginLayoutStrategy extends VerticalMarginStrategy {
|
|||||||
abstract class HorizontalMarginStrategy {
|
abstract class HorizontalMarginStrategy {
|
||||||
SizeList measure(Iterable<LayoutView> views,
|
SizeList measure(Iterable<LayoutView> views,
|
||||||
{@required int maxHeight, @required int width, @required int fullWidth}) {
|
{@required int maxHeight, @required int width, @required int fullWidth}) {
|
||||||
final measuredHeights = new _DesiredViewSizes();
|
final measuredHeights = _DesiredViewSizes();
|
||||||
int remainingHeight = maxHeight;
|
int remainingHeight = maxHeight;
|
||||||
|
|
||||||
views.forEach((LayoutView view) {
|
views.forEach((view) {
|
||||||
final params = view.layoutConfig;
|
final params = view.layoutConfig;
|
||||||
final viewMargin = params.viewMargin;
|
final viewMargin = params.viewMargin;
|
||||||
|
|
||||||
@@ -218,7 +218,7 @@ class TopMarginLayoutStrategy extends HorizontalMarginStrategy {
|
|||||||
var prevBoundsBottom = drawAreaBounds.top;
|
var prevBoundsBottom = drawAreaBounds.top;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
views.forEach((LayoutView view) {
|
views.forEach((view) {
|
||||||
final params = view.layoutConfig;
|
final params = view.layoutConfig;
|
||||||
|
|
||||||
final height = measuredSizes[i];
|
final height = measuredSizes[i];
|
||||||
@@ -234,7 +234,7 @@ class TopMarginLayoutStrategy extends HorizontalMarginStrategy {
|
|||||||
prevBoundsBottom = top - params.viewMargin.topPx;
|
prevBoundsBottom = top - params.viewMargin.topPx;
|
||||||
|
|
||||||
// Layout this component.
|
// Layout this component.
|
||||||
view.layout(new Rectangle(left, top, width, height), drawAreaBounds);
|
view.layout(Rectangle(left, top, width, height), drawAreaBounds);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
@@ -249,7 +249,7 @@ class BottomMarginLayoutStrategy extends HorizontalMarginStrategy {
|
|||||||
var prevBoundsTop = drawAreaBounds.bottom;
|
var prevBoundsTop = drawAreaBounds.bottom;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
views.forEach((LayoutView view) {
|
views.forEach((view) {
|
||||||
final params = view.layoutConfig;
|
final params = view.layoutConfig;
|
||||||
|
|
||||||
final height = measuredSizes[i];
|
final height = measuredSizes[i];
|
||||||
@@ -265,7 +265,7 @@ class BottomMarginLayoutStrategy extends HorizontalMarginStrategy {
|
|||||||
prevBoundsTop = top + height + params.viewMargin.bottomPx;
|
prevBoundsTop = top + height + params.viewMargin.bottomPx;
|
||||||
|
|
||||||
// Layout this component.
|
// Layout this component.
|
||||||
view.layout(new Rectangle(left, top, width, height), drawAreaBounds);
|
view.layout(Rectangle(left, top, width, height), drawAreaBounds);
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -80,8 +80,7 @@ class LayoutViewPositionOrder {
|
|||||||
/// A configuration for margin (empty space) around a layout child view.
|
/// A configuration for margin (empty space) around a layout child view.
|
||||||
class ViewMargin {
|
class ViewMargin {
|
||||||
/// A [ViewMargin] with all zero px.
|
/// A [ViewMargin] with all zero px.
|
||||||
static const empty =
|
static const empty = ViewMargin(topPx: 0, bottomPx: 0, rightPx: 0, leftPx: 0);
|
||||||
const ViewMargin(topPx: 0, bottomPx: 0, rightPx: 0, leftPx: 0);
|
|
||||||
|
|
||||||
final int topPx;
|
final int topPx;
|
||||||
final int bottomPx;
|
final int bottomPx;
|
||||||
@@ -152,7 +151,7 @@ class LayoutViewConfig {
|
|||||||
/// The measurement is tight to the component, without adding [ComponentBuffer].
|
/// The measurement is tight to the component, without adding [ComponentBuffer].
|
||||||
class ViewMeasuredSizes {
|
class ViewMeasuredSizes {
|
||||||
/// All zeroes component size.
|
/// All zeroes component size.
|
||||||
static const zero = const ViewMeasuredSizes(
|
static const zero = ViewMeasuredSizes(
|
||||||
preferredWidth: 0, preferredHeight: 0, minWidth: 0, minHeight: 0);
|
preferredWidth: 0, preferredHeight: 0, minWidth: 0, minHeight: 0);
|
||||||
|
|
||||||
final int preferredWidth;
|
final int preferredWidth;
|
||||||
|
|||||||
@@ -37,7 +37,6 @@ class LineChart extends NumericCartesianChart {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
SeriesRenderer<num> makeDefaultRenderer() {
|
SeriesRenderer<num> makeDefaultRenderer() {
|
||||||
return new LineRenderer<num>()
|
return LineRenderer<num>()..rendererId = SeriesRenderer.defaultRendererId;
|
||||||
..rendererId = SeriesRenderer.defaultRendererId;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,11 +33,10 @@ import '../scatter_plot/point_renderer.dart' show PointRenderer;
|
|||||||
import '../scatter_plot/point_renderer_config.dart' show PointRendererConfig;
|
import '../scatter_plot/point_renderer_config.dart' show PointRendererConfig;
|
||||||
import 'line_renderer_config.dart' show LineRendererConfig;
|
import 'line_renderer_config.dart' show LineRendererConfig;
|
||||||
|
|
||||||
const styleSegmentsKey = const AttributeKey<List<_LineRendererElement>>(
|
const styleSegmentsKey =
|
||||||
'LineRenderer.styleSegments');
|
AttributeKey<List<_LineRendererElement>>('LineRenderer.styleSegments');
|
||||||
|
|
||||||
const lineStackIndexKey =
|
const lineStackIndexKey = AttributeKey<int>('LineRenderer.lineStackIndex');
|
||||||
const AttributeKey<int>('LineRenderer.lineStackIndex');
|
|
||||||
|
|
||||||
class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
||||||
// Configuration used to extend the clipping area to extend the draw bounds.
|
// Configuration used to extend the clipping area to extend the draw bounds.
|
||||||
@@ -69,9 +68,9 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final _currentKeys = <String>[];
|
final _currentKeys = <String>[];
|
||||||
|
|
||||||
factory LineRenderer({String rendererId, LineRendererConfig config}) {
|
factory LineRenderer({String rendererId, LineRendererConfig config}) {
|
||||||
return new LineRenderer._internal(
|
return LineRenderer._internal(
|
||||||
rendererId: rendererId ?? 'line',
|
rendererId: rendererId ?? 'line',
|
||||||
config: config ?? new LineRendererConfig());
|
config: config ?? LineRendererConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
LineRenderer._internal({String rendererId, this.config})
|
LineRenderer._internal({String rendererId, this.config})
|
||||||
@@ -79,8 +78,8 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
rendererId: rendererId,
|
rendererId: rendererId,
|
||||||
layoutPaintOrder: config.layoutPaintOrder,
|
layoutPaintOrder: config.layoutPaintOrder,
|
||||||
symbolRenderer: config.symbolRenderer) {
|
symbolRenderer: config.symbolRenderer) {
|
||||||
_pointRenderer = new PointRenderer<D>(
|
_pointRenderer = PointRenderer<D>(
|
||||||
config: new PointRendererConfig<D>(radiusPx: this.config.radiusPx));
|
config: PointRendererConfig<D>(radiusPx: this.config.radiusPx));
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -96,13 +95,13 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
void configureSeries(List<MutableSeries<D>> seriesList) {
|
void configureSeries(List<MutableSeries<D>> seriesList) {
|
||||||
assignMissingColors(seriesList, emptyCategoryUsesSinglePalette: false);
|
assignMissingColors(seriesList, emptyCategoryUsesSinglePalette: false);
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
// Add a default area color function which applies the configured
|
// Add a default area color function which applies the configured
|
||||||
// areaOpacity value to the datum's current color.
|
// areaOpacity value to the datum's current color.
|
||||||
series.areaColorFn ??= (int index) {
|
series.areaColorFn ??= (index) {
|
||||||
final color = series.colorFn(index);
|
final color = series.colorFn(index);
|
||||||
|
|
||||||
return new Color(
|
return Color(
|
||||||
r: color.r,
|
r: color.r,
|
||||||
g: color.g,
|
g: color.g,
|
||||||
b: color.b,
|
b: color.b,
|
||||||
@@ -123,7 +122,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
series.measureUpperBoundFn != null &&
|
series.measureUpperBoundFn != null &&
|
||||||
series.measureLowerBoundFn != null);
|
series.measureLowerBoundFn != null);
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
final colorFn = series.colorFn;
|
final colorFn = series.colorFn;
|
||||||
final areaColorFn = series.areaColorFn;
|
final areaColorFn = series.areaColorFn;
|
||||||
final domainFn = series.domainFn;
|
final domainFn = series.domainFn;
|
||||||
@@ -136,7 +135,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final styleSegments = <_LineRendererElement<D>>[];
|
final styleSegments = <_LineRendererElement<D>>[];
|
||||||
var styleSegmentsIndex = 0;
|
var styleSegmentsIndex = 0;
|
||||||
|
|
||||||
final usedKeys = new Set<String>();
|
final usedKeys = Set<String>();
|
||||||
|
|
||||||
// Configure style segments for each series.
|
// Configure style segments for each series.
|
||||||
String previousSegmentKey;
|
String previousSegmentKey;
|
||||||
@@ -163,8 +162,8 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// Compare strokeWidthPx to 2 decimals of precision. Any less and you
|
// Compare strokeWidthPx to 2 decimals of precision. Any less and you
|
||||||
// can't see any difference in the canvas anyways.
|
// can't see any difference in the canvas anyways.
|
||||||
final strokeWidthPxRounded = (strokeWidthPx * 100).round() / 100;
|
final strokeWidthPxRounded = (strokeWidthPx * 100).round() / 100;
|
||||||
var styleKey = '${series.id}__${styleSegmentsIndex}__${color}'
|
var styleKey = '${series.id}__${styleSegmentsIndex}__$color'
|
||||||
'__${dashPattern}__${strokeWidthPxRounded}';
|
'__${dashPattern}__$strokeWidthPxRounded';
|
||||||
|
|
||||||
if (styleKey != previousSegmentKey) {
|
if (styleKey != previousSegmentKey) {
|
||||||
// If we have a repeated style segment, update the repeat index and
|
// If we have a repeated style segment, update the repeat index and
|
||||||
@@ -173,8 +172,8 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
if (usedKeys.isNotEmpty && usedKeys.contains(styleKey)) {
|
if (usedKeys.isNotEmpty && usedKeys.contains(styleKey)) {
|
||||||
styleSegmentsIndex++;
|
styleSegmentsIndex++;
|
||||||
|
|
||||||
styleKey = '${series.id}__${styleSegmentsIndex}__${color}'
|
styleKey = '${series.id}__${styleSegmentsIndex}__$color'
|
||||||
'__${dashPattern}__${strokeWidthPxRounded}';
|
'__${dashPattern}__$strokeWidthPxRounded';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the previous style segment extends to the current
|
// Make sure that the previous style segment extends to the current
|
||||||
@@ -185,11 +184,11 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a new style segment.
|
// Create a new style segment.
|
||||||
currentDetails = new _LineRendererElement<D>()
|
currentDetails = _LineRendererElement<D>()
|
||||||
..color = color
|
..color = color
|
||||||
..areaColor = areaColor
|
..areaColor = areaColor
|
||||||
..dashPattern = dashPattern
|
..dashPattern = dashPattern
|
||||||
..domainExtent = new _Range<D>(domain, domain)
|
..domainExtent = _Range<D>(domain, domain)
|
||||||
..strokeWidthPx = strokeWidthPx
|
..strokeWidthPx = strokeWidthPx
|
||||||
..styleKey = styleKey
|
..styleKey = styleKey
|
||||||
..roundEndCaps = config.roundEndCaps;
|
..roundEndCaps = config.roundEndCaps;
|
||||||
@@ -273,7 +272,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int i) => curOffsets[domainFn(i)];
|
return (i) => curOffsets[domainFn(i)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merge the line map and the new series so that the new elements are mixed
|
/// Merge the line map and the new series so that the new elements are mixed
|
||||||
@@ -285,7 +284,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
void _mergeIntoSeriesMap(List<ImmutableSeries<D>> seriesList) {
|
void _mergeIntoSeriesMap(List<ImmutableSeries<D>> seriesList) {
|
||||||
List<MapEntry<String, List<_AnimatedElements<D>>>> newLineMap = [];
|
List<MapEntry<String, List<_AnimatedElements<D>>>> newLineMap = [];
|
||||||
|
|
||||||
seriesList.forEach((ImmutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
final key = series.id;
|
final key = series.id;
|
||||||
|
|
||||||
// First, add all the series from the old map that have been removed from
|
// First, add all the series from the old map that have been removed from
|
||||||
@@ -332,7 +331,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
|
|
||||||
_mergeIntoSeriesMap(seriesList);
|
_mergeIntoSeriesMap(seriesList);
|
||||||
|
|
||||||
seriesList.forEach((ImmutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
final domainAxis = series.getAttr(domainAxisKey) as ImmutableAxis<D>;
|
final domainAxis = series.getAttr(domainAxisKey) as ImmutableAxis<D>;
|
||||||
final lineKey = series.id;
|
final lineKey = series.id;
|
||||||
final stackIndex = series.getAttr(lineStackIndexKey);
|
final stackIndex = series.getAttr(lineStackIndexKey);
|
||||||
@@ -372,12 +371,12 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// later to display only the relevant parts of data. This ensures that
|
// later to display only the relevant parts of data. This ensures that
|
||||||
// styles that visually depend on the start location, such as dash
|
// styles that visually depend on the start location, such as dash
|
||||||
// patterns, are not disrupted by other changes in style.
|
// patterns, are not disrupted by other changes in style.
|
||||||
styleSegments.forEach((_LineRendererElement styleSegment) {
|
styleSegments.forEach((styleSegment) {
|
||||||
final styleKey = styleSegment.styleKey;
|
final styleKey = styleSegment.styleKey;
|
||||||
|
|
||||||
// If we already have an AnimatingPoint for that index, use it.
|
// If we already have an AnimatingPoint for that index, use it.
|
||||||
var animatingElements = elementsList.firstWhere(
|
var animatingElements = elementsList.firstWhere(
|
||||||
(_AnimatedElements elements) => elements.styleKey == styleKey,
|
(elements) => elements.styleKey == styleKey,
|
||||||
orElse: () => null);
|
orElse: () => null);
|
||||||
|
|
||||||
if (animatingElements != null) {
|
if (animatingElements != null) {
|
||||||
@@ -398,7 +397,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final animatingLines = <_AnimatedLine<D>>[];
|
final animatingLines = <_AnimatedLine<D>>[];
|
||||||
|
|
||||||
for (var index = 0; index < lineElementList.length; index++) {
|
for (var index = 0; index < lineElementList.length; index++) {
|
||||||
animatingLines.add(new _AnimatedLine<D>(
|
animatingLines.add(_AnimatedLine<D>(
|
||||||
key: lineElementList[index].styleKey,
|
key: lineElementList[index].styleKey,
|
||||||
overlaySeries: series.overlaySeries)
|
overlaySeries: series.overlaySeries)
|
||||||
..setNewTarget(lineElementList[index]));
|
..setNewTarget(lineElementList[index]));
|
||||||
@@ -410,7 +409,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
animatingAreas = <_AnimatedArea<D>>[];
|
animatingAreas = <_AnimatedArea<D>>[];
|
||||||
|
|
||||||
for (var index = 0; index < areaElementList.length; index++) {
|
for (var index = 0; index < areaElementList.length; index++) {
|
||||||
animatingAreas.add(new _AnimatedArea<D>(
|
animatingAreas.add(_AnimatedArea<D>(
|
||||||
key: areaElementList[index].styleKey,
|
key: areaElementList[index].styleKey,
|
||||||
overlaySeries: series.overlaySeries)
|
overlaySeries: series.overlaySeries)
|
||||||
..setNewTarget(areaElementList[index]));
|
..setNewTarget(areaElementList[index]));
|
||||||
@@ -424,14 +423,14 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
animatingBounds ??= <_AnimatedArea<D>>[];
|
animatingBounds ??= <_AnimatedArea<D>>[];
|
||||||
|
|
||||||
for (var index = 0; index < boundsElementList.length; index++) {
|
for (var index = 0; index < boundsElementList.length; index++) {
|
||||||
animatingBounds.add(new _AnimatedArea<D>(
|
animatingBounds.add(_AnimatedArea<D>(
|
||||||
key: boundsElementList[index].styleKey,
|
key: boundsElementList[index].styleKey,
|
||||||
overlaySeries: series.overlaySeries)
|
overlaySeries: series.overlaySeries)
|
||||||
..setNewTarget(boundsElementList[index]));
|
..setNewTarget(boundsElementList[index]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
animatingElements = new _AnimatedElements<D>()
|
animatingElements = _AnimatedElements<D>()
|
||||||
..styleKey = styleSegment.styleKey
|
..styleKey = styleSegment.styleKey
|
||||||
..allPoints = allPointList
|
..allPoints = allPointList
|
||||||
..lines = animatingLines
|
..lines = animatingLines
|
||||||
@@ -458,7 +457,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// than we did in the previous chart draw cycle.
|
// than we did in the previous chart draw cycle.
|
||||||
// TODO: Nicer animations for incoming segments.
|
// TODO: Nicer animations for incoming segments.
|
||||||
if (index >= animatingElements.lines.length) {
|
if (index >= animatingElements.lines.length) {
|
||||||
animatingElements.lines.add(new _AnimatedLine<D>(
|
animatingElements.lines.add(_AnimatedLine<D>(
|
||||||
key: lineElement.styleKey,
|
key: lineElement.styleKey,
|
||||||
overlaySeries: series.overlaySeries));
|
overlaySeries: series.overlaySeries));
|
||||||
}
|
}
|
||||||
@@ -473,7 +472,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// cycle than we did in the previous chart draw cycle.
|
// cycle than we did in the previous chart draw cycle.
|
||||||
// TODO: Nicer animations for incoming segments.
|
// TODO: Nicer animations for incoming segments.
|
||||||
if (index >= animatingElements.areas.length) {
|
if (index >= animatingElements.areas.length) {
|
||||||
animatingElements.areas.add(new _AnimatedArea<D>(
|
animatingElements.areas.add(_AnimatedArea<D>(
|
||||||
key: areaElement.styleKey,
|
key: areaElement.styleKey,
|
||||||
overlaySeries: series.overlaySeries));
|
overlaySeries: series.overlaySeries));
|
||||||
}
|
}
|
||||||
@@ -489,7 +488,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// cycle than we did in the previous chart draw cycle.
|
// cycle than we did in the previous chart draw cycle.
|
||||||
// TODO: Nicer animations for incoming segments.
|
// TODO: Nicer animations for incoming segments.
|
||||||
if (index >= animatingElements.bounds.length) {
|
if (index >= animatingElements.bounds.length) {
|
||||||
animatingElements.bounds.add(new _AnimatedArea<D>(
|
animatingElements.bounds.add(_AnimatedArea<D>(
|
||||||
key: boundElement.styleKey,
|
key: boundElement.styleKey,
|
||||||
overlaySeries: series.overlaySeries));
|
overlaySeries: series.overlaySeries));
|
||||||
}
|
}
|
||||||
@@ -506,7 +505,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Animate out lines that don't exist anymore.
|
// Animate out lines that don't exist anymore.
|
||||||
_seriesLineMap.forEach((String key, List<_AnimatedElements<D>> elements) {
|
_seriesLineMap.forEach((key, elements) {
|
||||||
for (var element in elements) {
|
for (var element in elements) {
|
||||||
if (element.lines != null) {
|
if (element.lines != null) {
|
||||||
for (var line in element.lines) {
|
for (var line in element.lines) {
|
||||||
@@ -599,10 +598,10 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final linePointList = lineSegments[index];
|
final linePointList = lineSegments[index];
|
||||||
|
|
||||||
// Update the set of areas that still exist in the series data.
|
// Update the set of areas that still exist in the series data.
|
||||||
final lineStyleKey = '${styleKey}__line__${index}';
|
final lineStyleKey = '${styleKey}__line__$index';
|
||||||
_currentKeys.add(lineStyleKey);
|
_currentKeys.add(lineStyleKey);
|
||||||
|
|
||||||
lineElements.add(new _LineRendererElement<D>()
|
lineElements.add(_LineRendererElement<D>()
|
||||||
..points = linePointList
|
..points = linePointList
|
||||||
..color = color
|
..color = color
|
||||||
..areaColor = areaColor
|
..areaColor = areaColor
|
||||||
@@ -622,10 +621,10 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final areaPointList = areaSegments[index];
|
final areaPointList = areaSegments[index];
|
||||||
|
|
||||||
// Update the set of areas that still exist in the series data.
|
// Update the set of areas that still exist in the series data.
|
||||||
final areaStyleKey = '${styleKey}__area_${index}';
|
final areaStyleKey = '${styleKey}__area_$index';
|
||||||
_currentKeys.add(areaStyleKey);
|
_currentKeys.add(areaStyleKey);
|
||||||
|
|
||||||
areaElements.add(new _AreaRendererElement<D>()
|
areaElements.add(_AreaRendererElement<D>()
|
||||||
..points = areaPointList
|
..points = areaPointList
|
||||||
..color = color
|
..color = color
|
||||||
..areaColor = areaColor
|
..areaColor = areaColor
|
||||||
@@ -643,10 +642,10 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
for (var index = 0; index < boundsSegment.length; index++) {
|
for (var index = 0; index < boundsSegment.length; index++) {
|
||||||
final boundsPointList = boundsSegment[index];
|
final boundsPointList = boundsSegment[index];
|
||||||
|
|
||||||
final boundsStyleKey = '${styleKey}__bounds_${index}';
|
final boundsStyleKey = '${styleKey}__bounds_$index';
|
||||||
_currentKeys.add(boundsStyleKey);
|
_currentKeys.add(boundsStyleKey);
|
||||||
|
|
||||||
boundsElements.add(new _AreaRendererElement<D>()
|
boundsElements.add(_AreaRendererElement<D>()
|
||||||
..points = boundsPointList
|
..points = boundsPointList
|
||||||
..color = color
|
..color = color
|
||||||
..areaColor = areaColor
|
..areaColor = areaColor
|
||||||
@@ -858,7 +857,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final areaPointList = <_DatumPoint<D>>[];
|
final areaPointList = <_DatumPoint<D>>[];
|
||||||
|
|
||||||
// Add all points for upper bounds.
|
// Add all points for upper bounds.
|
||||||
areaPointList.addAll(pointList.map((datumPoint) => new _DatumPoint.from(
|
areaPointList.addAll(pointList.map((datumPoint) => _DatumPoint.from(
|
||||||
datumPoint,
|
datumPoint,
|
||||||
datumPoint.x,
|
datumPoint.x,
|
||||||
initializeFromZero
|
initializeFromZero
|
||||||
@@ -869,7 +868,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
|
|
||||||
// Add all points for lower bounds, in reverse order.
|
// Add all points for lower bounds, in reverse order.
|
||||||
areaPointList.addAll(pointList.reversed.map((datumPoint) =>
|
areaPointList.addAll(pointList.reversed.map((datumPoint) =>
|
||||||
new _DatumPoint.from(
|
_DatumPoint.from(
|
||||||
datumPoint,
|
datumPoint,
|
||||||
datumPoint.x,
|
datumPoint.x,
|
||||||
initializeFromZero
|
initializeFromZero
|
||||||
@@ -902,7 +901,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final endPosition = domainAxis.getLocation(details.domainExtent.end) ??
|
final endPosition = domainAxis.getLocation(details.domainExtent.end) ??
|
||||||
drawBounds.right.toDouble();
|
drawBounds.right.toDouble();
|
||||||
|
|
||||||
return new _Range<num>(startPosition, endPosition);
|
return _Range<num>(startPosition, endPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -919,9 +918,8 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
if (animationPercent == 1.0) {
|
if (animationPercent == 1.0) {
|
||||||
final keysToRemove = <String>[];
|
final keysToRemove = <String>[];
|
||||||
|
|
||||||
_seriesLineMap.forEach((String key, List<_AnimatedElements<D>> elements) {
|
_seriesLineMap.forEach((key, elements) {
|
||||||
elements.removeWhere(
|
elements.removeWhere((element) => element.animatingOut);
|
||||||
(_AnimatedElements<D> element) => element.animatingOut);
|
|
||||||
|
|
||||||
if (elements.isEmpty) {
|
if (elements.isEmpty) {
|
||||||
keysToRemove.add(key);
|
keysToRemove.add(key);
|
||||||
@@ -931,16 +929,15 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
keysToRemove.forEach(_seriesLineMap.remove);
|
keysToRemove.forEach(_seriesLineMap.remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
_seriesLineMap.forEach((String key, List<_AnimatedElements<D>> elements) {
|
_seriesLineMap.forEach((key, elements) {
|
||||||
if (config.includeArea) {
|
if (config.includeArea) {
|
||||||
elements
|
elements
|
||||||
.map<List<_AnimatedArea<D>>>(
|
.map<List<_AnimatedArea<D>>>(
|
||||||
(_AnimatedElements<D> animatingElement) =>
|
(animatingElement) => animatingElement.areas)
|
||||||
animatingElement.areas)
|
.expand<_AnimatedArea<D>>((areas) => areas)
|
||||||
.expand<_AnimatedArea<D>>((List<_AnimatedArea<D>> areas) => areas)
|
.map<_AreaRendererElement<D>>((animatingArea) =>
|
||||||
.map<_AreaRendererElement<D>>((_AnimatedArea<D> animatingArea) =>
|
|
||||||
animatingArea?.getCurrentArea(animationPercent))
|
animatingArea?.getCurrentArea(animationPercent))
|
||||||
.forEach((_AreaRendererElement area) {
|
.forEach((area) {
|
||||||
if (area != null) {
|
if (area != null) {
|
||||||
canvas.drawPolygon(
|
canvas.drawPolygon(
|
||||||
clipBounds: _getClipBoundsForExtent(area.positionExtent),
|
clipBounds: _getClipBoundsForExtent(area.positionExtent),
|
||||||
@@ -953,12 +950,11 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
if (_hasMeasureBounds) {
|
if (_hasMeasureBounds) {
|
||||||
elements
|
elements
|
||||||
.map<List<_AnimatedArea<D>>>(
|
.map<List<_AnimatedArea<D>>>(
|
||||||
(_AnimatedElements<D> animatingElement) =>
|
(animatingElement) => animatingElement.bounds)
|
||||||
animatingElement.bounds)
|
.expand<_AnimatedArea<D>>((bounds) => bounds)
|
||||||
.expand<_AnimatedArea<D>>((List<_AnimatedArea<D>> bounds) => bounds)
|
.map<_AreaRendererElement<D>>((animatingBounds) =>
|
||||||
.map<_AreaRendererElement<D>>((_AnimatedArea<D> animatingBounds) =>
|
|
||||||
animatingBounds?.getCurrentArea(animationPercent))
|
animatingBounds?.getCurrentArea(animationPercent))
|
||||||
.forEach((_AreaRendererElement bound) {
|
.forEach((bound) {
|
||||||
if (bound != null) {
|
if (bound != null) {
|
||||||
canvas.drawPolygon(
|
canvas.drawPolygon(
|
||||||
clipBounds: _getClipBoundsForExtent(bound.positionExtent),
|
clipBounds: _getClipBoundsForExtent(bound.positionExtent),
|
||||||
@@ -971,12 +967,11 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
if (config.includeLine) {
|
if (config.includeLine) {
|
||||||
elements
|
elements
|
||||||
.map<List<_AnimatedLine<D>>>(
|
.map<List<_AnimatedLine<D>>>(
|
||||||
(_AnimatedElements<D> animatingElement) =>
|
(animatingElement) => animatingElement.lines)
|
||||||
animatingElement.lines)
|
.expand<_AnimatedLine<D>>((lines) => lines)
|
||||||
.expand<_AnimatedLine<D>>((List<_AnimatedLine<D>> lines) => lines)
|
.map<_LineRendererElement<D>>((animatingLine) =>
|
||||||
.map<_LineRendererElement<D>>((_AnimatedLine<D> animatingLine) =>
|
|
||||||
animatingLine?.getCurrentLine(animationPercent))
|
animatingLine?.getCurrentLine(animationPercent))
|
||||||
.forEach((_LineRendererElement line) {
|
.forEach((line) {
|
||||||
if (line != null) {
|
if (line != null) {
|
||||||
canvas.drawLine(
|
canvas.drawLine(
|
||||||
clipBounds: _getClipBoundsForExtent(line.positionExtent),
|
clipBounds: _getClipBoundsForExtent(line.positionExtent),
|
||||||
@@ -1009,7 +1004,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
? clamp((extent.start), drawBounds.left, drawBounds.right)
|
? clamp((extent.start), drawBounds.left, drawBounds.right)
|
||||||
: clamp((extent.end), drawBounds.left, drawBounds.right);
|
: clamp((extent.end), drawBounds.left, drawBounds.right);
|
||||||
|
|
||||||
return new Rectangle<num>(
|
return Rectangle<num>(
|
||||||
left,
|
left,
|
||||||
drawBounds.top - drawBoundTopExtensionPx,
|
drawBounds.top - drawBoundTopExtensionPx,
|
||||||
right - left,
|
right - left,
|
||||||
@@ -1035,7 +1030,7 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
? measureAxis.getLocation(measureValue + measureOffsetValue)
|
? measureAxis.getLocation(measureValue + measureOffsetValue)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return new _DatumPoint<D>(
|
return _DatumPoint<D>(
|
||||||
datum: datum,
|
datum: datum,
|
||||||
domain: domainValue,
|
domain: domainValue,
|
||||||
series: series,
|
series: series,
|
||||||
@@ -1054,18 +1049,18 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
return nearest;
|
return nearest;
|
||||||
}
|
}
|
||||||
|
|
||||||
_seriesLineMap.values.forEach((List<_AnimatedElements<D>> seriesSegments) {
|
_seriesLineMap.values.forEach((seriesSegments) {
|
||||||
_DatumPoint<D> nearestPoint;
|
_DatumPoint<D> nearestPoint;
|
||||||
double nearestDomainDistance = 10000.0;
|
double nearestDomainDistance = 10000.0;
|
||||||
double nearestMeasureDistance = 10000.0;
|
double nearestMeasureDistance = 10000.0;
|
||||||
double nearestRelativeDistance = 10000.0;
|
double nearestRelativeDistance = 10000.0;
|
||||||
|
|
||||||
seriesSegments.forEach((_AnimatedElements<D> segment) {
|
seriesSegments.forEach((segment) {
|
||||||
if (segment.overlaySeries) {
|
if (segment.overlaySeries) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
segment.allPoints.forEach((Point p) {
|
segment.allPoints.forEach((p) {
|
||||||
// Don't look at points not in the drawArea.
|
// Don't look at points not in the drawArea.
|
||||||
if (p.x < componentBounds.left || p.x > componentBounds.right) {
|
if (p.x < componentBounds.left || p.x > componentBounds.right) {
|
||||||
return;
|
return;
|
||||||
@@ -1108,8 +1103,8 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
|
|
||||||
// Found a point, add it to the list.
|
// Found a point, add it to the list.
|
||||||
if (nearestPoint != null) {
|
if (nearestPoint != null) {
|
||||||
nearest.add(new DatumDetails<D>(
|
nearest.add(DatumDetails<D>(
|
||||||
chartPosition: new Point<double>(nearestPoint.x, nearestPoint.y),
|
chartPosition: Point<double>(nearestPoint.x, nearestPoint.y),
|
||||||
datum: nearestPoint.datum,
|
datum: nearestPoint.datum,
|
||||||
domain: nearestPoint.domain,
|
domain: nearestPoint.domain,
|
||||||
series: nearestPoint.series,
|
series: nearestPoint.series,
|
||||||
@@ -1134,9 +1129,9 @@ class LineRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
|
|
||||||
final point = _getPoint(seriesDatum.datum, details.domain, series,
|
final point = _getPoint(seriesDatum.datum, details.domain, series,
|
||||||
domainAxis, details.measure, details.measureOffset, measureAxis);
|
domainAxis, details.measure, details.measureOffset, measureAxis);
|
||||||
final chartPosition = new Point<double>(point.x, point.y);
|
final chartPosition = Point<double>(point.x, point.y);
|
||||||
|
|
||||||
return new DatumDetails.from(details, chartPosition: chartPosition);
|
return DatumDetails.from(details, chartPosition: chartPosition);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1151,7 +1146,7 @@ class _DatumPoint<D> extends Point<double> {
|
|||||||
: super(x, y);
|
: super(x, y);
|
||||||
|
|
||||||
factory _DatumPoint.from(_DatumPoint<D> other, [double x, double y]) {
|
factory _DatumPoint.from(_DatumPoint<D> other, [double x, double y]) {
|
||||||
return new _DatumPoint<D>(
|
return _DatumPoint<D>(
|
||||||
datum: other.datum,
|
datum: other.datum,
|
||||||
domain: other.domain,
|
domain: other.domain,
|
||||||
series: other.series,
|
series: other.series,
|
||||||
@@ -1175,13 +1170,11 @@ class _LineRendererElement<D> {
|
|||||||
bool roundEndCaps;
|
bool roundEndCaps;
|
||||||
|
|
||||||
_LineRendererElement<D> clone() {
|
_LineRendererElement<D> clone() {
|
||||||
return new _LineRendererElement<D>()
|
return _LineRendererElement<D>()
|
||||||
..points = new List<_DatumPoint<D>>.from(points)
|
..points = List<_DatumPoint<D>>.from(points)
|
||||||
..color = color != null ? new Color.fromOther(color: color) : null
|
..color = color != null ? Color.fromOther(color: color) : null
|
||||||
..areaColor =
|
..areaColor = areaColor != null ? Color.fromOther(color: areaColor) : null
|
||||||
areaColor != null ? new Color.fromOther(color: areaColor) : null
|
..dashPattern = dashPattern != null ? List<int>.from(dashPattern) : null
|
||||||
..dashPattern =
|
|
||||||
dashPattern != null ? new List<int>.from(dashPattern) : null
|
|
||||||
..domainExtent = domainExtent
|
..domainExtent = domainExtent
|
||||||
..measureAxisPosition = measureAxisPosition
|
..measureAxisPosition = measureAxisPosition
|
||||||
..positionExtent = positionExtent
|
..positionExtent = positionExtent
|
||||||
@@ -1207,7 +1200,7 @@ class _LineRendererElement<D> {
|
|||||||
lastPoint = previousPoint;
|
lastPoint = previousPoint;
|
||||||
} else {
|
} else {
|
||||||
previousPoint =
|
previousPoint =
|
||||||
new _DatumPoint<D>.from(targetPoint, targetPoint.x, lastPoint.y);
|
_DatumPoint<D>.from(targetPoint, targetPoint.x, lastPoint.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
final x = ((targetPoint.x - previousPoint.x) * animationPercent) +
|
final x = ((targetPoint.x - previousPoint.x) * animationPercent) +
|
||||||
@@ -1224,9 +1217,9 @@ class _LineRendererElement<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (points.length - 1 >= pointIndex) {
|
if (points.length - 1 >= pointIndex) {
|
||||||
points[pointIndex] = new _DatumPoint<D>.from(targetPoint, x, y);
|
points[pointIndex] = _DatumPoint<D>.from(targetPoint, x, y);
|
||||||
} else {
|
} else {
|
||||||
points.add(new _DatumPoint<D>.from(targetPoint, x, y));
|
points.add(_DatumPoint<D>.from(targetPoint, x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1278,7 +1271,7 @@ class _AnimatedLine<D> {
|
|||||||
for (var index = 0; index < newTarget.points.length; index++) {
|
for (var index = 0; index < newTarget.points.length; index++) {
|
||||||
var targetPoint = newTarget.points[index];
|
var targetPoint = newTarget.points[index];
|
||||||
|
|
||||||
newPoints.add(new _DatumPoint<D>.from(targetPoint, targetPoint.x,
|
newPoints.add(_DatumPoint<D>.from(targetPoint, targetPoint.x,
|
||||||
newTarget.measureAxisPosition.roundToDouble()));
|
newTarget.measureAxisPosition.roundToDouble()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1328,11 +1321,10 @@ class _AreaRendererElement<D> {
|
|||||||
String styleKey;
|
String styleKey;
|
||||||
|
|
||||||
_AreaRendererElement<D> clone() {
|
_AreaRendererElement<D> clone() {
|
||||||
return new _AreaRendererElement<D>()
|
return _AreaRendererElement<D>()
|
||||||
..points = new List<_DatumPoint<D>>.from(points)
|
..points = List<_DatumPoint<D>>.from(points)
|
||||||
..color = color != null ? new Color.fromOther(color: color) : null
|
..color = color != null ? Color.fromOther(color: color) : null
|
||||||
..areaColor =
|
..areaColor = areaColor != null ? Color.fromOther(color: areaColor) : null
|
||||||
areaColor != null ? new Color.fromOther(color: areaColor) : null
|
|
||||||
..domainExtent = domainExtent
|
..domainExtent = domainExtent
|
||||||
..measureAxisPosition = measureAxisPosition
|
..measureAxisPosition = measureAxisPosition
|
||||||
..positionExtent = positionExtent
|
..positionExtent = positionExtent
|
||||||
@@ -1356,7 +1348,7 @@ class _AreaRendererElement<D> {
|
|||||||
lastPoint = previousPoint;
|
lastPoint = previousPoint;
|
||||||
} else {
|
} else {
|
||||||
previousPoint =
|
previousPoint =
|
||||||
new _DatumPoint<D>.from(targetPoint, targetPoint.x, lastPoint.y);
|
_DatumPoint<D>.from(targetPoint, targetPoint.x, lastPoint.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
final x = ((targetPoint.x - previousPoint.x) * animationPercent) +
|
final x = ((targetPoint.x - previousPoint.x) * animationPercent) +
|
||||||
@@ -1373,9 +1365,9 @@ class _AreaRendererElement<D> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (points.length - 1 >= pointIndex) {
|
if (points.length - 1 >= pointIndex) {
|
||||||
points[pointIndex] = new _DatumPoint<D>.from(targetPoint, x, y);
|
points[pointIndex] = _DatumPoint<D>.from(targetPoint, x, y);
|
||||||
} else {
|
} else {
|
||||||
points.add(new _DatumPoint<D>.from(targetPoint, x, y));
|
points.add(_DatumPoint<D>.from(targetPoint, x, y));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1423,7 +1415,7 @@ class _AnimatedArea<D> {
|
|||||||
for (var index = 0; index < newTarget.points.length; index++) {
|
for (var index = 0; index < newTarget.points.length; index++) {
|
||||||
var targetPoint = newTarget.points[index];
|
var targetPoint = newTarget.points[index];
|
||||||
|
|
||||||
newPoints.add(new _DatumPoint<D>.from(targetPoint, targetPoint.x,
|
newPoints.add(_DatumPoint<D>.from(targetPoint, targetPoint.x,
|
||||||
newTarget.measureAxisPosition.roundToDouble()));
|
newTarget.measureAxisPosition.roundToDouble()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class LineRendererConfig<D> extends LayoutViewConfig
|
|||||||
|
|
||||||
final SymbolRenderer symbolRenderer;
|
final SymbolRenderer symbolRenderer;
|
||||||
|
|
||||||
final rendererAttributes = new RendererAttributes();
|
final rendererAttributes = RendererAttributes();
|
||||||
|
|
||||||
/// Radius of points on the line, if [includePoints] is enabled.
|
/// Radius of points on the line, if [includePoints] is enabled.
|
||||||
final double radiusPx;
|
final double radiusPx;
|
||||||
@@ -83,10 +83,10 @@ class LineRendererConfig<D> extends LayoutViewConfig
|
|||||||
this.areaOpacity = 0.1,
|
this.areaOpacity = 0.1,
|
||||||
this.roundEndCaps = false,
|
this.roundEndCaps = false,
|
||||||
SymbolRenderer symbolRenderer})
|
SymbolRenderer symbolRenderer})
|
||||||
: this.symbolRenderer = symbolRenderer ?? new LineSymbolRenderer();
|
: this.symbolRenderer = symbolRenderer ?? LineSymbolRenderer();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
LineRenderer<D> build() {
|
LineRenderer<D> build() {
|
||||||
return new LineRenderer<D>(config: this, rendererId: customRendererId);
|
return LineRenderer<D>(config: this, rendererId: customRendererId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ class ArcLabelDecorator<D> extends ArcRendererDecorator<D> {
|
|||||||
static const _defaultLabelPosition = ArcLabelPosition.auto;
|
static const _defaultLabelPosition = ArcLabelPosition.auto;
|
||||||
static const _defaultLabelPadding = 5;
|
static const _defaultLabelPadding = 5;
|
||||||
static final _defaultInsideLabelStyle =
|
static final _defaultInsideLabelStyle =
|
||||||
new TextStyleSpec(fontSize: 12, color: Color.white);
|
TextStyleSpec(fontSize: 12, color: Color.white);
|
||||||
static final _defaultOutsideLabelStyle =
|
static final _defaultOutsideLabelStyle =
|
||||||
new TextStyleSpec(fontSize: 12, color: Color.black);
|
TextStyleSpec(fontSize: 12, color: Color.black);
|
||||||
static final _defaultLeaderLineStyle = new ArcLabelLeaderLineStyleSpec(
|
static final _defaultLeaderLineStyle = ArcLabelLeaderLineStyleSpec(
|
||||||
length: 20.0,
|
length: 20.0,
|
||||||
thickness: 1.0,
|
thickness: 1.0,
|
||||||
color: StyleFactory.style.arcLabelOutsideLeaderLine);
|
color: StyleFactory.style.arcLabelOutsideLeaderLine);
|
||||||
@@ -136,16 +136,16 @@ class ArcLabelDecorator<D> extends ArcRendererDecorator<D> {
|
|||||||
final centerRadius = arcElements.innerRadius +
|
final centerRadius = arcElements.innerRadius +
|
||||||
((arcElements.radius - arcElements.innerRadius) / 2);
|
((arcElements.radius - arcElements.innerRadius) / 2);
|
||||||
|
|
||||||
final innerPoint = new Point<double>(
|
final innerPoint = Point<double>(
|
||||||
arcElements.center.x + arcElements.innerRadius * cos(centerAngle),
|
arcElements.center.x + arcElements.innerRadius * cos(centerAngle),
|
||||||
arcElements.center.y + arcElements.innerRadius * sin(centerAngle));
|
arcElements.center.y + arcElements.innerRadius * sin(centerAngle));
|
||||||
|
|
||||||
final outerPoint = new Point<double>(
|
final outerPoint = Point<double>(
|
||||||
arcElements.center.x + arcElements.radius * cos(centerAngle),
|
arcElements.center.x + arcElements.radius * cos(centerAngle),
|
||||||
arcElements.center.y + arcElements.radius * sin(centerAngle));
|
arcElements.center.y + arcElements.radius * sin(centerAngle));
|
||||||
|
|
||||||
//final bounds = element.bounds;
|
//final bounds = element.bounds;
|
||||||
final bounds = new Rectangle<double>.fromPoints(innerPoint, outerPoint);
|
final bounds = Rectangle<double>.fromPoints(innerPoint, outerPoint);
|
||||||
|
|
||||||
// Get space available inside and outside the arc.
|
// Get space available inside and outside the arc.
|
||||||
final totalPadding = labelPadding * 2;
|
final totalPadding = labelPadding * 2;
|
||||||
@@ -268,7 +268,7 @@ class ArcLabelDecorator<D> extends ArcRendererDecorator<D> {
|
|||||||
bool previousLabelLeftOfChart) {
|
bool previousLabelLeftOfChart) {
|
||||||
final labelRadius = arcElements.radius + leaderLineStyleSpec.length / 2;
|
final labelRadius = arcElements.radius + leaderLineStyleSpec.length / 2;
|
||||||
|
|
||||||
final labelPoint = new Point<double>(
|
final labelPoint = Point<double>(
|
||||||
arcElements.center.x + labelRadius * cos(centerAngle),
|
arcElements.center.x + labelRadius * cos(centerAngle),
|
||||||
arcElements.center.y + labelRadius * sin(centerAngle));
|
arcElements.center.y + labelRadius * sin(centerAngle));
|
||||||
|
|
||||||
@@ -347,10 +347,10 @@ class ArcLabelDecorator<D> extends ArcRendererDecorator<D> {
|
|||||||
final tailX = (labelLeftOfChart ? -1 : 1) * leaderLineStyleSpec.length;
|
final tailX = (labelLeftOfChart ? -1 : 1) * leaderLineStyleSpec.length;
|
||||||
|
|
||||||
final leaderLineTailPoint =
|
final leaderLineTailPoint =
|
||||||
new Point<double>(labelPoint.x + tailX, labelPoint.y);
|
Point<double>(labelPoint.x + tailX, labelPoint.y);
|
||||||
|
|
||||||
final centerRadius = radius - leaderLineStyleSpec.length / 2;
|
final centerRadius = radius - leaderLineStyleSpec.length / 2;
|
||||||
final leaderLineStartPoint = new Point<double>(
|
final leaderLineStartPoint = Point<double>(
|
||||||
arcCenterPoint.x + centerRadius * cos(centerAngle),
|
arcCenterPoint.x + centerRadius * cos(centerAngle),
|
||||||
arcCenterPoint.y + centerRadius * sin(centerAngle));
|
arcCenterPoint.y + centerRadius * sin(centerAngle));
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import 'arc_renderer_config.dart' show ArcRendererConfig;
|
|||||||
import 'arc_renderer_decorator.dart' show ArcRendererDecorator;
|
import 'arc_renderer_decorator.dart' show ArcRendererDecorator;
|
||||||
|
|
||||||
const arcElementsKey =
|
const arcElementsKey =
|
||||||
const AttributeKey<List<ArcRendererElement>>('ArcRenderer.elements');
|
AttributeKey<List<ArcRendererElement>>('ArcRenderer.elements');
|
||||||
|
|
||||||
class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
||||||
// Constant used in the calculation of [centerContentBounds], calculated once
|
// Constant used in the calculation of [centerContentBounds], calculated once
|
||||||
@@ -49,7 +49,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
///
|
///
|
||||||
/// [LinkedHashMap] is used to render the series on the canvas in the same
|
/// [LinkedHashMap] is used to render the series on the canvas in the same
|
||||||
/// order as the data was given to the chart.
|
/// order as the data was given to the chart.
|
||||||
final _seriesArcMap = new LinkedHashMap<String, _AnimatedArcList<D>>();
|
final _seriesArcMap = LinkedHashMap<String, _AnimatedArcList<D>>();
|
||||||
|
|
||||||
// Store a list of arcs that exist in the series data.
|
// Store a list of arcs that exist in the series data.
|
||||||
//
|
//
|
||||||
@@ -59,9 +59,9 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
final _currentKeys = <String>[];
|
final _currentKeys = <String>[];
|
||||||
|
|
||||||
factory ArcRenderer({String rendererId, ArcRendererConfig config}) {
|
factory ArcRenderer({String rendererId, ArcRendererConfig config}) {
|
||||||
return new ArcRenderer._internal(
|
return ArcRenderer._internal(
|
||||||
rendererId: rendererId ?? 'line',
|
rendererId: rendererId ?? 'line',
|
||||||
config: config ?? new ArcRendererConfig());
|
config: config ?? ArcRendererConfig());
|
||||||
}
|
}
|
||||||
|
|
||||||
ArcRenderer._internal({String rendererId, this.config})
|
ArcRenderer._internal({String rendererId, this.config})
|
||||||
@@ -84,7 +84,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void preprocessSeries(List<MutableSeries<D>> seriesList) {
|
void preprocessSeries(List<MutableSeries<D>> seriesList) {
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
var elements = <ArcRendererElement<D>>[];
|
var elements = <ArcRendererElement<D>>[];
|
||||||
|
|
||||||
var domainFn = series.domainFn;
|
var domainFn = series.domainFn;
|
||||||
@@ -110,7 +110,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
var angle = arcLength == 2 * pi ? arcLength * .999999 : arcLength;
|
var angle = arcLength == 2 * pi ? arcLength * .999999 : arcLength;
|
||||||
var endAngle = startAngle + angle;
|
var endAngle = startAngle + angle;
|
||||||
|
|
||||||
var details = new ArcRendererElement<D>();
|
var details = ArcRendererElement<D>();
|
||||||
details.startAngle = startAngle;
|
details.startAngle = startAngle;
|
||||||
details.endAngle = endAngle;
|
details.endAngle = endAngle;
|
||||||
details.index = 0;
|
details.index = 0;
|
||||||
@@ -132,7 +132,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
var angle = arcLength * percentOfSeries;
|
var angle = arcLength * percentOfSeries;
|
||||||
var endAngle = startAngle + angle;
|
var endAngle = startAngle + angle;
|
||||||
|
|
||||||
var details = new ArcRendererElement<D>();
|
var details = ArcRendererElement<D>();
|
||||||
details.startAngle = startAngle;
|
details.startAngle = startAngle;
|
||||||
details.endAngle = endAngle;
|
details.endAngle = endAngle;
|
||||||
details.index = arcIndex;
|
details.index = arcIndex;
|
||||||
@@ -158,8 +158,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
|
|
||||||
final bounds = _chart.drawAreaBounds;
|
final bounds = _chart.drawAreaBounds;
|
||||||
|
|
||||||
final center = new Point<double>(
|
final center = Point<double>((bounds.left + bounds.width / 2).toDouble(),
|
||||||
(bounds.left + bounds.width / 2).toDouble(),
|
|
||||||
(bounds.top + bounds.height / 2).toDouble());
|
(bounds.top + bounds.height / 2).toDouble());
|
||||||
|
|
||||||
final radius = bounds.height < bounds.width
|
final radius = bounds.height < bounds.width
|
||||||
@@ -168,18 +167,18 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
|
|
||||||
if (config.arcRatio != null) {
|
if (config.arcRatio != null) {
|
||||||
if (0 < config.arcRatio || config.arcRatio > 1) {
|
if (0 < config.arcRatio || config.arcRatio > 1) {
|
||||||
throw new ArgumentError('arcRatio must be between 0 and 1');
|
throw ArgumentError('arcRatio must be between 0 and 1');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final innerRadius = _calculateInnerRadius(radius);
|
final innerRadius = _calculateInnerRadius(radius);
|
||||||
|
|
||||||
seriesList.forEach((ImmutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
var colorFn = series.colorFn;
|
var colorFn = series.colorFn;
|
||||||
var arcListKey = series.id;
|
var arcListKey = series.id;
|
||||||
|
|
||||||
var arcList =
|
var arcList =
|
||||||
_seriesArcMap.putIfAbsent(arcListKey, () => new _AnimatedArcList());
|
_seriesArcMap.putIfAbsent(arcListKey, () => _AnimatedArcList());
|
||||||
|
|
||||||
var elementsList = series.getAttr(arcElementsKey);
|
var elementsList = series.getAttr(arcElementsKey);
|
||||||
|
|
||||||
@@ -191,9 +190,8 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
var arcKey = '__no_data__';
|
var arcKey = '__no_data__';
|
||||||
|
|
||||||
// If we already have an AnimatingArc for that index, use it.
|
// If we already have an AnimatingArc for that index, use it.
|
||||||
var animatingArc = arcList.arcs.firstWhere(
|
var animatingArc = arcList.arcs
|
||||||
(_AnimatedArc arc) => arc.key == arcKey,
|
.firstWhere((arc) => arc.key == arcKey, orElse: () => null);
|
||||||
orElse: () => null);
|
|
||||||
|
|
||||||
arcList.center = center;
|
arcList.center = center;
|
||||||
arcList.radius = radius;
|
arcList.radius = radius;
|
||||||
@@ -205,7 +203,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
// If we don't have any existing arc element, create a new arc. Unlike
|
// If we don't have any existing arc element, create a new arc. Unlike
|
||||||
// real arcs, we should not animate the no data state in from 0.
|
// real arcs, we should not animate the no data state in from 0.
|
||||||
if (animatingArc == null) {
|
if (animatingArc == null) {
|
||||||
animatingArc = new _AnimatedArc<D>(arcKey, null, null);
|
animatingArc = _AnimatedArc<D>(arcKey, null, null);
|
||||||
arcList.arcs.add(animatingArc);
|
arcList.arcs.add(animatingArc);
|
||||||
} else {
|
} else {
|
||||||
animatingArc.datum = null;
|
animatingArc.datum = null;
|
||||||
@@ -217,7 +215,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
|
|
||||||
// Get the arcElement we are going to setup.
|
// Get the arcElement we are going to setup.
|
||||||
// Optimization to prevent allocation in non-animating case.
|
// Optimization to prevent allocation in non-animating case.
|
||||||
final arcElement = new ArcRendererElement<D>()
|
final arcElement = ArcRendererElement<D>()
|
||||||
..color = config.noDataColor
|
..color = config.noDataColor
|
||||||
..startAngle = details.startAngle
|
..startAngle = details.startAngle
|
||||||
..endAngle = details.endAngle
|
..endAngle = details.endAngle
|
||||||
@@ -235,9 +233,8 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
var arcKey = domainValue.toString();
|
var arcKey = domainValue.toString();
|
||||||
|
|
||||||
// If we already have an AnimatingArc for that index, use it.
|
// If we already have an AnimatingArc for that index, use it.
|
||||||
var animatingArc = arcList.arcs.firstWhere(
|
var animatingArc = arcList.arcs
|
||||||
(_AnimatedArc arc) => arc.key == arcKey,
|
.firstWhere((arc) => arc.key == arcKey, orElse: () => null);
|
||||||
orElse: () => null);
|
|
||||||
|
|
||||||
arcList.center = center;
|
arcList.center = center;
|
||||||
arcList.radius = radius;
|
arcList.radius = radius;
|
||||||
@@ -251,8 +248,8 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
// angle. If there were no previous arcs, then animate everything in
|
// angle. If there were no previous arcs, then animate everything in
|
||||||
// from 0.
|
// from 0.
|
||||||
if (animatingArc == null) {
|
if (animatingArc == null) {
|
||||||
animatingArc = new _AnimatedArc<D>(arcKey, datum, domainValue)
|
animatingArc = _AnimatedArc<D>(arcKey, datum, domainValue)
|
||||||
..setNewTarget(new ArcRendererElement<D>()
|
..setNewTarget(ArcRendererElement<D>()
|
||||||
..color = colorFn(arcIndex)
|
..color = colorFn(arcIndex)
|
||||||
..startAngle = previousEndAngle
|
..startAngle = previousEndAngle
|
||||||
..endAngle = previousEndAngle
|
..endAngle = previousEndAngle
|
||||||
@@ -273,7 +270,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
|
|
||||||
// Get the arcElement we are going to setup.
|
// Get the arcElement we are going to setup.
|
||||||
// Optimization to prevent allocation in non-animating case.
|
// Optimization to prevent allocation in non-animating case.
|
||||||
final arcElement = new ArcRendererElement<D>()
|
final arcElement = ArcRendererElement<D>()
|
||||||
..color = colorFn(arcIndex)
|
..color = colorFn(arcIndex)
|
||||||
..startAngle = details.startAngle
|
..startAngle = details.startAngle
|
||||||
..endAngle = details.endAngle
|
..endAngle = details.endAngle
|
||||||
@@ -286,7 +283,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Animate out arcs that don't exist anymore.
|
// Animate out arcs that don't exist anymore.
|
||||||
_seriesArcMap.forEach((String key, _AnimatedArcList<D> arcList) {
|
_seriesArcMap.forEach((key, arcList) {
|
||||||
for (var arcIndex = 0; arcIndex < arcList.arcs.length; arcIndex++) {
|
for (var arcIndex = 0; arcIndex < arcList.arcs.length; arcIndex++) {
|
||||||
final arc = arcList.arcs[arcIndex];
|
final arc = arcList.arcs[arcIndex];
|
||||||
final arcStartAngle = arc.previousArcStartAngle;
|
final arcStartAngle = arc.previousArcStartAngle;
|
||||||
@@ -319,8 +316,8 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
if (animationPercent == 1.0) {
|
if (animationPercent == 1.0) {
|
||||||
final keysToRemove = <String>[];
|
final keysToRemove = <String>[];
|
||||||
|
|
||||||
_seriesArcMap.forEach((String key, _AnimatedArcList<D> arcList) {
|
_seriesArcMap.forEach((key, arcList) {
|
||||||
arcList.arcs.removeWhere((_AnimatedArc<D> arc) => arc.animatingOut);
|
arcList.arcs.removeWhere((arc) => arc.animatingOut);
|
||||||
|
|
||||||
if (arcList.arcs.isEmpty) {
|
if (arcList.arcs.isEmpty) {
|
||||||
keysToRemove.add(key);
|
keysToRemove.add(key);
|
||||||
@@ -330,9 +327,9 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
keysToRemove.forEach(_seriesArcMap.remove);
|
keysToRemove.forEach(_seriesArcMap.remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
_seriesArcMap.forEach((String key, _AnimatedArcList<D> arcList) {
|
_seriesArcMap.forEach((key, arcList) {
|
||||||
final circleSectors = <CanvasPieSlice>[];
|
final circleSectors = <CanvasPieSlice>[];
|
||||||
final arcElementsList = new ArcRendererElementList<D>()
|
final arcElementsList = ArcRendererElementList<D>()
|
||||||
..arcs = <ArcRendererElement<D>>[]
|
..arcs = <ArcRendererElement<D>>[]
|
||||||
..center = arcList.center
|
..center = arcList.center
|
||||||
..innerRadius = arcList.innerRadius
|
..innerRadius = arcList.innerRadius
|
||||||
@@ -342,11 +339,11 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
..strokeWidthPx = arcList.strokeWidthPx;
|
..strokeWidthPx = arcList.strokeWidthPx;
|
||||||
|
|
||||||
arcList.arcs
|
arcList.arcs
|
||||||
.map<ArcRendererElement<D>>((_AnimatedArc<D> animatingArc) =>
|
.map<ArcRendererElement<D>>(
|
||||||
animatingArc.getCurrentArc(animationPercent))
|
(animatingArc) => animatingArc.getCurrentArc(animationPercent))
|
||||||
.forEach((ArcRendererElement arc) {
|
.forEach((arc) {
|
||||||
circleSectors.add(
|
circleSectors
|
||||||
new CanvasPieSlice(arc.startAngle, arc.endAngle, fill: arc.color));
|
.add(CanvasPieSlice(arc.startAngle, arc.endAngle, fill: arc.color));
|
||||||
|
|
||||||
arcElementsList.arcs.add(arc);
|
arcElementsList.arcs.add(arc);
|
||||||
});
|
});
|
||||||
@@ -354,8 +351,8 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
// Decorate the arcs with decorators that should appear below the main
|
// Decorate the arcs with decorators that should appear below the main
|
||||||
// series data.
|
// series data.
|
||||||
arcRendererDecorators
|
arcRendererDecorators
|
||||||
.where((ArcRendererDecorator decorator) => !decorator.renderAbove)
|
.where((decorator) => !decorator.renderAbove)
|
||||||
.forEach((ArcRendererDecorator decorator) {
|
.forEach((decorator) {
|
||||||
decorator.decorate(arcElementsList, canvas, graphicsFactory,
|
decorator.decorate(arcElementsList, canvas, graphicsFactory,
|
||||||
drawBounds: drawBounds,
|
drawBounds: drawBounds,
|
||||||
animationPercent: animationPercent,
|
animationPercent: animationPercent,
|
||||||
@@ -363,15 +360,15 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Draw the arcs.
|
// Draw the arcs.
|
||||||
canvas.drawPie(new CanvasPie(
|
canvas.drawPie(CanvasPie(
|
||||||
circleSectors, arcList.center, arcList.radius, arcList.innerRadius,
|
circleSectors, arcList.center, arcList.radius, arcList.innerRadius,
|
||||||
stroke: arcList.stroke, strokeWidthPx: arcList.strokeWidthPx));
|
stroke: arcList.stroke, strokeWidthPx: arcList.strokeWidthPx));
|
||||||
|
|
||||||
// Decorate the arcs with decorators that should appear above the main
|
// Decorate the arcs with decorators that should appear above the main
|
||||||
// series data. This is the typical place for labels.
|
// series data. This is the typical place for labels.
|
||||||
arcRendererDecorators
|
arcRendererDecorators
|
||||||
.where((ArcRendererDecorator decorator) => decorator.renderAbove)
|
.where((decorator) => decorator.renderAbove)
|
||||||
.forEach((ArcRendererDecorator decorator) {
|
.forEach((decorator) {
|
||||||
decorator.decorate(arcElementsList, canvas, graphicsFactory,
|
decorator.decorate(arcElementsList, canvas, graphicsFactory,
|
||||||
drawBounds: drawBounds,
|
drawBounds: drawBounds,
|
||||||
animationPercent: animationPercent,
|
animationPercent: animationPercent,
|
||||||
@@ -398,7 +395,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
arcList.innerRadius < config.minHoleWidthForCenterContent) {
|
arcList.innerRadius < config.minHoleWidthForCenterContent) {
|
||||||
// Return default bounds of 0 size.
|
// Return default bounds of 0 size.
|
||||||
final bounds = _chart.drawAreaBounds;
|
final bounds = _chart.drawAreaBounds;
|
||||||
return new Rectangle<int>((bounds.left + bounds.width / 2).round(),
|
return Rectangle<int>((bounds.left + bounds.width / 2).round(),
|
||||||
(bounds.top + bounds.height / 2).round(), 0, 0);
|
(bounds.top + bounds.height / 2).round(), 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,7 +403,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
// size that will fit within the pie's inner radius.
|
// size that will fit within the pie's inner radius.
|
||||||
final width = (_cosPIOver4 * arcList.innerRadius).floor();
|
final width = (_cosPIOver4 * arcList.innerRadius).floor();
|
||||||
|
|
||||||
return new Rectangle<int>((arcList.center.x - width).round(),
|
return Rectangle<int>((arcList.center.x - width).round(),
|
||||||
(arcList.center.y - width).round(), width * 2, width * 2);
|
(arcList.center.y - width).round(), width * 2, width * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,7 +419,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
|
|
||||||
final chartPosition = _getChartPosition(series.id, domain.toString());
|
final chartPosition = _getChartPosition(series.id, domain.toString());
|
||||||
|
|
||||||
return new DatumDetails(
|
return DatumDetails(
|
||||||
datum: datum,
|
datum: datum,
|
||||||
domain: domain,
|
domain: domain,
|
||||||
measure: measure,
|
measure: measure,
|
||||||
@@ -457,7 +454,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
final centerPointRadius =
|
final centerPointRadius =
|
||||||
arcList.innerRadius + (arcList.radius - arcList.innerRadius) / 2;
|
arcList.innerRadius + (arcList.radius - arcList.innerRadius) / 2;
|
||||||
|
|
||||||
chartPosition = new Point<double>(
|
chartPosition = Point<double>(
|
||||||
centerPointRadius * cos(centerAngle) + arcList.center.x,
|
centerPointRadius * cos(centerAngle) + arcList.center.x,
|
||||||
centerPointRadius * sin(centerAngle) + arcList.center.y);
|
centerPointRadius * sin(centerAngle) + arcList.center.y);
|
||||||
|
|
||||||
@@ -478,7 +475,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
return nearest;
|
return nearest;
|
||||||
}
|
}
|
||||||
|
|
||||||
_seriesArcMap.forEach((String key, _AnimatedArcList<D> arcList) {
|
_seriesArcMap.forEach((key, arcList) {
|
||||||
if (arcList.series.overlaySeries) {
|
if (arcList.series.overlaySeries) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -506,11 +503,11 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
chartPointAngle = 2 * pi + chartPointAngle;
|
chartPointAngle = 2 * pi + chartPointAngle;
|
||||||
}
|
}
|
||||||
|
|
||||||
arcList.arcs.forEach((_AnimatedArc<D> arc) {
|
arcList.arcs.forEach((arc) {
|
||||||
if (innerRadius <= distance && distance <= radius) {
|
if (innerRadius <= distance && distance <= radius) {
|
||||||
if (arc.currentArcStartAngle <= chartPointAngle &&
|
if (arc.currentArcStartAngle <= chartPointAngle &&
|
||||||
chartPointAngle <= arc.currentArcEndAngle) {
|
chartPointAngle <= arc.currentArcEndAngle) {
|
||||||
nearest.add(new DatumDetails<D>(
|
nearest.add(DatumDetails<D>(
|
||||||
series: arcList.series,
|
series: arcList.series,
|
||||||
datum: arc.datum,
|
datum: arc.datum,
|
||||||
domain: arc.domain,
|
domain: arc.domain,
|
||||||
@@ -531,7 +528,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
final chartPosition =
|
final chartPosition =
|
||||||
_getChartPosition(details.series.id, details.domain.toString());
|
_getChartPosition(details.series.id, details.domain.toString());
|
||||||
|
|
||||||
return new DatumDetails.from(details, chartPosition: chartPosition);
|
return DatumDetails.from(details, chartPosition: chartPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assigns colors to series that are missing their colorFn.
|
/// Assigns colors to series that are missing their colorFn.
|
||||||
@@ -540,7 +537,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
{@required bool emptyCategoryUsesSinglePalette}) {
|
{@required bool emptyCategoryUsesSinglePalette}) {
|
||||||
int maxMissing = 0;
|
int maxMissing = 0;
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
if (series.colorFn == null) {
|
if (series.colorFn == null) {
|
||||||
maxMissing = max(maxMissing, series.data.length);
|
maxMissing = max(maxMissing, series.data.length);
|
||||||
}
|
}
|
||||||
@@ -550,7 +547,7 @@ class ArcRenderer<D> extends BaseSeriesRenderer<D> {
|
|||||||
final colorPalettes = StyleFactory.style.getOrderedPalettes(1);
|
final colorPalettes = StyleFactory.style.getOrderedPalettes(1);
|
||||||
final colorPalette = colorPalettes[0].makeShades(maxMissing);
|
final colorPalette = colorPalettes[0].makeShades(maxMissing);
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries series) {
|
seriesList.forEach((series) {
|
||||||
series.colorFn ??= (index) => colorPalette[index];
|
series.colorFn ??= (index) => colorPalette[index];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -593,10 +590,10 @@ class ArcRendererElement<D> {
|
|||||||
ImmutableSeries<D> series;
|
ImmutableSeries<D> series;
|
||||||
|
|
||||||
ArcRendererElement<D> clone() {
|
ArcRendererElement<D> clone() {
|
||||||
return new ArcRendererElement<D>()
|
return ArcRendererElement<D>()
|
||||||
..startAngle = startAngle
|
..startAngle = startAngle
|
||||||
..endAngle = endAngle
|
..endAngle = endAngle
|
||||||
..color = new Color.fromOther(color: color)
|
..color = Color.fromOther(color: color)
|
||||||
..index = index
|
..index = index
|
||||||
..key = key
|
..key = key
|
||||||
..series = series;
|
..series = series;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class ArcRendererConfig<D> extends LayoutViewConfig
|
|||||||
|
|
||||||
final SymbolRenderer symbolRenderer;
|
final SymbolRenderer symbolRenderer;
|
||||||
|
|
||||||
final rendererAttributes = new RendererAttributes();
|
final rendererAttributes = RendererAttributes();
|
||||||
|
|
||||||
/// Total arc length, in radians.
|
/// Total arc length, in radians.
|
||||||
///
|
///
|
||||||
@@ -85,10 +85,10 @@ class ArcRendererConfig<D> extends LayoutViewConfig
|
|||||||
SymbolRenderer symbolRenderer})
|
SymbolRenderer symbolRenderer})
|
||||||
: this.noDataColor = StyleFactory.style.noDataColor,
|
: this.noDataColor = StyleFactory.style.noDataColor,
|
||||||
this.stroke = StyleFactory.style.white,
|
this.stroke = StyleFactory.style.white,
|
||||||
this.symbolRenderer = symbolRenderer ?? new CircleSymbolRenderer();
|
this.symbolRenderer = symbolRenderer ?? CircleSymbolRenderer();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
ArcRenderer<D> build() {
|
ArcRenderer<D> build() {
|
||||||
return new ArcRenderer<D>(config: this, rendererId: customRendererId);
|
return ArcRenderer<D>(config: this, rendererId: customRendererId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,11 +24,11 @@ import '../layout/layout_config.dart' show LayoutConfig, MarginSpec;
|
|||||||
import 'arc_renderer.dart' show ArcRenderer;
|
import 'arc_renderer.dart' show ArcRenderer;
|
||||||
|
|
||||||
class PieChart<D> extends BaseChart<D> {
|
class PieChart<D> extends BaseChart<D> {
|
||||||
static final _defaultLayoutConfig = new LayoutConfig(
|
static final _defaultLayoutConfig = LayoutConfig(
|
||||||
topSpec: new MarginSpec.fromPixel(minPixel: 20),
|
topSpec: MarginSpec.fromPixel(minPixel: 20),
|
||||||
bottomSpec: new MarginSpec.fromPixel(minPixel: 20),
|
bottomSpec: MarginSpec.fromPixel(minPixel: 20),
|
||||||
leftSpec: new MarginSpec.fromPixel(minPixel: 20),
|
leftSpec: MarginSpec.fromPixel(minPixel: 20),
|
||||||
rightSpec: new MarginSpec.fromPixel(minPixel: 20),
|
rightSpec: MarginSpec.fromPixel(minPixel: 20),
|
||||||
);
|
);
|
||||||
|
|
||||||
PieChart({LayoutConfig layoutConfig})
|
PieChart({LayoutConfig layoutConfig})
|
||||||
@@ -38,7 +38,7 @@ class PieChart<D> extends BaseChart<D> {
|
|||||||
void drawInternal(List<MutableSeries<D>> seriesList,
|
void drawInternal(List<MutableSeries<D>> seriesList,
|
||||||
{bool skipAnimation, bool skipLayout}) {
|
{bool skipAnimation, bool skipLayout}) {
|
||||||
if (seriesList.length > 1) {
|
if (seriesList.length > 1) {
|
||||||
throw new ArgumentError('PieChart can only render a single series');
|
throw ArgumentError('PieChart can only render a single series');
|
||||||
}
|
}
|
||||||
super.drawInternal(seriesList,
|
super.drawInternal(seriesList,
|
||||||
skipAnimation: skipAnimation, skipLayout: skipLayout);
|
skipAnimation: skipAnimation, skipLayout: skipLayout);
|
||||||
@@ -46,7 +46,7 @@ class PieChart<D> extends BaseChart<D> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
SeriesRenderer<D> makeDefaultRenderer() {
|
SeriesRenderer<D> makeDefaultRenderer() {
|
||||||
return new ArcRenderer<D>()..rendererId = SeriesRenderer.defaultRendererId;
|
return ArcRenderer<D>()..rendererId = SeriesRenderer.defaultRendererId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of datum details from selection model of [type].
|
/// Returns a list of datum details from selection model of [type].
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class ComparisonPointsDecorator<D> extends PointRendererDecorator<D> {
|
|||||||
final bool renderAbove = false;
|
final bool renderAbove = false;
|
||||||
|
|
||||||
ComparisonPointsDecorator({PointSymbolRenderer symbolRenderer})
|
ComparisonPointsDecorator({PointSymbolRenderer symbolRenderer})
|
||||||
: this.symbolRenderer = symbolRenderer ?? new CylinderSymbolRenderer();
|
: this.symbolRenderer = symbolRenderer ?? CylinderSymbolRenderer();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void decorate(PointRendererElement<D> pointElement, ChartCanvas canvas,
|
void decorate(PointRendererElement<D> pointElement, ChartCanvas canvas,
|
||||||
@@ -79,19 +79,19 @@ class ComparisonPointsDecorator<D> extends PointRendererDecorator<D> {
|
|||||||
|
|
||||||
// Construct the points that describe our line p1p2.
|
// Construct the points that describe our line p1p2.
|
||||||
var p1 =
|
var p1 =
|
||||||
new Point<double>(pointElement.point.xLower, pointElement.point.yLower);
|
Point<double>(pointElement.point.xLower, pointElement.point.yLower);
|
||||||
var p2 =
|
var p2 =
|
||||||
new Point<double>(pointElement.point.xUpper, pointElement.point.yUpper);
|
Point<double>(pointElement.point.xUpper, pointElement.point.yUpper);
|
||||||
|
|
||||||
// First check to see if there is no intersection at all between the line
|
// First check to see if there is no intersection at all between the line
|
||||||
// p1p2 and [drawBounds].
|
// p1p2 and [drawBounds].
|
||||||
final dataBoundsRect = new Rectangle<num>.fromPoints(p1, p2);
|
final dataBoundsRect = Rectangle<num>.fromPoints(p1, p2);
|
||||||
if (!drawBounds.intersects(dataBoundsRect)) {
|
if (!drawBounds.intersects(dataBoundsRect)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Line with end points [p1] and [p2].
|
// Line with end points [p1] and [p2].
|
||||||
final p1p2 = new _Line.fromPoints(p1, p2);
|
final p1p2 = _Line.fromPoints(p1, p2);
|
||||||
|
|
||||||
// Next, slide p1 along the line p1p2 towards the edge of the draw area if
|
// Next, slide p1 along the line p1p2 towards the edge of the draw area if
|
||||||
// the point is located outside of it.
|
// the point is located outside of it.
|
||||||
@@ -125,14 +125,14 @@ class ComparisonPointsDecorator<D> extends PointRendererDecorator<D> {
|
|||||||
// with equations y = bounds.top and y = bounds.bottom. We can pass these
|
// with equations y = bounds.top and y = bounds.bottom. We can pass these
|
||||||
// into a standard line interception method to find our point.
|
// into a standard line interception method to find our point.
|
||||||
if (p1.y < bounds.top) {
|
if (p1.y < bounds.top) {
|
||||||
final p = line.intersection(new _Line(0.0, bounds.top.toDouble()));
|
final p = line.intersection(_Line(0.0, bounds.top.toDouble()));
|
||||||
if (p != null && bounds.containsPoint(p)) {
|
if (p != null && bounds.containsPoint(p)) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p1.y > bounds.bottom) {
|
if (p1.y > bounds.bottom) {
|
||||||
final p = line.intersection(new _Line(0.0, bounds.bottom.toDouble()));
|
final p = line.intersection(_Line(0.0, bounds.bottom.toDouble()));
|
||||||
if (p != null && bounds.containsPoint(p)) {
|
if (p != null && bounds.containsPoint(p)) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -145,16 +145,14 @@ class ComparisonPointsDecorator<D> extends PointRendererDecorator<D> {
|
|||||||
//
|
//
|
||||||
// y = slope * x + yIntercept
|
// y = slope * x + yIntercept
|
||||||
if (p1.x < bounds.left) {
|
if (p1.x < bounds.left) {
|
||||||
final p =
|
final p = line.intersection(_Line.fromVertical(bounds.left.toDouble()));
|
||||||
line.intersection(new _Line.fromVertical(bounds.left.toDouble()));
|
|
||||||
if (p != null && bounds.containsPoint(p)) {
|
if (p != null && bounds.containsPoint(p)) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p1.x > bounds.right) {
|
if (p1.x > bounds.right) {
|
||||||
final p =
|
final p = line.intersection(_Line.fromVertical(bounds.right.toDouble()));
|
||||||
line.intersection(new _Line.fromVertical(bounds.right.toDouble()));
|
|
||||||
if (p != null && bounds.containsPoint(p)) {
|
if (p != null && bounds.containsPoint(p)) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
@@ -187,7 +185,7 @@ class _Line {
|
|||||||
factory _Line.fromPoints(Point<num> p1, Point<num> p2) {
|
factory _Line.fromPoints(Point<num> p1, Point<num> p2) {
|
||||||
// Handle vertical lines.
|
// Handle vertical lines.
|
||||||
if (p1.x == p2.x) {
|
if (p1.x == p2.x) {
|
||||||
return new _Line.fromVertical(p1.x);
|
return _Line.fromVertical(p1.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Slope of the line p1p2.
|
// Slope of the line p1p2.
|
||||||
@@ -196,12 +194,12 @@ class _Line {
|
|||||||
// y-intercept of the line p1p2.
|
// y-intercept of the line p1p2.
|
||||||
double b = (p1.y - (m * p1.x)).toDouble();
|
double b = (p1.y - (m * p1.x)).toDouble();
|
||||||
|
|
||||||
return new _Line(m, b);
|
return _Line(m, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a vertical line, with the question x = [xIntercept].
|
/// Creates a vertical line, with the question x = [xIntercept].
|
||||||
factory _Line.fromVertical(num xIntercept) {
|
factory _Line.fromVertical(num xIntercept) {
|
||||||
return new _Line(null, null, xIntercept.toDouble());
|
return _Line(null, null, xIntercept.toDouble());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the intersection of `this` and [other].
|
/// Computes the intersection of `this` and [other].
|
||||||
@@ -218,14 +216,14 @@ class _Line {
|
|||||||
// just plug its xIntercept value into the line equation as x and solve for
|
// just plug its xIntercept value into the line equation as x and solve for
|
||||||
// y.
|
// y.
|
||||||
if (other.vertical) {
|
if (other.vertical) {
|
||||||
return new Point<double>(
|
return Point<double>(
|
||||||
other.xIntercept, slope * other.xIntercept + yIntercept);
|
other.xIntercept, slope * other.xIntercept + yIntercept);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this line is a vertical line (has undefined slope), then we can just
|
// If this line is a vertical line (has undefined slope), then we can just
|
||||||
// plug its xIntercept value into the line equation as x and solve for y.
|
// plug its xIntercept value into the line equation as x and solve for y.
|
||||||
if (vertical) {
|
if (vertical) {
|
||||||
return new Point<double>(
|
return Point<double>(
|
||||||
xIntercept, other.slope * xIntercept + other.yIntercept);
|
xIntercept, other.slope * xIntercept + other.yIntercept);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,6 +234,6 @@ class _Line {
|
|||||||
final y = slope * (other.yIntercept - yIntercept) / (slope - other.slope) +
|
final y = slope * (other.yIntercept - yIntercept) / (slope - other.slope) +
|
||||||
yIntercept;
|
yIntercept;
|
||||||
|
|
||||||
return new Point<double>(x, y);
|
return Point<double>(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,22 +38,22 @@ import 'point_renderer_config.dart' show PointRendererConfig;
|
|||||||
import 'point_renderer_decorator.dart' show PointRendererDecorator;
|
import 'point_renderer_decorator.dart' show PointRendererDecorator;
|
||||||
|
|
||||||
const pointElementsKey =
|
const pointElementsKey =
|
||||||
const AttributeKey<List<PointRendererElement>>('PointRenderer.elements');
|
AttributeKey<List<PointRendererElement>>('PointRenderer.elements');
|
||||||
|
|
||||||
const pointSymbolRendererFnKey =
|
const pointSymbolRendererFnKey =
|
||||||
const AttributeKey<AccessorFn<String>>('PointRenderer.symbolRendererFn');
|
AttributeKey<AccessorFn<String>>('PointRenderer.symbolRendererFn');
|
||||||
|
|
||||||
const pointSymbolRendererIdKey =
|
const pointSymbolRendererIdKey =
|
||||||
const AttributeKey<String>('PointRenderer.symbolRendererId');
|
AttributeKey<String>('PointRenderer.symbolRendererId');
|
||||||
|
|
||||||
/// Defines a fixed radius for data bounds lines (typically drawn by attaching a
|
/// Defines a fixed radius for data bounds lines (typically drawn by attaching a
|
||||||
/// [ComparisonPointsDecorator] to the renderer.
|
/// [ComparisonPointsDecorator] to the renderer.
|
||||||
const boundsLineRadiusPxKey =
|
const boundsLineRadiusPxKey =
|
||||||
const AttributeKey<double>('SymbolAnnotationRenderer.boundsLineRadiusPx');
|
AttributeKey<double>('SymbolAnnotationRenderer.boundsLineRadiusPx');
|
||||||
|
|
||||||
/// Defines an [AccessorFn] for the radius for data bounds lines (typically
|
/// Defines an [AccessorFn] for the radius for data bounds lines (typically
|
||||||
/// drawn by attaching a [ComparisonPointsDecorator] to the renderer.
|
/// drawn by attaching a [ComparisonPointsDecorator] to the renderer.
|
||||||
const boundsLineRadiusPxFnKey = const AttributeKey<AccessorFn<double>>(
|
const boundsLineRadiusPxFnKey = AttributeKey<AccessorFn<double>>(
|
||||||
'SymbolAnnotationRenderer.boundsLineRadiusPxFn');
|
'SymbolAnnotationRenderer.boundsLineRadiusPxFn');
|
||||||
|
|
||||||
const defaultSymbolRendererId = '__default__';
|
const defaultSymbolRendererId = '__default__';
|
||||||
@@ -75,7 +75,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
/// [LinkedHashMap] is used to render the series on the canvas in the same
|
/// [LinkedHashMap] is used to render the series on the canvas in the same
|
||||||
/// order as the data was given to the chart.
|
/// order as the data was given to the chart.
|
||||||
@protected
|
@protected
|
||||||
var seriesPointMap = new LinkedHashMap<String, List<AnimatedPoint<D>>>();
|
var seriesPointMap = LinkedHashMap<String, List<AnimatedPoint<D>>>();
|
||||||
|
|
||||||
// Store a list of lines that exist in the series data.
|
// Store a list of lines that exist in the series data.
|
||||||
//
|
//
|
||||||
@@ -85,14 +85,13 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final _currentKeys = <String>[];
|
final _currentKeys = <String>[];
|
||||||
|
|
||||||
PointRenderer({String rendererId, PointRendererConfig config})
|
PointRenderer({String rendererId, PointRendererConfig config})
|
||||||
: this.config = config ?? new PointRendererConfig(),
|
: this.config = config ?? PointRendererConfig(),
|
||||||
pointRendererDecorators = config?.pointRendererDecorators ?? [],
|
pointRendererDecorators = config?.pointRendererDecorators ?? [],
|
||||||
super(
|
super(
|
||||||
rendererId: rendererId ?? 'point',
|
rendererId: rendererId ?? 'point',
|
||||||
layoutPaintOrder:
|
layoutPaintOrder:
|
||||||
config?.layoutPaintOrder ?? LayoutViewPaintOrder.point,
|
config?.layoutPaintOrder ?? LayoutViewPaintOrder.point,
|
||||||
symbolRenderer:
|
symbolRenderer: config?.symbolRenderer ?? CircleSymbolRenderer());
|
||||||
config?.symbolRenderer ?? new CircleSymbolRenderer());
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void configureSeries(List<MutableSeries<D>> seriesList) {
|
void configureSeries(List<MutableSeries<D>> seriesList) {
|
||||||
@@ -101,7 +100,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void preprocessSeries(List<MutableSeries<D>> seriesList) {
|
void preprocessSeries(List<MutableSeries<D>> seriesList) {
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
final elements = <PointRendererElement<D>>[];
|
final elements = <PointRendererElement<D>>[];
|
||||||
|
|
||||||
// Default to the configured radius if none was defined by the series.
|
// Default to the configured radius if none was defined by the series.
|
||||||
@@ -132,9 +131,8 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// series data between chart draw cycles. Ideally we should require the
|
// series data between chart draw cycles. Ideally we should require the
|
||||||
// user to provide a key function, but this at least provides some
|
// user to provide a key function, but this at least provides some
|
||||||
// smoothing when adding/removing data.
|
// smoothing when adding/removing data.
|
||||||
series.keyFn ??=
|
series.keyFn ??= (index) => '${series.id}__${series.domainFn(index)}__'
|
||||||
(int index) => '${series.id}__${series.domainFn(index)}__'
|
'${series.measureFn(index)}';
|
||||||
'${series.measureFn(index)}';
|
|
||||||
|
|
||||||
for (var index = 0; index < series.data.length; index++) {
|
for (var index = 0; index < series.data.length; index++) {
|
||||||
// Default to the configured radius if none was returned by the
|
// Default to the configured radius if none was returned by the
|
||||||
@@ -181,7 +179,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
var fillColor = fillColorFn(index);
|
var fillColor = fillColorFn(index);
|
||||||
fillColor ??= color;
|
fillColor ??= color;
|
||||||
|
|
||||||
final details = new PointRendererElement<D>()
|
final details = PointRendererElement<D>()
|
||||||
..color = color
|
..color = color
|
||||||
..fillColor = fillColor
|
..fillColor = fillColor
|
||||||
..radiusPx = radiusPx.toDouble()
|
..radiusPx = radiusPx.toDouble()
|
||||||
@@ -203,7 +201,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// later for sorting.
|
// later for sorting.
|
||||||
final sortedSeriesIds = [];
|
final sortedSeriesIds = [];
|
||||||
|
|
||||||
seriesList.forEach((ImmutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
sortedSeriesIds.add(series.id);
|
sortedSeriesIds.add(series.id);
|
||||||
|
|
||||||
final domainAxis = series.getAttr(domainAxisKey) as ImmutableAxis<D>;
|
final domainAxis = series.getAttr(domainAxisKey) as ImmutableAxis<D>;
|
||||||
@@ -256,9 +254,8 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
final pointKey = keyFn(index);
|
final pointKey = keyFn(index);
|
||||||
|
|
||||||
// If we already have an AnimatingPoint for that index, use it.
|
// If we already have an AnimatingPoint for that index, use it.
|
||||||
var animatingPoint = pointList.firstWhere(
|
var animatingPoint = pointList
|
||||||
(AnimatedPoint point) => point.key == pointKey,
|
.firstWhere((point) => point.key == pointKey, orElse: () => null);
|
||||||
orElse: () => null);
|
|
||||||
|
|
||||||
// If we don't have any existing arc element, create a new arc and
|
// If we don't have any existing arc element, create a new arc and
|
||||||
// have it animate in from the position of the previous arc's end
|
// have it animate in from the position of the previous arc's end
|
||||||
@@ -279,9 +276,9 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
0.0,
|
0.0,
|
||||||
measureAxis);
|
measureAxis);
|
||||||
|
|
||||||
animatingPoint = new AnimatedPoint<D>(
|
animatingPoint = AnimatedPoint<D>(
|
||||||
key: pointKey, overlaySeries: series.overlaySeries)
|
key: pointKey, overlaySeries: series.overlaySeries)
|
||||||
..setNewTarget(new PointRendererElement<D>()
|
..setNewTarget(PointRendererElement<D>()
|
||||||
..color = details.color
|
..color = details.color
|
||||||
..fillColor = details.fillColor
|
..fillColor = details.fillColor
|
||||||
..measureAxisPosition = measureAxis.getLocation(0.0)
|
..measureAxisPosition = measureAxis.getLocation(0.0)
|
||||||
@@ -298,7 +295,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
_currentKeys.add(pointKey);
|
_currentKeys.add(pointKey);
|
||||||
|
|
||||||
// Get the pointElement we are going to setup.
|
// Get the pointElement we are going to setup.
|
||||||
final pointElement = new PointRendererElement<D>()
|
final pointElement = PointRendererElement<D>()
|
||||||
..color = details.color
|
..color = details.color
|
||||||
..fillColor = details.fillColor
|
..fillColor = details.fillColor
|
||||||
..measureAxisPosition = measureAxis.getLocation(0.0)
|
..measureAxisPosition = measureAxis.getLocation(0.0)
|
||||||
@@ -315,11 +312,11 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// Sort the renderer elements to be in the same order as the series list.
|
// Sort the renderer elements to be in the same order as the series list.
|
||||||
// They may get disordered between chart draw cycles if a behavior adds or
|
// They may get disordered between chart draw cycles if a behavior adds or
|
||||||
// removes series from the list (e.g. click to hide on legends).
|
// removes series from the list (e.g. click to hide on legends).
|
||||||
seriesPointMap = new LinkedHashMap.fromIterable(sortedSeriesIds,
|
seriesPointMap = LinkedHashMap.fromIterable(sortedSeriesIds,
|
||||||
key: (k) => k, value: (k) => seriesPointMap[k]);
|
key: (k) => k, value: (k) => seriesPointMap[k]);
|
||||||
|
|
||||||
// Animate out points that don't exist anymore.
|
// Animate out points that don't exist anymore.
|
||||||
seriesPointMap.forEach((String key, List<AnimatedPoint<D>> points) {
|
seriesPointMap.forEach((key, points) {
|
||||||
for (var point in points) {
|
for (var point in points) {
|
||||||
if (_currentKeys.contains(point.key) != true) {
|
if (_currentKeys.contains(point.key) != true) {
|
||||||
point.animateOut();
|
point.animateOut();
|
||||||
@@ -342,27 +339,27 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
if (animationPercent == 1.0) {
|
if (animationPercent == 1.0) {
|
||||||
final keysToRemove = <String>[];
|
final keysToRemove = <String>[];
|
||||||
|
|
||||||
seriesPointMap.forEach((String key, List<AnimatedPoint<D>> points) {
|
seriesPointMap.forEach((key, points) {
|
||||||
points.removeWhere((AnimatedPoint<D> point) => point.animatingOut);
|
points.removeWhere((point) => point.animatingOut);
|
||||||
|
|
||||||
if (points.isEmpty) {
|
if (points.isEmpty) {
|
||||||
keysToRemove.add(key);
|
keysToRemove.add(key);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
keysToRemove.forEach((String key) => seriesPointMap.remove(key));
|
keysToRemove.forEach((key) => seriesPointMap.remove(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
seriesPointMap.forEach((String key, List<AnimatedPoint<D>> points) {
|
seriesPointMap.forEach((key, points) {
|
||||||
points
|
points
|
||||||
.map<PointRendererElement<D>>((AnimatedPoint<D> animatingPoint) =>
|
.map<PointRendererElement<D>>((animatingPoint) =>
|
||||||
animatingPoint.getCurrentPoint(animationPercent))
|
animatingPoint.getCurrentPoint(animationPercent))
|
||||||
.forEach((PointRendererElement point) {
|
.forEach((point) {
|
||||||
// Decorate the points with decorators that should appear below the main
|
// Decorate the points with decorators that should appear below the main
|
||||||
// series data.
|
// series data.
|
||||||
pointRendererDecorators
|
pointRendererDecorators
|
||||||
.where((PointRendererDecorator decorator) => !decorator.renderAbove)
|
.where((decorator) => !decorator.renderAbove)
|
||||||
.forEach((PointRendererDecorator decorator) {
|
.forEach((decorator) {
|
||||||
decorator.decorate(point, canvas, graphicsFactory,
|
decorator.decorate(point, canvas, graphicsFactory,
|
||||||
drawBounds: componentBounds,
|
drawBounds: componentBounds,
|
||||||
animationPercent: animationPercent,
|
animationPercent: animationPercent,
|
||||||
@@ -374,7 +371,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// prevents harshly clipping off half of the shape.
|
// prevents harshly clipping off half of the shape.
|
||||||
if (point.point.y != null &&
|
if (point.point.y != null &&
|
||||||
componentBounds.containsPoint(point.point)) {
|
componentBounds.containsPoint(point.point)) {
|
||||||
final bounds = new Rectangle<double>(
|
final bounds = Rectangle<double>(
|
||||||
point.point.x - point.radiusPx,
|
point.point.x - point.radiusPx,
|
||||||
point.point.y - point.radiusPx,
|
point.point.y - point.radiusPx,
|
||||||
point.radiusPx * 2,
|
point.radiusPx * 2,
|
||||||
@@ -388,8 +385,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
} else {
|
} else {
|
||||||
final id = point.symbolRendererId;
|
final id = point.symbolRendererId;
|
||||||
if (!config.customSymbolRenderers.containsKey(id)) {
|
if (!config.customSymbolRenderers.containsKey(id)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError('Invalid custom symbol renderer id "$id"');
|
||||||
'Invalid custom symbol renderer id "${id}"');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final customRenderer = config.customSymbolRenderers[id];
|
final customRenderer = config.customSymbolRenderers[id];
|
||||||
@@ -403,8 +399,8 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// Decorate the points with decorators that should appear above the main
|
// Decorate the points with decorators that should appear above the main
|
||||||
// series data. This is the typical place for labels.
|
// series data. This is the typical place for labels.
|
||||||
pointRendererDecorators
|
pointRendererDecorators
|
||||||
.where((PointRendererDecorator decorator) => decorator.renderAbove)
|
.where((decorator) => decorator.renderAbove)
|
||||||
.forEach((PointRendererDecorator decorator) {
|
.forEach((decorator) {
|
||||||
decorator.decorate(point, canvas, graphicsFactory,
|
decorator.decorate(point, canvas, graphicsFactory,
|
||||||
drawBounds: componentBounds,
|
drawBounds: componentBounds,
|
||||||
animationPercent: animationPercent,
|
animationPercent: animationPercent,
|
||||||
@@ -450,7 +446,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
? measureAxis.getLocation(measureUpperBoundValue + measureOffsetValue)
|
? measureAxis.getLocation(measureUpperBoundValue + measureOffsetValue)
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return new DatumPoint<D>(
|
return DatumPoint<D>(
|
||||||
datum: datum,
|
datum: datum,
|
||||||
domain: domainValue,
|
domain: domainValue,
|
||||||
series: series,
|
series: series,
|
||||||
@@ -472,13 +468,13 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
return nearest;
|
return nearest;
|
||||||
}
|
}
|
||||||
|
|
||||||
seriesPointMap.values.forEach((List<AnimatedPoint<D>> points) {
|
seriesPointMap.values.forEach((points) {
|
||||||
PointRendererElement<D> nearestPoint;
|
PointRendererElement<D> nearestPoint;
|
||||||
double nearestDomainDistance = _maxInitialDistance;
|
double nearestDomainDistance = _maxInitialDistance;
|
||||||
double nearestMeasureDistance = _maxInitialDistance;
|
double nearestMeasureDistance = _maxInitialDistance;
|
||||||
double nearestRelativeDistance = _maxInitialDistance;
|
double nearestRelativeDistance = _maxInitialDistance;
|
||||||
|
|
||||||
points.forEach((AnimatedPoint<D> point) {
|
points.forEach((point) {
|
||||||
if (point.overlaySeries) {
|
if (point.overlaySeries) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -519,14 +515,13 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
} else {
|
} else {
|
||||||
final id = nearestPoint.symbolRendererId;
|
final id = nearestPoint.symbolRendererId;
|
||||||
if (!config.customSymbolRenderers.containsKey(id)) {
|
if (!config.customSymbolRenderers.containsKey(id)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError('Invalid custom symbol renderer id "$id"');
|
||||||
'Invalid custom symbol renderer id "${id}"');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nearestSymbolRenderer = config.customSymbolRenderers[id];
|
nearestSymbolRenderer = config.customSymbolRenderers[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
nearest.add(new DatumDetails<D>(
|
nearest.add(DatumDetails<D>(
|
||||||
datum: nearestPoint.point.datum,
|
datum: nearestPoint.point.datum,
|
||||||
domain: nearestPoint.point.domain,
|
domain: nearestPoint.point.domain,
|
||||||
series: nearestPoint.point.series,
|
series: nearestPoint.point.series,
|
||||||
@@ -573,9 +568,9 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
// use the smaller of this distance and the distance from the primary
|
// use the smaller of this distance and the distance from the primary
|
||||||
// point as the relativeDistance from this datum.
|
// point as the relativeDistance from this datum.
|
||||||
final num relativeDistanceBounds = distanceBetweenPointAndLineSegment(
|
final num relativeDistanceBounds = distanceBetweenPointAndLineSegment(
|
||||||
new Vector2(chartPoint.x, chartPoint.y),
|
Vector2(chartPoint.x, chartPoint.y),
|
||||||
new Vector2(datumPoint.xLower, datumPoint.yLower),
|
Vector2(datumPoint.xLower, datumPoint.yLower),
|
||||||
new Vector2(datumPoint.xUpper, datumPoint.yUpper));
|
Vector2(datumPoint.xUpper, datumPoint.yUpper));
|
||||||
|
|
||||||
insidePoint = (relativeDistance < radiusPx) ||
|
insidePoint = (relativeDistance < radiusPx) ||
|
||||||
(boundsLineRadiusPx != null &&
|
(boundsLineRadiusPx != null &&
|
||||||
@@ -589,7 +584,7 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
insidePoint = (relativeDistance < radiusPx);
|
insidePoint = (relativeDistance < radiusPx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new _Distances(
|
return _Distances(
|
||||||
domainDistance: domainDistance,
|
domainDistance: domainDistance,
|
||||||
measureDistance: measureDistance,
|
measureDistance: measureDistance,
|
||||||
relativeDistance: relativeDistance,
|
relativeDistance: relativeDistance,
|
||||||
@@ -636,16 +631,16 @@ class PointRenderer<D> extends BaseCartesianRenderer<D> {
|
|||||||
} else {
|
} else {
|
||||||
final id = symbolRendererId;
|
final id = symbolRendererId;
|
||||||
if (!config.customSymbolRenderers.containsKey(id)) {
|
if (!config.customSymbolRenderers.containsKey(id)) {
|
||||||
throw new ArgumentError('Invalid custom symbol renderer id "${id}"');
|
throw ArgumentError('Invalid custom symbol renderer id "$id"');
|
||||||
}
|
}
|
||||||
|
|
||||||
nearestSymbolRenderer = config.customSymbolRenderers[id];
|
nearestSymbolRenderer = config.customSymbolRenderers[id];
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DatumDetails.from(details,
|
return DatumDetails.from(details,
|
||||||
chartPosition: new Point<double>(point.x, point.y),
|
chartPosition: Point<double>(point.x, point.y),
|
||||||
chartPositionLower: new Point<double>(point.xLower, point.yLower),
|
chartPositionLower: Point<double>(point.xLower, point.yLower),
|
||||||
chartPositionUpper: new Point<double>(point.xUpper, point.yUpper),
|
chartPositionUpper: Point<double>(point.xUpper, point.yUpper),
|
||||||
symbolRenderer: nearestSymbolRenderer);
|
symbolRenderer: nearestSymbolRenderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -682,7 +677,7 @@ class DatumPoint<D> extends Point<double> {
|
|||||||
double y,
|
double y,
|
||||||
double yLower,
|
double yLower,
|
||||||
double yUpper}) {
|
double yUpper}) {
|
||||||
return new DatumPoint<D>(
|
return DatumPoint<D>(
|
||||||
datum: other.datum,
|
datum: other.datum,
|
||||||
domain: other.domain,
|
domain: other.domain,
|
||||||
series: other.series,
|
series: other.series,
|
||||||
@@ -706,11 +701,10 @@ class PointRendererElement<D> {
|
|||||||
String symbolRendererId;
|
String symbolRendererId;
|
||||||
|
|
||||||
PointRendererElement<D> clone() {
|
PointRendererElement<D> clone() {
|
||||||
return new PointRendererElement<D>()
|
return PointRendererElement<D>()
|
||||||
..point = new DatumPoint<D>.from(point)
|
..point = DatumPoint<D>.from(point)
|
||||||
..color = color != null ? new Color.fromOther(color: color) : null
|
..color = color != null ? Color.fromOther(color: color) : null
|
||||||
..fillColor =
|
..fillColor = fillColor != null ? Color.fromOther(color: fillColor) : null
|
||||||
fillColor != null ? new Color.fromOther(color: fillColor) : null
|
|
||||||
..measureAxisPosition = measureAxisPosition
|
..measureAxisPosition = measureAxisPosition
|
||||||
..radiusPx = radiusPx
|
..radiusPx = radiusPx
|
||||||
..boundsLineRadiusPx = boundsLineRadiusPx
|
..boundsLineRadiusPx = boundsLineRadiusPx
|
||||||
@@ -756,7 +750,7 @@ class PointRendererElement<D> {
|
|||||||
previousPoint.yUpper
|
previousPoint.yUpper
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
point = new DatumPoint<D>.from(targetPoint,
|
point = DatumPoint<D>.from(targetPoint,
|
||||||
x: x,
|
x: x,
|
||||||
xLower: xLower,
|
xLower: xLower,
|
||||||
xUpper: xUpper,
|
xUpper: xUpper,
|
||||||
@@ -808,7 +802,7 @@ class AnimatedPoint<D> {
|
|||||||
|
|
||||||
// Set the target measure value to the axis position.
|
// Set the target measure value to the axis position.
|
||||||
var targetPoint = newTarget.point;
|
var targetPoint = newTarget.point;
|
||||||
newTarget.point = new DatumPoint<D>.from(targetPoint,
|
newTarget.point = DatumPoint<D>.from(targetPoint,
|
||||||
x: targetPoint.x,
|
x: targetPoint.x,
|
||||||
y: newTarget.measureAxisPosition.roundToDouble(),
|
y: newTarget.measureAxisPosition.roundToDouble(),
|
||||||
yLower: newTarget.measureAxisPosition.roundToDouble(),
|
yLower: newTarget.measureAxisPosition.roundToDouble(),
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class PointRendererConfig<D> extends LayoutViewConfig
|
|||||||
/// [symbolRenderer].
|
/// [symbolRenderer].
|
||||||
final Map<String, SymbolRenderer> customSymbolRenderers;
|
final Map<String, SymbolRenderer> customSymbolRenderers;
|
||||||
|
|
||||||
final rendererAttributes = new RendererAttributes();
|
final rendererAttributes = RendererAttributes();
|
||||||
|
|
||||||
/// Default radius of the points, used if a series does not define a radiusPx
|
/// Default radius of the points, used if a series does not define a radiusPx
|
||||||
/// accessor function.
|
/// accessor function.
|
||||||
@@ -75,6 +75,6 @@ class PointRendererConfig<D> extends LayoutViewConfig
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
PointRenderer<D> build() {
|
PointRenderer<D> build() {
|
||||||
return new PointRenderer<D>(config: this, rendererId: customRendererId);
|
return PointRenderer<D>(config: this, rendererId: customRendererId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,13 +55,12 @@ class ScatterPlotChart extends NumericCartesianChart {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
SeriesRenderer<num> makeDefaultRenderer() {
|
SeriesRenderer<num> makeDefaultRenderer() {
|
||||||
return new PointRenderer<num>()
|
return PointRenderer<num>()..rendererId = SeriesRenderer.defaultRendererId;
|
||||||
..rendererId = SeriesRenderer.defaultRendererId;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initDomainAxis() {
|
void initDomainAxis() {
|
||||||
domainAxis.tickDrawStrategy = new GridlineRendererSpec<num>()
|
domainAxis.tickDrawStrategy = GridlineRendererSpec<num>()
|
||||||
.createDrawStrategy(context, graphicsFactory);
|
.createDrawStrategy(context, graphicsFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import '../layout/layout_view.dart'
|
|||||||
LayoutViewPaintOrder,
|
LayoutViewPaintOrder,
|
||||||
LayoutViewPositionOrder,
|
LayoutViewPositionOrder,
|
||||||
ViewMeasuredSizes;
|
ViewMeasuredSizes;
|
||||||
import 'point_renderer.dart' show AnimatedPoint, DatumPoint, PointRenderer;
|
import 'point_renderer.dart' show DatumPoint, PointRenderer;
|
||||||
import 'symbol_annotation_renderer_config.dart'
|
import 'symbol_annotation_renderer_config.dart'
|
||||||
show SymbolAnnotationRendererConfig;
|
show SymbolAnnotationRendererConfig;
|
||||||
|
|
||||||
@@ -51,13 +51,13 @@ import 'symbol_annotation_renderer_config.dart'
|
|||||||
class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
||||||
implements LayoutView {
|
implements LayoutView {
|
||||||
Rectangle<int> _componentBounds;
|
Rectangle<int> _componentBounds;
|
||||||
GraphicsFactory _graphicsFactory;
|
GraphicsFactory graphicsFactory;
|
||||||
|
|
||||||
CartesianChart<D> _chart;
|
CartesianChart<D> _chart;
|
||||||
|
|
||||||
var _currentHeight = 0;
|
var _currentHeight = 0;
|
||||||
|
|
||||||
final _seriesInfo = new LinkedHashMap<String, _SeriesInfo<D>>();
|
final _seriesInfo = LinkedHashMap<String, _SeriesInfo<D>>();
|
||||||
|
|
||||||
SymbolAnnotationRenderer(
|
SymbolAnnotationRenderer(
|
||||||
{String rendererId, SymbolAnnotationRendererConfig config})
|
{String rendererId, SymbolAnnotationRendererConfig config})
|
||||||
@@ -79,7 +79,7 @@ class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
|||||||
|
|
||||||
double offset = 0.0;
|
double offset = 0.0;
|
||||||
|
|
||||||
seriesList.forEach((MutableSeries<D> series) {
|
seriesList.forEach((series) {
|
||||||
final seriesKey = series.id;
|
final seriesKey = series.id;
|
||||||
|
|
||||||
// Default to the configured radius if none was defined by the series.
|
// Default to the configured radius if none was defined by the series.
|
||||||
@@ -105,19 +105,18 @@ class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
|||||||
localConfig.verticalSymbolTopPaddingPx +
|
localConfig.verticalSymbolTopPaddingPx +
|
||||||
(rowInnerHeight / 2);
|
(rowInnerHeight / 2);
|
||||||
|
|
||||||
series.measureFn = (int index) => 0;
|
series.measureFn = (index) => 0;
|
||||||
series.measureOffsetFn = (int index) => 0;
|
series.measureOffsetFn = (index) => 0;
|
||||||
|
|
||||||
// Override the key function to allow for range annotations that start at
|
// Override the key function to allow for range annotations that start at
|
||||||
// the same point. This is a necessary hack because every annotation has a
|
// the same point. This is a necessary hack because every annotation has a
|
||||||
// measure value of 0, so the key generated in [PointRenderer] is not
|
// measure value of 0, so the key generated in [PointRenderer] is not
|
||||||
// unique enough.
|
// unique enough.
|
||||||
series.keyFn ??=
|
series.keyFn ??= (index) => '${series.id}__${series.domainFn(index)}__'
|
||||||
(int index) => '${series.id}__${series.domainFn(index)}__'
|
'${series.domainLowerBoundFn(index)}__'
|
||||||
'${series.domainLowerBoundFn(index)}__'
|
'${series.domainUpperBoundFn(index)}';
|
||||||
'${series.domainUpperBoundFn(index)}';
|
|
||||||
|
|
||||||
_seriesInfo[seriesKey] = new _SeriesInfo<D>(
|
_seriesInfo[seriesKey] = _SeriesInfo<D>(
|
||||||
rowHeight: rowHeight,
|
rowHeight: rowHeight,
|
||||||
rowStart: offset,
|
rowStart: offset,
|
||||||
symbolCenter: symbolCenter,
|
symbolCenter: symbolCenter,
|
||||||
@@ -165,7 +164,7 @@ class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
|||||||
final measureUpperBoundPosition =
|
final measureUpperBoundPosition =
|
||||||
domainUpperBoundPosition != null ? measurePosition : null;
|
domainUpperBoundPosition != null ? measurePosition : null;
|
||||||
|
|
||||||
return new DatumPoint<D>(
|
return DatumPoint<D>(
|
||||||
datum: datum,
|
datum: datum,
|
||||||
domain: domainValue,
|
domain: domainValue,
|
||||||
series: series,
|
series: series,
|
||||||
@@ -180,7 +179,7 @@ class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
|||||||
@override
|
@override
|
||||||
void onAttach(BaseChart<D> chart) {
|
void onAttach(BaseChart<D> chart) {
|
||||||
if (!(chart is CartesianChart)) {
|
if (!(chart is CartesianChart)) {
|
||||||
throw new ArgumentError(
|
throw ArgumentError(
|
||||||
'SymbolAnnotationRenderer can only be attached to a CartesianChart');
|
'SymbolAnnotationRenderer can only be attached to a CartesianChart');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,13 +204,13 @@ class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
|||||||
// Use the domain axis of the attached chart to render the separator lines
|
// Use the domain axis of the attached chart to render the separator lines
|
||||||
// to keep the same overall style.
|
// to keep the same overall style.
|
||||||
if ((config as SymbolAnnotationRendererConfig).showSeparatorLines) {
|
if ((config as SymbolAnnotationRendererConfig).showSeparatorLines) {
|
||||||
seriesPointMap.forEach((String key, List<AnimatedPoint<D>> points) {
|
seriesPointMap.forEach((key, points) {
|
||||||
final seriesInfo = _seriesInfo[key];
|
final seriesInfo = _seriesInfo[key];
|
||||||
|
|
||||||
final y = componentBounds.top + seriesInfo.rowStart;
|
final y = componentBounds.top + seriesInfo.rowStart;
|
||||||
|
|
||||||
final domainAxis = _chart.domainAxis;
|
final domainAxis = _chart.domainAxis;
|
||||||
final bounds = new Rectangle<int>(
|
final bounds = Rectangle<int>(
|
||||||
componentBounds.left, y.round(), componentBounds.width, 0);
|
componentBounds.left, y.round(), componentBounds.width, 0);
|
||||||
domainAxis.tickDrawStrategy
|
domainAxis.tickDrawStrategy
|
||||||
.drawAxisLine(canvas, domainAxis.axisOrientation, bounds);
|
.drawAxisLine(canvas, domainAxis.axisOrientation, bounds);
|
||||||
@@ -219,21 +218,13 @@ class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
GraphicsFactory get graphicsFactory => _graphicsFactory;
|
|
||||||
|
|
||||||
@override
|
|
||||||
set graphicsFactory(GraphicsFactory value) {
|
|
||||||
_graphicsFactory = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Layout methods
|
// Layout methods
|
||||||
//
|
//
|
||||||
|
|
||||||
@override
|
@override
|
||||||
LayoutViewConfig get layoutConfig {
|
LayoutViewConfig get layoutConfig {
|
||||||
return new LayoutViewConfig(
|
return LayoutViewConfig(
|
||||||
paintOrder: LayoutViewPaintOrder.point,
|
paintOrder: LayoutViewPaintOrder.point,
|
||||||
position: LayoutPosition.Bottom,
|
position: LayoutPosition.Bottom,
|
||||||
positionOrder: LayoutViewPositionOrder.symbolAnnotation);
|
positionOrder: LayoutViewPositionOrder.symbolAnnotation);
|
||||||
@@ -244,7 +235,7 @@ class SymbolAnnotationRenderer<D> extends PointRenderer<D>
|
|||||||
// The sizing of component is not flexible. It's height is always a multiple
|
// The sizing of component is not flexible. It's height is always a multiple
|
||||||
// of the number of series rendered, even if that ends up taking all of the
|
// of the number of series rendered, even if that ends up taking all of the
|
||||||
// available margin space.
|
// available margin space.
|
||||||
return new ViewMeasuredSizes(
|
return ViewMeasuredSizes(
|
||||||
preferredWidth: maxWidth, preferredHeight: _currentHeight);
|
preferredWidth: maxWidth, preferredHeight: _currentHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,8 +57,8 @@ class SymbolAnnotationRendererConfig<D> extends PointRendererConfig<D> {
|
|||||||
customRendererId: customRendererId,
|
customRendererId: customRendererId,
|
||||||
pointRendererDecorators: pointRendererDecorators ??
|
pointRendererDecorators: pointRendererDecorators ??
|
||||||
[
|
[
|
||||||
new ComparisonPointsDecorator(
|
ComparisonPointsDecorator(
|
||||||
symbolRenderer: new RectangleRangeSymbolRenderer())
|
symbolRenderer: RectangleRangeSymbolRenderer())
|
||||||
],
|
],
|
||||||
radiusPx: radiusPx,
|
radiusPx: radiusPx,
|
||||||
symbolRenderer: symbolRenderer,
|
symbolRenderer: symbolRenderer,
|
||||||
@@ -66,7 +66,7 @@ class SymbolAnnotationRendererConfig<D> extends PointRendererConfig<D> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
SymbolAnnotationRenderer<D> build() {
|
SymbolAnnotationRenderer<D> build() {
|
||||||
return new SymbolAnnotationRenderer<D>(
|
return SymbolAnnotationRenderer<D>(
|
||||||
config: this, rendererId: customRendererId);
|
config: this, rendererId: customRendererId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,20 +41,20 @@ class TimeSeriesChart extends CartesianChart<DateTime> {
|
|||||||
: super(
|
: super(
|
||||||
vertical: vertical,
|
vertical: vertical,
|
||||||
layoutConfig: layoutConfig,
|
layoutConfig: layoutConfig,
|
||||||
domainAxis: new DateTimeAxis(dateTimeFactory),
|
domainAxis: DateTimeAxis(dateTimeFactory),
|
||||||
primaryMeasureAxis: primaryMeasureAxis,
|
primaryMeasureAxis: primaryMeasureAxis,
|
||||||
secondaryMeasureAxis: secondaryMeasureAxis,
|
secondaryMeasureAxis: secondaryMeasureAxis,
|
||||||
disjointMeasureAxes: disjointMeasureAxes);
|
disjointMeasureAxes: disjointMeasureAxes);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initDomainAxis() {
|
void initDomainAxis() {
|
||||||
domainAxis.tickDrawStrategy = new SmallTickRendererSpec<DateTime>()
|
domainAxis.tickDrawStrategy = SmallTickRendererSpec<DateTime>()
|
||||||
.createDrawStrategy(context, graphicsFactory);
|
.createDrawStrategy(context, graphicsFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
SeriesRenderer<DateTime> makeDefaultRenderer() {
|
SeriesRenderer<DateTime> makeDefaultRenderer() {
|
||||||
return new LineRenderer<DateTime>()
|
return LineRenderer<DateTime>()
|
||||||
..rendererId = SeriesRenderer.defaultRendererId;
|
..rendererId = SeriesRenderer.defaultRendererId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,9 +17,9 @@ import 'package:meta/meta.dart' show immutable;
|
|||||||
|
|
||||||
@immutable
|
@immutable
|
||||||
class Color {
|
class Color {
|
||||||
static const black = const Color(r: 0, g: 0, b: 0);
|
static const black = Color(r: 0, g: 0, b: 0);
|
||||||
static const white = const Color(r: 255, g: 255, b: 255);
|
static const white = Color(r: 255, g: 255, b: 255);
|
||||||
static const transparent = const Color(r: 0, g: 0, b: 0, a: 0);
|
static const transparent = Color(r: 0, g: 0, b: 0, a: 0);
|
||||||
|
|
||||||
static const _darkerPercentOfOrig = 0.7;
|
static const _darkerPercentOfOrig = 0.7;
|
||||||
static const _lighterPercentOfOrig = 0.1;
|
static const _lighterPercentOfOrig = 0.1;
|
||||||
@@ -53,12 +53,12 @@ class Color {
|
|||||||
final g = (bigint >> 8) & 255;
|
final g = (bigint >> 8) & 255;
|
||||||
final b = bigint & 255;
|
final b = bigint & 255;
|
||||||
final a = 255;
|
final a = 255;
|
||||||
return new Color(r: r, g: g, b: b, a: a);
|
return Color(r: r, g: g, b: b, a: a);
|
||||||
}
|
}
|
||||||
|
|
||||||
Color get darker =>
|
Color get darker =>
|
||||||
_darker ??
|
_darker ??
|
||||||
new Color(
|
Color(
|
||||||
r: (r * _darkerPercentOfOrig).round(),
|
r: (r * _darkerPercentOfOrig).round(),
|
||||||
g: (g * _darkerPercentOfOrig).round(),
|
g: (g * _darkerPercentOfOrig).round(),
|
||||||
b: (b * _darkerPercentOfOrig).round(),
|
b: (b * _darkerPercentOfOrig).round(),
|
||||||
@@ -66,7 +66,7 @@ class Color {
|
|||||||
|
|
||||||
Color get lighter =>
|
Color get lighter =>
|
||||||
_lighter ??
|
_lighter ??
|
||||||
new Color(
|
Color(
|
||||||
r: r + ((255 - r) * _lighterPercentOfOrig).round(),
|
r: r + ((255 - r) * _lighterPercentOfOrig).round(),
|
||||||
g: g + ((255 - g) * _lighterPercentOfOrig).round(),
|
g: g + ((255 - g) * _lighterPercentOfOrig).round(),
|
||||||
b: b + ((255 - b) * _lighterPercentOfOrig).round(),
|
b: b + ((255 - b) * _lighterPercentOfOrig).round(),
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ class LocalDateTimeFactory implements DateTimeFactory {
|
|||||||
|
|
||||||
DateTime createDateTimeFromMilliSecondsSinceEpoch(
|
DateTime createDateTimeFromMilliSecondsSinceEpoch(
|
||||||
int millisecondsSinceEpoch) {
|
int millisecondsSinceEpoch) {
|
||||||
return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
|
return DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch);
|
||||||
}
|
}
|
||||||
|
|
||||||
DateTime createDateTime(int year,
|
DateTime createDateTime(int year,
|
||||||
@@ -59,13 +59,13 @@ class LocalDateTimeFactory implements DateTimeFactory {
|
|||||||
int second = 0,
|
int second = 0,
|
||||||
int millisecond = 0,
|
int millisecond = 0,
|
||||||
int microsecond = 0]) {
|
int microsecond = 0]) {
|
||||||
return new DateTime(
|
return DateTime(
|
||||||
year, month, day, hour, minute, second, millisecond, microsecond);
|
year, month, day, hour, minute, second, millisecond, microsecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a [DateFormat].
|
/// Returns a [DateFormat].
|
||||||
DateFormat createDateFormat(String pattern) {
|
DateFormat createDateFormat(String pattern) {
|
||||||
return new DateFormat(pattern);
|
return DateFormat(pattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ class UTCDateTimeFactory implements DateTimeFactory {
|
|||||||
|
|
||||||
DateTime createDateTimeFromMilliSecondsSinceEpoch(
|
DateTime createDateTimeFromMilliSecondsSinceEpoch(
|
||||||
int millisecondsSinceEpoch) {
|
int millisecondsSinceEpoch) {
|
||||||
return new DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
|
return DateTime.fromMillisecondsSinceEpoch(millisecondsSinceEpoch,
|
||||||
isUtc: true);
|
isUtc: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,12 +87,12 @@ class UTCDateTimeFactory implements DateTimeFactory {
|
|||||||
int second = 0,
|
int second = 0,
|
||||||
int millisecond = 0,
|
int millisecond = 0,
|
||||||
int microsecond = 0]) {
|
int microsecond = 0]) {
|
||||||
return new DateTime.utc(
|
return DateTime.utc(
|
||||||
year, month, day, hour, minute, second, millisecond, microsecond);
|
year, month, day, hour, minute, second, millisecond, microsecond);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a [DateFormat].
|
/// Returns a [DateFormat].
|
||||||
DateFormat createDateFormat(String pattern) {
|
DateFormat createDateFormat(String pattern) {
|
||||||
return new DateFormat(pattern);
|
return DateFormat(pattern);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,10 +95,11 @@ class GestureListener {
|
|||||||
this.onTapCancel = onTapCancel ?? defaultTapCancel;
|
this.onTapCancel = onTapCancel ?? defaultTapCancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef GestureCancelCallback();
|
typedef GestureCancelCallback = Function();
|
||||||
typedef bool GestureSinglePointCallback(Point<double> localPosition);
|
typedef GestureSinglePointCallback = bool Function(Point<double> localPosition);
|
||||||
|
|
||||||
typedef bool GestureDragStartCallback(Point<double> localPosition);
|
typedef GestureDragStartCallback = bool Function(Point<double> localPosition);
|
||||||
typedef GestureDragUpdateCallback(Point<double> localPosition, double scale);
|
typedef GestureDragUpdateCallback = Function(
|
||||||
typedef GestureDragEndCallback(
|
Point<double> localPosition, double scale);
|
||||||
|
typedef GestureDragEndCallback = Function(
|
||||||
Point<double> localPosition, double scale, double pixelsPerSec);
|
Point<double> localPosition, double scale, double pixelsPerSec);
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ import 'palette.dart' show Palette;
|
|||||||
///
|
///
|
||||||
/// @link https://material.io/guidelines/style/color.html#color-color-palette
|
/// @link https://material.io/guidelines/style/color.html#color-color-palette
|
||||||
class MaterialPalette {
|
class MaterialPalette {
|
||||||
static const black = const Color(r: 0, g: 0, b: 0);
|
static const black = Color(r: 0, g: 0, b: 0);
|
||||||
static const transparent = const Color(r: 0, g: 0, b: 0, a: 0);
|
static const transparent = Color(r: 0, g: 0, b: 0, a: 0);
|
||||||
static const white = const Color(r: 255, g: 255, b: 255);
|
static const white = Color(r: 255, g: 255, b: 255);
|
||||||
|
|
||||||
static Palette get blue => const MaterialBlue();
|
static Palette get blue => const MaterialBlue();
|
||||||
static Palette get red => const MaterialRed();
|
static Palette get red => const MaterialRed();
|
||||||
@@ -77,10 +77,10 @@ class MaterialPalette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialBlue extends Palette {
|
class MaterialBlue extends Palette {
|
||||||
static const _shade200 = const Color(r: 0x90, g: 0xCA, b: 0xF9); //#90CAF9
|
static const _shade200 = Color(r: 0x90, g: 0xCA, b: 0xF9); //#90CAF9
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0x21, g: 0x96, b: 0xF3, darker: _shade700, lighter: _shade200);
|
Color(r: 0x21, g: 0x96, b: 0xF3, darker: _shade700, lighter: _shade200);
|
||||||
static const _shade700 = const Color(r: 0x19, g: 0x76, b: 0xD2); //#1976D2
|
static const _shade700 = Color(r: 0x19, g: 0x76, b: 0xD2); //#1976D2
|
||||||
|
|
||||||
const MaterialBlue();
|
const MaterialBlue();
|
||||||
|
|
||||||
@@ -89,10 +89,10 @@ class MaterialBlue extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialRed extends Palette {
|
class MaterialRed extends Palette {
|
||||||
static const _shade200 = const Color(r: 0xEF, g: 0x9A, b: 0x9A); //#EF9A9A
|
static const _shade200 = Color(r: 0xEF, g: 0x9A, b: 0x9A); //#EF9A9A
|
||||||
static const _shade700 = const Color(r: 0xD3, g: 0x2F, b: 0x2F); //#D32F2F
|
static const _shade700 = Color(r: 0xD3, g: 0x2F, b: 0x2F); //#D32F2F
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0xF4, g: 0x43, b: 0x36, darker: _shade700, lighter: _shade200);
|
Color(r: 0xF4, g: 0x43, b: 0x36, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialRed();
|
const MaterialRed();
|
||||||
|
|
||||||
@@ -101,10 +101,10 @@ class MaterialRed extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialYellow extends Palette {
|
class MaterialYellow extends Palette {
|
||||||
static const _shade200 = const Color(r: 0xFF, g: 0xF5, b: 0x9D); //#FFF59D
|
static const _shade200 = Color(r: 0xFF, g: 0xF5, b: 0x9D); //#FFF59D
|
||||||
static const _shade700 = const Color(r: 0xFB, g: 0xC0, b: 0x2D); //#FBC02D
|
static const _shade700 = Color(r: 0xFB, g: 0xC0, b: 0x2D); //#FBC02D
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0xFF, g: 0xEB, b: 0x3B, darker: _shade700, lighter: _shade200);
|
Color(r: 0xFF, g: 0xEB, b: 0x3B, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialYellow();
|
const MaterialYellow();
|
||||||
|
|
||||||
@@ -113,10 +113,10 @@ class MaterialYellow extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialGreen extends Palette {
|
class MaterialGreen extends Palette {
|
||||||
static const _shade200 = const Color(r: 0xA5, g: 0xD6, b: 0xA7); //#A5D6A7
|
static const _shade200 = Color(r: 0xA5, g: 0xD6, b: 0xA7); //#A5D6A7
|
||||||
static const _shade700 = const Color(r: 0x38, g: 0x8E, b: 0x3C); //#388E3C;
|
static const _shade700 = Color(r: 0x38, g: 0x8E, b: 0x3C); //#388E3C;
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0x4C, g: 0xAF, b: 0x50, darker: _shade700, lighter: _shade200);
|
Color(r: 0x4C, g: 0xAF, b: 0x50, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialGreen();
|
const MaterialGreen();
|
||||||
|
|
||||||
@@ -125,10 +125,10 @@ class MaterialGreen extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialPurple extends Palette {
|
class MaterialPurple extends Palette {
|
||||||
static const _shade200 = const Color(r: 0xCE, g: 0x93, b: 0xD8); //#CE93D8
|
static const _shade200 = Color(r: 0xCE, g: 0x93, b: 0xD8); //#CE93D8
|
||||||
static const _shade700 = const Color(r: 0x7B, g: 0x1F, b: 0xA2); //#7B1FA2
|
static const _shade700 = Color(r: 0x7B, g: 0x1F, b: 0xA2); //#7B1FA2
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0x9C, g: 0x27, b: 0xB0, darker: _shade700, lighter: _shade200);
|
Color(r: 0x9C, g: 0x27, b: 0xB0, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialPurple();
|
const MaterialPurple();
|
||||||
|
|
||||||
@@ -137,10 +137,10 @@ class MaterialPurple extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialCyan extends Palette {
|
class MaterialCyan extends Palette {
|
||||||
static const _shade200 = const Color(r: 0x80, g: 0xDE, b: 0xEA); //#80DEEA
|
static const _shade200 = Color(r: 0x80, g: 0xDE, b: 0xEA); //#80DEEA
|
||||||
static const _shade700 = const Color(r: 0x00, g: 0x97, b: 0xA7); //#0097A7
|
static const _shade700 = Color(r: 0x00, g: 0x97, b: 0xA7); //#0097A7
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0x00, g: 0xBC, b: 0xD4, darker: _shade700, lighter: _shade200);
|
Color(r: 0x00, g: 0xBC, b: 0xD4, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialCyan();
|
const MaterialCyan();
|
||||||
|
|
||||||
@@ -149,10 +149,10 @@ class MaterialCyan extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialDeepOrange extends Palette {
|
class MaterialDeepOrange extends Palette {
|
||||||
static const _shade200 = const Color(r: 0xFF, g: 0xAB, b: 0x91); //#FFAB91
|
static const _shade200 = Color(r: 0xFF, g: 0xAB, b: 0x91); //#FFAB91
|
||||||
static const _shade700 = const Color(r: 0xE6, g: 0x4A, b: 0x19); //#E64A19
|
static const _shade700 = Color(r: 0xE6, g: 0x4A, b: 0x19); //#E64A19
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0xFF, g: 0x57, b: 0x22, darker: _shade700, lighter: _shade200);
|
Color(r: 0xFF, g: 0x57, b: 0x22, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialDeepOrange();
|
const MaterialDeepOrange();
|
||||||
|
|
||||||
@@ -161,10 +161,10 @@ class MaterialDeepOrange extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialLime extends Palette {
|
class MaterialLime extends Palette {
|
||||||
static const _shade200 = const Color(r: 0xE6, g: 0xEE, b: 0x9C); //#E6EE9C
|
static const _shade200 = Color(r: 0xE6, g: 0xEE, b: 0x9C); //#E6EE9C
|
||||||
static const _shade700 = const Color(r: 0xAF, g: 0xB4, b: 0x2B); //#AFB42B
|
static const _shade700 = Color(r: 0xAF, g: 0xB4, b: 0x2B); //#AFB42B
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0xCD, g: 0xDC, b: 0x39, darker: _shade700, lighter: _shade200);
|
Color(r: 0xCD, g: 0xDC, b: 0x39, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialLime();
|
const MaterialLime();
|
||||||
|
|
||||||
@@ -173,10 +173,10 @@ class MaterialLime extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialIndigo extends Palette {
|
class MaterialIndigo extends Palette {
|
||||||
static const _shade200 = const Color(r: 0x9F, g: 0xA8, b: 0xDA); //#9FA8DA
|
static const _shade200 = Color(r: 0x9F, g: 0xA8, b: 0xDA); //#9FA8DA
|
||||||
static const _shade700 = const Color(r: 0x30, g: 0x3F, b: 0x9F); //#303F9F
|
static const _shade700 = Color(r: 0x30, g: 0x3F, b: 0x9F); //#303F9F
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0x3F, g: 0x51, b: 0xB5, darker: _shade700, lighter: _shade200);
|
Color(r: 0x3F, g: 0x51, b: 0xB5, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialIndigo();
|
const MaterialIndigo();
|
||||||
|
|
||||||
@@ -185,10 +185,10 @@ class MaterialIndigo extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialPink extends Palette {
|
class MaterialPink extends Palette {
|
||||||
static const _shade200 = const Color(r: 0xF4, g: 0x8F, b: 0xB1); //#F48FB1
|
static const _shade200 = Color(r: 0xF4, g: 0x8F, b: 0xB1); //#F48FB1
|
||||||
static const _shade700 = const Color(r: 0xC2, g: 0x18, b: 0x5B); //#C2185B
|
static const _shade700 = Color(r: 0xC2, g: 0x18, b: 0x5B); //#C2185B
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0xE9, g: 0x1E, b: 0x63, darker: _shade700, lighter: _shade200);
|
Color(r: 0xE9, g: 0x1E, b: 0x63, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialPink();
|
const MaterialPink();
|
||||||
|
|
||||||
@@ -197,10 +197,10 @@ class MaterialPink extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialTeal extends Palette {
|
class MaterialTeal extends Palette {
|
||||||
static const _shade200 = const Color(r: 0x80, g: 0xCB, b: 0xC4); //#80CBC4
|
static const _shade200 = Color(r: 0x80, g: 0xCB, b: 0xC4); //#80CBC4
|
||||||
static const _shade700 = const Color(r: 0x00, g: 0x79, b: 0x6B); //#00796B
|
static const _shade700 = Color(r: 0x00, g: 0x79, b: 0x6B); //#00796B
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0x00, g: 0x96, b: 0x88, darker: _shade700, lighter: _shade200);
|
Color(r: 0x00, g: 0x96, b: 0x88, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialTeal();
|
const MaterialTeal();
|
||||||
|
|
||||||
@@ -209,10 +209,10 @@ class MaterialTeal extends Palette {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class MaterialGray extends Palette {
|
class MaterialGray extends Palette {
|
||||||
static const _shade200 = const Color(r: 0xEE, g: 0xEE, b: 0xEE); //#EEEEEE
|
static const _shade200 = Color(r: 0xEE, g: 0xEE, b: 0xEE); //#EEEEEE
|
||||||
static const _shade700 = const Color(r: 0x61, g: 0x61, b: 0x61); //#616161
|
static const _shade700 = Color(r: 0x61, g: 0x61, b: 0x61); //#616161
|
||||||
static const _shade500 = const Color(
|
static const _shade500 =
|
||||||
r: 0x9E, g: 0x9E, b: 0x9E, darker: _shade700, lighter: _shade200);
|
Color(r: 0x9E, g: 0x9E, b: 0x9E, darker: _shade700, lighter: _shade200);
|
||||||
|
|
||||||
const MaterialGray();
|
const MaterialGray();
|
||||||
|
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ abstract class Palette {
|
|||||||
darker: shadeDefault.darker, lighter: lighterColor));
|
darker: shadeDefault.darker, lighter: lighterColor));
|
||||||
}
|
}
|
||||||
|
|
||||||
colors.add(new Color.fromOther(color: shadeDefault, lighter: lighterColor));
|
colors.add(Color.fromOther(color: shadeDefault, lighter: lighterColor));
|
||||||
return colors;
|
return colors;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color _getSteppedColor(Color color, int index, int steps,
|
Color _getSteppedColor(Color color, int index, int steps,
|
||||||
{Color darker, Color lighter}) {
|
{Color darker, Color lighter}) {
|
||||||
final fraction = index / steps;
|
final fraction = index / steps;
|
||||||
return new Color(
|
return Color(
|
||||||
r: color.r + ((255 - color.r) * fraction).round(),
|
r: color.r + ((255 - color.r) * fraction).round(),
|
||||||
g: color.g + ((255 - color.g) * fraction).round(),
|
g: color.g + ((255 - color.g) * fraction).round(),
|
||||||
b: color.b + ((255 - color.b) * fraction).round(),
|
b: color.b + ((255 - color.b) * fraction).round(),
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user