diff --git a/charts_common/test/chart/bar/renderer_nearest_detail_test.dart b/charts_common/test/chart/bar/renderer_nearest_detail_test.dart new file mode 100644 index 000000000..de4ccbf04 --- /dev/null +++ b/charts_common/test/chart/bar/renderer_nearest_detail_test.dart @@ -0,0 +1,1531 @@ +// Copyright 2018 the Charts project authors. Please see the AUTHORS file +// for details. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import 'dart:math'; + +import 'package:mockito/mockito.dart'; +import 'package:nimble_charts_common/src/chart/bar/bar_renderer.dart'; +import 'package:nimble_charts_common/src/chart/bar/bar_renderer_config.dart'; +import 'package:nimble_charts_common/src/chart/bar/bar_target_line_renderer.dart'; +import 'package:nimble_charts_common/src/chart/bar/bar_target_line_renderer_config.dart'; +import 'package:nimble_charts_common/src/chart/bar/base_bar_renderer.dart'; +import 'package:nimble_charts_common/src/chart/bar/base_bar_renderer_config.dart'; +import 'package:nimble_charts_common/src/chart/cartesian/axis/axis.dart'; +import 'package:nimble_charts_common/src/chart/common/processed_series.dart'; +import 'package:nimble_charts_common/src/common/color.dart'; +import 'package:nimble_charts_common/src/data/series.dart'; +import 'package:test/test.dart'; + +import '../../mox.mocks.dart'; + +/// Datum/Row for the chart. +class MyRow { + MyRow(this.campaign, this.clickCount); + final String campaign; + final int clickCount; +} + +/// Datum for the time series chart +class MyDateTimeRow { + MyDateTimeRow(this.time, this.clickCount); + final DateTime time; + final int clickCount; +} + +void main() { + final date0 = DateTime(2018, 2); + final date1 = DateTime(2018, 2, 7); + final dateOutsideViewport = DateTime(2018); + + ///////////////////////////////////////// + // Convenience methods for creating mocks. + ///////////////////////////////////////// + BaseBarRenderer configureBaseRenderer( + BaseBarRenderer renderer, + bool vertical, + ) { + final context = MockChartContext(); + when(context.chartContainerIsRtl).thenReturn(false); + when(context.isRtl).thenReturn(false); + final verticalChart = MockChart(); + when(verticalChart.vertical).thenReturn(vertical); + when(verticalChart.context).thenReturn(context); + renderer.onAttach(verticalChart); + + final layoutBounds = vertical + ? const Rectangle(70, 20, 230, 100) + : const Rectangle(70, 20, 100, 230); + renderer.layout(layoutBounds, layoutBounds); + return renderer; + } + + BaseBarRenderer makeBarRenderer({ + required bool vertical, + required BarGroupingType groupType, + }) { + final renderer = + BarRenderer(config: BarRendererConfig(groupingType: groupType)); + configureBaseRenderer(renderer, vertical); + return renderer; + } + + BaseBarRenderer makeBarTargetRenderer({ + required bool vertical, + required BarGroupingType groupType, + }) { + final renderer = BarTargetLineRenderer( + config: BarTargetLineRendererConfig(groupingType: groupType), + ); + configureBaseRenderer(renderer, vertical); + return renderer; + } + + MutableSeries makeSeries({ + required String id, + String? seriesCategory, + bool vertical = true, + }) { + final data = [ + MyRow('camp0', 10), + MyRow('camp1', 10), + ]; + + final series = MutableSeries( + Series( + id: id, + data: data, + domainFn: (row, _) => row.campaign, + measureFn: (row, _) => row.clickCount, + seriesCategory: seriesCategory, + ), + ) + ..measureOffsetFn = ((_) => 0.0) + ..colorFn = (_) => Color.fromHex(code: '#000000'); + + // Mock the Domain axis results. + final domainAxis = MockOrdinalAxis(); + when(domainAxis.rangeBand).thenReturn(100); + final domainOffset = vertical ? 70.0 : 20.0; + when(domainAxis.getLocation('camp0')) + .thenReturn(domainOffset + 10.0 + 50.0); + when(domainAxis.getLocation('camp1')) + .thenReturn(domainOffset + 10.0 + 100.0 + 10.0 + 50.0); + when(domainAxis.getLocation('outsideViewport')).thenReturn(-51); + + if (vertical) { + when(domainAxis.getDomain(100)).thenReturn('camp0'); + when(domainAxis.getDomain(93)).thenReturn('camp0'); + when(domainAxis.getDomain(130)).thenReturn('camp0'); + when(domainAxis.getDomain(65)).thenReturn('outsideViewport'); + } else { + when(domainAxis.getDomain(50)).thenReturn('camp0'); + when(domainAxis.getDomain(43)).thenReturn('camp0'); + when(domainAxis.getDomain(80)).thenReturn('camp0'); + } + series.setAttr(domainAxisKey, domainAxis); + + // Mock the Measure axis results. + final measureAxis = MockAxis(); + if (vertical) { + when(measureAxis.getLocation(0.0)).thenReturn(20.0 + 100.0); + when(measureAxis.getLocation(10.0)).thenReturn(20.0 + 100.0 - 10.0); + when(measureAxis.getLocation(20.0)).thenReturn(20.0 + 100.0 - 20.0); + } else { + when(measureAxis.getLocation(0.0)).thenReturn(70); + when(measureAxis.getLocation(10.0)).thenReturn(70.0 + 10.0); + when(measureAxis.getLocation(20.0)).thenReturn(70.0 + 20.0); + } + series.setAttr(measureAxisKey, measureAxis); + + return series; + } + + MutableSeries makeDateTimeSeries({ + required String id, + String? seriesCategory, + bool vertical = true, + }) { + final data = [ + MyDateTimeRow(date0, 10), + MyDateTimeRow(date1, 10), + ]; + + final series = MutableSeries( + Series( + id: id, + data: data, + domainFn: (row, _) => row.time, + measureFn: (row, _) => row.clickCount, + seriesCategory: seriesCategory, + ), + ) + ..measureOffsetFn = ((_) => 0.0) + ..colorFn = (_) => Color.fromHex(code: '#000000'); + + // Mock the Domain axis results. + final domainAxis = MockAxis(); + when(domainAxis.rangeBand).thenReturn(100); + final domainOffset = vertical ? 70.0 : 20.0; + when(domainAxis.getLocation(date0)).thenReturn(domainOffset + 10.0 + 50.0); + when(domainAxis.getLocation(date1)) + .thenReturn(domainOffset + 10.0 + 100.0 + 10.0 + 50.0); + when(domainAxis.getLocation(dateOutsideViewport)).thenReturn(-51); + + series.setAttr(domainAxisKey, domainAxis); + + // Mock the Measure axis results. + final measureAxis = MockAxis(); + if (vertical) { + when(measureAxis.getLocation(0.0)).thenReturn(20.0 + 100.0); + when(measureAxis.getLocation(10.0)).thenReturn(20.0 + 100.0 - 10.0); + when(measureAxis.getLocation(20.0)).thenReturn(20.0 + 100.0 - 20.0); + } else { + when(measureAxis.getLocation(0.0)).thenReturn(70); + when(measureAxis.getLocation(10.0)).thenReturn(70.0 + 10.0); + when(measureAxis.getLocation(20.0)).thenReturn(70.0 + 20.0); + } + series.setAttr(measureAxisKey, measureAxis); + + return series; + } + + late bool selectNearestByDomain; + + setUp(() { + selectNearestByDomain = true; + }); + + ///////////////////////////////////////// + // Additional edge test cases + ///////////////////////////////////////// + group('edge cases', () { + test('hit target on missing data in group should highlight group', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo')..data.clear(), + makeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('bar')); + expect(closest.datum, equals(seriesList[1].data[0])); + expect(closest.domainDistance, equals(31)); // 2 + 49 - 20 + expect(closest.measureDistance, equals(0)); + }); + + test('all series without data is skipped', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo')..data.clear(), + makeSeries(id: 'bar')..data.clear(), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(0)); + }); + + test('single overlay series is skipped', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo')..overlaySeries = true, + makeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('bar')); + expect(closest.datum, equals(seriesList[1].data[0])); + expect(closest.domainDistance, equals(31)); // 2 + 49 - 20 + expect(closest.measureDistance, equals(0)); + }); + + test('all overlay series is skipped', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo')..overlaySeries = true, + makeSeries(id: 'bar')..overlaySeries = true, + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(0)); + }); + }); + + ///////////////////////////////////////// + // Vertical BarRenderer + ///////////////////////////////////////// + group('Vertical BarRenderer', () { + test('hit test works on bar', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.stacked); + final seriesList = [makeSeries(id: 'foo')]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 13.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series, equals(seriesList[0])); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + }); + + test('hit test expands to grouped bars', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo'), + makeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(31)); // 2 + 49 - 20 + expect(next.measureDistance, equals(0)); + }); + + test('hit test expands to stacked bars', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.stacked); + final seriesList = [ + makeSeries(id: 'foo'), + makeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 13.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + // For vertical stacked bars, the first series is at the top of the stack. + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('bar')); + expect(closest.datum, equals(seriesList[1].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('foo')); + expect(next.datum, equals(seriesList[0].data[0])); + expect(next.domainDistance, equals(0)); + expect(next.measureDistance, equals(5.0)); + }); + + test('hit test expands to grouped stacked', () { + // Setup + final renderer = makeBarRenderer( + vertical: true, + groupType: BarGroupingType.groupedStacked, + ); + final seriesList = [ + makeSeries(id: 'foo0', seriesCategory: 'c0'), + makeSeries(id: 'bar0', seriesCategory: 'c0'), + makeSeries(id: 'foo1', seriesCategory: 'c1'), + makeSeries(id: 'bar1', seriesCategory: 'c1'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(4)); + + // For vertical stacked bars, the first series is at the top of the stack. + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('bar0')); + expect(closest.datum, equals(seriesList[1].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + + final other1 = details[1]; + expect(other1.domain, equals('camp0')); + expect(other1.series?.id, equals('foo0')); + expect(other1.datum, equals(seriesList[0].data[0])); + expect(other1.domainDistance, equals(0)); + expect(other1.measureDistance, equals(5)); + + final other2 = details[2]; + expect(other2.domain, equals('camp0')); + expect(other2.series?.id, equals('bar1')); + expect(other2.datum, equals(seriesList[3].data[0])); + expect(other2.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other2.measureDistance, equals(0)); + + final other3 = details[3]; + expect(other3.domain, equals('camp0')); + expect(other3.series?.id, equals('foo1')); + expect(other3.datum, equals(seriesList[2].data[0])); + expect(other3.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other3.measureDistance, equals(5)); + }); + + test('hit test works above bar', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.stacked); + final seriesList = [makeSeries(id: 'foo')]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 13.0, 20), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series, equals(seriesList[0])); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(90)); + }); + + test('hit test works between bars in a group', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo'), + makeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 50.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(1)); + expect(closest.measureDistance, equals(0)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(1)); + expect(next.measureDistance, equals(0)); + }); + + test('no selection for bars outside of viewport', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo')..data.add(MyRow('outsideViewport', 20)), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + // Note: point is in the axis, over a bar outside of the viewport. + final details = renderer.getNearestDatumDetailPerSeries( + const Point(65, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(0)); + }); + }); + + ///////////////////////////////////////// + // Horizontal BarRenderer + ///////////////////////////////////////// + group('Horizontal BarRenderer', () { + test('hit test works on bar', () { + // Setup + final renderer = + makeBarRenderer(vertical: false, groupType: BarGroupingType.stacked); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 13.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series, equals(seriesList[0])); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + }); + + test('hit test expands to grouped bars', () { + // Setup + final renderer = + makeBarRenderer(vertical: false, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + makeSeries(id: 'bar', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 20.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(31)); // 2 + 49 - 20 + expect(next.measureDistance, equals(0)); + }); + + test('hit test expands to stacked bars', () { + // Setup + final renderer = + makeBarRenderer(vertical: false, groupType: BarGroupingType.stacked); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + makeSeries(id: 'bar', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 20.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(0)); + expect(next.measureDistance, equals(5.0)); + }); + + test('hit test expands to grouped stacked', () { + // Setup + final renderer = makeBarRenderer( + vertical: false, + groupType: BarGroupingType.groupedStacked, + ); + final seriesList = [ + makeSeries(id: 'foo0', seriesCategory: 'c0', vertical: false), + makeSeries(id: 'bar0', seriesCategory: 'c0', vertical: false), + makeSeries(id: 'foo1', seriesCategory: 'c1', vertical: false), + makeSeries(id: 'bar1', seriesCategory: 'c1', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 20.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(4)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo0')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + + final other1 = details[1]; + expect(other1.domain, equals('camp0')); + expect(other1.series?.id, equals('bar0')); + expect(other1.datum, equals(seriesList[1].data[0])); + expect(other1.domainDistance, equals(0)); + expect(other1.measureDistance, equals(5)); + + final other2 = details[2]; + expect(other2.domain, equals('camp0')); + expect(other2.series?.id, equals('foo1')); + expect(other2.datum, equals(seriesList[2].data[0])); + expect(other2.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other2.measureDistance, equals(0)); + + final other3 = details[3]; + expect(other3.domain, equals('camp0')); + expect(other3.series?.id, equals('bar1')); + expect(other3.datum, equals(seriesList[3].data[0])); + expect(other3.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other3.measureDistance, equals(5)); + }); + + test('hit test works above bar', () { + // Setup + final renderer = + makeBarRenderer(vertical: false, groupType: BarGroupingType.stacked); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 100.0, 20.0 + 10.0 + 20.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series, equals(seriesList[0])); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(90)); + }); + + test('hit test works between bars in a group', () { + // Setup + final renderer = + makeBarRenderer(vertical: false, groupType: BarGroupingType.grouped); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + makeSeries(id: 'bar', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 50.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(1)); + expect(closest.measureDistance, equals(0)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(1)); + expect(next.measureDistance, equals(0)); + }); + }); + + ///////////////////////////////////////// + // Vertical BarTargetRenderer + ///////////////////////////////////////// + group('Vertical BarTargetRenderer', () { + test('hit test works above target', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.stacked, + ); + final seriesList = [makeSeries(id: 'foo')]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 13.0, 20), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series, equals(seriesList[0])); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(90)); + }); + + test('hit test expands to grouped bar targets', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.grouped, + ); + final seriesList = [ + makeSeries(id: 'foo'), + makeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(5)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(31)); // 2 + 49 - 20 + expect(next.measureDistance, equals(5)); + }); + + test('hit test expands to stacked bar targets', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.stacked, + ); + final seriesList = [ + makeSeries(id: 'foo'), + makeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 13.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + // For vertical stacked bars, the first series is at the top of the stack. + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('bar')); + expect(closest.datum, equals(seriesList[1].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(5)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('foo')); + expect(next.datum, equals(seriesList[0].data[0])); + expect(next.domainDistance, equals(0)); + expect(next.measureDistance, equals(15.0)); + }); + + test('hit test expands to grouped stacked', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.groupedStacked, + ); + final seriesList = [ + makeSeries(id: 'foo0', seriesCategory: 'c0'), + makeSeries(id: 'bar0', seriesCategory: 'c0'), + makeSeries(id: 'foo1', seriesCategory: 'c1'), + makeSeries(id: 'bar1', seriesCategory: 'c1'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(4)); + + // For vertical stacked bars, the first series is at the top of the stack. + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('bar0')); + expect(closest.datum, equals(seriesList[1].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(5)); + + final other1 = details[1]; + expect(other1.domain, equals('camp0')); + expect(other1.series?.id, equals('foo0')); + expect(other1.datum, equals(seriesList[0].data[0])); + expect(other1.domainDistance, equals(0)); + expect(other1.measureDistance, equals(15)); + + final other2 = details[2]; + expect(other2.domain, equals('camp0')); + expect(other2.series?.id, equals('bar1')); + expect(other2.datum, equals(seriesList[3].data[0])); + expect(other2.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other2.measureDistance, equals(5)); + + final other3 = details[3]; + expect(other3.domain, equals('camp0')); + expect(other3.series?.id, equals('foo1')); + expect(other3.datum, equals(seriesList[2].data[0])); + expect(other3.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other3.measureDistance, equals(15)); + }); + + test('hit test works between targets in a group', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.grouped, + ); + final seriesList = [ + makeSeries(id: 'foo'), + makeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 50.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(1)); + expect(closest.measureDistance, equals(5)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(1)); + expect(next.measureDistance, equals(5)); + }); + + test('no selection for targets outside of viewport', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.grouped, + ); + final seriesList = [ + makeSeries(id: 'foo')..data.add(MyRow('outsideViewport', 20)), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + // Note: point is in the axis, over a bar outside of the viewport. + final details = renderer.getNearestDatumDetailPerSeries( + const Point(65, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(0)); + }); + }); + + ///////////////////////////////////////// + // Horizontal BarTargetRenderer + ///////////////////////////////////////// + group('Horizontal BarTargetRenderer', () { + test('hit test works above target', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: false, + groupType: BarGroupingType.stacked, + ); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 100.0, 20.0 + 10.0 + 20.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series, equals(seriesList[0])); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(90)); + }); + + test('hit test expands to grouped bar targets', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: false, + groupType: BarGroupingType.grouped, + ); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + makeSeries(id: 'bar', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 20.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(5)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(31)); // 2 + 49 - 20 + expect(next.measureDistance, equals(5)); + }); + + test('hit test expands to stacked bar targets', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: false, + groupType: BarGroupingType.stacked, + ); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + makeSeries(id: 'bar', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 20.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(5)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(0)); + expect(next.measureDistance, equals(15)); + }); + + test('hit test expands to grouped stacked', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: false, + groupType: BarGroupingType.groupedStacked, + ); + final seriesList = [ + makeSeries(id: 'foo0', seriesCategory: 'c0', vertical: false), + makeSeries(id: 'bar0', seriesCategory: 'c0', vertical: false), + makeSeries(id: 'foo1', seriesCategory: 'c1', vertical: false), + makeSeries(id: 'bar1', seriesCategory: 'c1', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 20.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(4)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo0')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(5)); + + final other1 = details[1]; + expect(other1.domain, equals('camp0')); + expect(other1.series?.id, equals('bar0')); + expect(other1.datum, equals(seriesList[1].data[0])); + expect(other1.domainDistance, equals(0)); + expect(other1.measureDistance, equals(15)); + + final other2 = details[2]; + expect(other2.domain, equals('camp0')); + expect(other2.series?.id, equals('foo1')); + expect(other2.datum, equals(seriesList[2].data[0])); + expect(other2.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other2.measureDistance, equals(5)); + + final other3 = details[3]; + expect(other3.domain, equals('camp0')); + expect(other3.series?.id, equals('bar1')); + expect(other3.datum, equals(seriesList[3].data[0])); + expect(other3.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other3.measureDistance, equals(15)); + }); + + test('hit test works between bars in a group', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: false, + groupType: BarGroupingType.grouped, + ); + final seriesList = [ + makeSeries(id: 'foo', vertical: false), + makeSeries(id: 'bar', vertical: false), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 5.0, 20.0 + 10.0 + 50.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals('camp0')); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(1)); + expect(closest.measureDistance, equals(5)); + + final next = details[1]; + expect(next.domain, equals('camp0')); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(1)); + expect(next.measureDistance, equals(5)); + }); + }); + + ///////////////////////////////////////// + // Bar renderer with datetime axis + ///////////////////////////////////////// + group('with date time axis and vertical bar', () { + test('hit test works on bar', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.stacked); + final seriesList = [makeDateTimeSeries(id: 'foo')]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 13.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(1)); + final closest = details[0]; + expect(closest.domain, equals(date0)); + expect(closest.series, equals(seriesList[0])); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + }); + + test('hit test expands to grouped bars', () { + // Setup + final renderer = + makeBarRenderer(vertical: true, groupType: BarGroupingType.grouped); + final seriesList = [ + makeDateTimeSeries(id: 'foo'), + makeDateTimeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals(date0)); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(0)); + + final next = details[1]; + expect(next.domain, equals(date0)); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(31)); // 2 + 49 - 20 + expect(next.measureDistance, equals(0)); + }); + + test('hit test expands to stacked bar targets', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.stacked, + ); + final seriesList = [ + makeDateTimeSeries(id: 'foo'), + makeDateTimeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 13.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + // For vertical stacked bars, the first series is at the top of the stack. + final closest = details[0]; + expect(closest.domain, equals(date0)); + expect(closest.series?.id, equals('bar')); + expect(closest.datum, equals(seriesList[1].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(5)); + + final next = details[1]; + expect(next.domain, equals(date0)); + expect(next.series?.id, equals('foo')); + expect(next.datum, equals(seriesList[0].data[0])); + expect(next.domainDistance, equals(0)); + expect(next.measureDistance, equals(15.0)); + }); + + test('hit test expands to grouped stacked', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.groupedStacked, + ); + final seriesList = [ + makeDateTimeSeries(id: 'foo0', seriesCategory: 'c0'), + makeDateTimeSeries(id: 'bar0', seriesCategory: 'c0'), + makeDateTimeSeries(id: 'foo1', seriesCategory: 'c1'), + makeDateTimeSeries(id: 'bar1', seriesCategory: 'c1'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 20.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(4)); + + // For vertical stacked bars, the first series is at the top of the stack. + final closest = details[0]; + expect(closest.domain, equals(date0)); + expect(closest.series?.id, equals('bar0')); + expect(closest.datum, equals(seriesList[1].data[0])); + expect(closest.domainDistance, equals(0)); + expect(closest.measureDistance, equals(5)); + + final other1 = details[1]; + expect(other1.domain, equals(date0)); + expect(other1.series?.id, equals('foo0')); + expect(other1.datum, equals(seriesList[0].data[0])); + expect(other1.domainDistance, equals(0)); + expect(other1.measureDistance, equals(15)); + + final other2 = details[2]; + expect(other2.domain, equals(date0)); + expect(other2.series?.id, equals('bar1')); + expect(other2.datum, equals(seriesList[3].data[0])); + expect(other2.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other2.measureDistance, equals(5)); + + final other3 = details[3]; + expect(other3.domain, equals(date0)); + expect(other3.series?.id, equals('foo1')); + expect(other3.datum, equals(seriesList[2].data[0])); + expect(other3.domainDistance, equals(31)); // 2 + 49 - 20 + expect(other3.measureDistance, equals(15)); + }); + + test('hit test works between targets in a group', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.grouped, + ); + final seriesList = [ + makeDateTimeSeries(id: 'foo'), + makeDateTimeSeries(id: 'bar'), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + final details = renderer.getNearestDatumDetailPerSeries( + const Point(70.0 + 10.0 + 50.0, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(2)); + + final closest = details[0]; + expect(closest.domain, equals(date0)); + expect(closest.series?.id, equals('foo')); + expect(closest.datum, equals(seriesList[0].data[0])); + expect(closest.domainDistance, equals(1)); + expect(closest.measureDistance, equals(5)); + + final next = details[1]; + expect(next.domain, equals(date0)); + expect(next.series?.id, equals('bar')); + expect(next.datum, equals(seriesList[1].data[0])); + expect(next.domainDistance, equals(1)); + expect(next.measureDistance, equals(5)); + }); + + test('no selection for targets outside of viewport', () { + // Setup + final renderer = makeBarTargetRenderer( + vertical: true, + groupType: BarGroupingType.grouped, + ); + final seriesList = [ + makeDateTimeSeries(id: 'foo') + ..data.add(MyDateTimeRow(dateOutsideViewport, 20)), + ]; + renderer + ..configureSeries(seriesList) + ..preprocessSeries(seriesList) + ..update(seriesList, false) + ..paint(MockCanvas(), 1); + + // Act + // Note: point is in the axis, over a bar outside of the viewport. + final details = renderer.getNearestDatumDetailPerSeries( + const Point(65, 20.0 + 100.0 - 5.0), + selectNearestByDomain, + null, + ); + + // Verify + expect(details.length, equals(0)); + }); + }); +} diff --git a/charts_common/test/mox.dart b/charts_common/test/mox.dart index 9500d1d36..000216f27 100644 --- a/charts_common/test/mox.dart +++ b/charts_common/test/mox.dart @@ -17,5 +17,6 @@ import 'package:nimble_charts_common/common.dart'; MockSpec(as: #MockNumericScale), MockSpec(as: #MockTextStyle), MockSpec(as: #MockChart), + MockSpec(), ]) void main() {} diff --git a/charts_common/test/mox.mocks.dart b/charts_common/test/mox.mocks.dart index 91b8aa11a..7c0cf5f30 100644 --- a/charts_common/test/mox.mocks.dart +++ b/charts_common/test/mox.mocks.dart @@ -3386,3 +3386,426 @@ class MockChart extends _i1.Mock implements _i11.CartesianChart { returnValueForMissingStub: null, ); } + +/// A class which mocks [OrdinalAxis]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockOrdinalAxis extends _i1.Mock implements _i14.OrdinalAxis { + @override + set scale(_i12.MutableScale? _scale) => super.noSuchMethod( + Invocation.setter( + #scale, + _scale, + ), + returnValueForMissingStub: null, + ); + + @override + set tickProvider(_i22.TickProvider? _tickProvider) => + super.noSuchMethod( + Invocation.setter( + #tickProvider, + _tickProvider, + ), + returnValueForMissingStub: null, + ); + + @override + set tickDrawStrategy(_i21.TickDrawStrategy? _tickDrawStrategy) => + super.noSuchMethod( + Invocation.setter( + #tickDrawStrategy, + _tickDrawStrategy, + ), + returnValueForMissingStub: null, + ); + + @override + set axisOrientation(_i14.AxisOrientation? _axisOrientation) => + super.noSuchMethod( + Invocation.setter( + #axisOrientation, + _axisOrientation, + ), + returnValueForMissingStub: null, + ); + + @override + set context(_i7.ChartContext? _context) => super.noSuchMethod( + Invocation.setter( + #context, + _context, + ), + returnValueForMissingStub: null, + ); + + @override + bool get reverseOutputRange => (super.noSuchMethod( + Invocation.getter(#reverseOutputRange), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + set reverseOutputRange(bool? _reverseOutputRange) => super.noSuchMethod( + Invocation.setter( + #reverseOutputRange, + _reverseOutputRange, + ), + returnValueForMissingStub: null, + ); + + @override + bool get autoViewport => (super.noSuchMethod( + Invocation.getter(#autoViewport), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + set autoViewport(bool? _autoViewport) => super.noSuchMethod( + Invocation.setter( + #autoViewport, + _autoViewport, + ), + returnValueForMissingStub: null, + ); + + @override + set forceDrawAxisLine(bool? _forceDrawAxisLine) => super.noSuchMethod( + Invocation.setter( + #forceDrawAxisLine, + _forceDrawAxisLine, + ), + returnValueForMissingStub: null, + ); + + @override + bool get lockAxis => (super.noSuchMethod( + Invocation.getter(#lockAxis), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + set lockAxis(bool? _lockAxis) => super.noSuchMethod( + Invocation.setter( + #lockAxis, + _lockAxis, + ), + returnValueForMissingStub: null, + ); + + @override + int get layoutPaintOrder => (super.noSuchMethod( + Invocation.getter(#layoutPaintOrder), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + set layoutPaintOrder(int? _layoutPaintOrder) => super.noSuchMethod( + Invocation.setter( + #layoutPaintOrder, + _layoutPaintOrder, + ), + returnValueForMissingStub: null, + ); + + @override + bool get hasTickCollision => (super.noSuchMethod( + Invocation.getter(#hasTickCollision), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + set hasTickCollision(bool? _hasTickCollision) => super.noSuchMethod( + Invocation.setter( + #hasTickCollision, + _hasTickCollision, + ), + returnValueForMissingStub: null, + ); + + @override + set graphicsFactory(_i8.GraphicsFactory? _graphicsFactory) => + super.noSuchMethod( + Invocation.setter( + #graphicsFactory, + _graphicsFactory, + ), + returnValueForMissingStub: null, + ); + + @override + set tickFormatter(_i11.TickFormatter? formatter) => + super.noSuchMethod( + Invocation.setter( + #tickFormatter, + formatter, + ), + returnValueForMissingStub: null, + ); + + @override + double get rangeBand => (super.noSuchMethod( + Invocation.getter(#rangeBand), + returnValue: 0.0, + returnValueForMissingStub: 0.0, + ) as double); + + @override + double get stepSize => (super.noSuchMethod( + Invocation.getter(#stepSize), + returnValue: 0.0, + returnValueForMissingStub: 0.0, + ) as double); + + @override + bool get hasValidBarChartRangeBandConfig => (super.noSuchMethod( + Invocation.getter(#hasValidBarChartRangeBandConfig), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + double get viewportScalingFactor => (super.noSuchMethod( + Invocation.getter(#viewportScalingFactor), + returnValue: 0.0, + returnValueForMissingStub: 0.0, + ) as double); + + @override + double get viewportTranslatePx => (super.noSuchMethod( + Invocation.getter(#viewportTranslatePx), + returnValue: 0.0, + returnValueForMissingStub: 0.0, + ) as double); + + @override + _i10.LayoutViewConfig get layoutConfig => (super.noSuchMethod( + Invocation.getter(#layoutConfig), + returnValue: _FakeLayoutViewConfig_9( + this, + Invocation.getter(#layoutConfig), + ), + returnValueForMissingStub: _FakeLayoutViewConfig_9( + this, + Invocation.getter(#layoutConfig), + ), + ) as _i10.LayoutViewConfig); + + @override + bool get isVertical => (super.noSuchMethod( + Invocation.getter(#isVertical), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get isSeriesRenderer => (super.noSuchMethod( + Invocation.getter(#isSeriesRenderer), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + bool get drawAxisLine => (super.noSuchMethod( + Invocation.getter(#drawAxisLine), + returnValue: false, + returnValueForMissingStub: false, + ) as bool); + + @override + void setScaleViewport(_i14.OrdinalViewport? viewport) => super.noSuchMethod( + Invocation.method( + #setScaleViewport, + [viewport], + ), + returnValueForMissingStub: null, + ); + + @override + void layout( + _i13.Rectangle? componentBounds, + _i13.Rectangle? drawAreaBounds, + ) => + super.noSuchMethod( + Invocation.method( + #layout, + [ + componentBounds, + drawAreaBounds, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void setRangeBandConfig(_i12.RangeBandConfig? rangeBandConfig) => + super.noSuchMethod( + Invocation.method( + #setRangeBandConfig, + [rangeBandConfig], + ), + returnValueForMissingStub: null, + ); + + @override + void addDomainValue(String? domain) => super.noSuchMethod( + Invocation.method( + #addDomainValue, + [domain], + ), + returnValueForMissingStub: null, + ); + + @override + void resetDefaultConfiguration() => super.noSuchMethod( + Invocation.method( + #resetDefaultConfiguration, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void resetDomains() => super.noSuchMethod( + Invocation.method( + #resetDomains, + [], + ), + returnValueForMissingStub: null, + ); + + @override + String getDomain(double? location) => (super.noSuchMethod( + Invocation.method( + #getDomain, + [location], + ), + returnValue: _i16.dummyValue( + this, + Invocation.method( + #getDomain, + [location], + ), + ), + returnValueForMissingStub: _i16.dummyValue( + this, + Invocation.method( + #getDomain, + [location], + ), + ), + ) as String); + + @override + int compareDomainValueToViewport(String? domain) => (super.noSuchMethod( + Invocation.method( + #compareDomainValueToViewport, + [domain], + ), + returnValue: 0, + returnValueForMissingStub: 0, + ) as int); + + @override + void setOutputRange( + int? start, + int? end, + ) => + super.noSuchMethod( + Invocation.method( + #setOutputRange, + [ + start, + end, + ], + ), + returnValueForMissingStub: null, + ); + + @override + void updateTicks() => super.noSuchMethod( + Invocation.method( + #updateTicks, + [], + ), + returnValueForMissingStub: null, + ); + + @override + void setViewportSettings( + double? viewportScale, + double? viewportTranslatePx, { + int? drawAreaWidth, + int? drawAreaHeight, + }) => + super.noSuchMethod( + Invocation.method( + #setViewportSettings, + [ + viewportScale, + viewportTranslatePx, + ], + { + #drawAreaWidth: drawAreaWidth, + #drawAreaHeight: drawAreaHeight, + }, + ), + returnValueForMissingStub: null, + ); + + @override + _i10.ViewMeasuredSizes measure( + int? maxWidth, + int? maxHeight, + ) => + (super.noSuchMethod( + Invocation.method( + #measure, + [ + maxWidth, + maxHeight, + ], + ), + returnValue: _FakeViewMeasuredSizes_8( + this, + Invocation.method( + #measure, + [ + maxWidth, + maxHeight, + ], + ), + ), + returnValueForMissingStub: _FakeViewMeasuredSizes_8( + this, + Invocation.method( + #measure, + [ + maxWidth, + maxHeight, + ], + ), + ), + ) as _i10.ViewMeasuredSizes); + + @override + void paint( + _i19.ChartCanvas? canvas, + double? animationPercent, + ) => + super.noSuchMethod( + Invocation.method( + #paint, + [ + canvas, + animationPercent, + ], + ), + returnValueForMissingStub: null, + ); +}