Skip to content

Commit

Permalink
Refactor chart data. (flutter#7609)
Browse files Browse the repository at this point in the history
1. Remove live vs offline data from chart memory timeline.
2. Factor out chart data to separate class.

No functional changes.
  • Loading branch information
polina-c committed Apr 17, 2024
1 parent 3278c87 commit b7a3d73
Show file tree
Hide file tree
Showing 10 changed files with 159 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,13 +125,13 @@ class MemoryController extends DisposableController
diff = diffPaneController ??
offlineData?.diff ??
DiffPaneController(
loader: HeapGraphLoaderRuntime(chart.memoryTimeline),
loader: HeapGraphLoaderRuntime(chart.data.timeline),
);
profile = profilePaneController ??
offlineData?.profile ??
ProfilePaneController();
control = MemoryControlPaneController(
chart.memoryTimeline,
chart.data.timeline,
isChartVisible: chart.isChartVisible,
exportData: exportData,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ flowchart TD;
chart_connection.dart-->memory_tracker.dart;
chart_pane_controller.dart-->android_chart_controller.dart;
chart_pane_controller.dart-->chart_connection.dart;
chart_pane_controller.dart-->chart_data.dart;
chart_pane_controller.dart-->event_chart_controller.dart;
chart_pane_controller.dart-->vm_chart_controller.dart;
```
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Copyright 2024 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';

import '../../../../../shared/primitives/simple_items.dart';
import '../../../shared/primitives/memory_timeline.dart';
import '../data/primitives.dart';

/// Chart data, that should be saved when transferred to offline data mode.
class ChartData {
ChartData({required this.isDeviceAndroid});

/// Wether device is android, if [mode] is not [DevToolsMode.connected].
///
/// If [mode] is [DevToolsMode.connected], this value is null
/// and chart visibility should be detected based on connected app.
final bool? isDeviceAndroid;

final MemoryTimeline timeline = MemoryTimeline();

/// Default is to display default tick width based on width of chart of the collected
/// data in the chart.
ChartInterval get displayInterval => _displayInterval.value;
final _displayInterval =
ValueNotifier<ChartInterval>(ChartInterval.theDefault);
set displayInterval(ChartInterval interval) {
_displayInterval.value = interval;
}

ValueListenable<bool> get isLegendVisible => _legendVisibleNotifier;
final _legendVisibleNotifier = ValueNotifier<bool>(true);
bool toggleLegendVisibility() =>
_legendVisibleNotifier.value = !_legendVisibleNotifier.value;

void dispose() {
_displayInterval.dispose();
_legendVisibleNotifier.dispose();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,20 @@ import 'package:flutter/foundation.dart';

import '../../../../../shared/globals.dart';
import '../../../../../shared/primitives/simple_items.dart';
import '../../../shared/primitives/memory_timeline.dart';
import '../data/primitives.dart';
import 'android_chart_controller.dart';
import 'chart_connection.dart';
import 'chart_data.dart';
import 'event_chart_controller.dart';
import 'vm_chart_controller.dart';

class MemoryChartPaneController extends DisposableController
with AutoDisposeControllerMixin {
MemoryChartPaneController(this.mode, {this.isDeviceAndroid})
MemoryChartPaneController(this.mode, {bool? isDeviceAndroid})
: assert(
mode == DevToolsMode.connected || isDeviceAndroid != null,
'If application is not connected, isDeviceAndroid must be provided.',
) {
),
data = ChartData(isDeviceAndroid: isDeviceAndroid) {
unawaited(_init());
}

Expand All @@ -34,13 +34,22 @@ class MemoryChartPaneController extends DisposableController
);
}

Map<String, dynamic> toJson() {
// TODO(polina-c): implement, https://github.com/flutter/devtools/issues/6972
return {};
}

DevToolsMode mode;

/// Wether device is android, if [mode] is not [DevToolsMode.connected].
///
/// If [mode] is [DevToolsMode.connected], this value should be detected
/// by [_chartConnection].
final bool? isDeviceAndroid;
final ChartData data;

late final ChartConnection? _chartConnection =
(mode == DevToolsMode.connected)
? ChartConnection(
data.timeline,
isAndroidChartVisible: isAndroidChartVisible,
)
: null;

Future<void> _init() async {
_updateAndroidChartVisibility();
Expand All @@ -53,36 +62,16 @@ class MemoryChartPaneController extends DisposableController
);
}

Map<String, dynamic> toJson() {
// TODO(polina-c): implement, https://github.com/flutter/devtools/issues/6972
return {};
}

late final ChartConnection? _chartConnection =
(mode == DevToolsMode.connected)
? ChartConnection(
memoryTimeline,
isAndroidChartVisible: isAndroidChartVisible,
)
: null;

final MemoryTimeline memoryTimeline = MemoryTimeline();

late final EventChartController event =
EventChartController(memoryTimeline, paused: paused);
EventChartController(data.timeline, paused: paused);
late final VMChartController vm =
VMChartController(memoryTimeline, paused: paused);
VMChartController(data.timeline, paused: paused);
late final AndroidChartController android = AndroidChartController(
memoryTimeline,
data.timeline,
sharedLabels: vm.labelTimestamps,
paused: paused,
);

ValueListenable<bool> get isLegendVisible => _legendVisibleNotifier;
final _legendVisibleNotifier = ValueNotifier<bool>(true);
bool toggleLegendVisibility() =>
_legendVisibleNotifier.value = !_legendVisibleNotifier.value;

ValueNotifier<bool> isChartVisible = preferences.memory.showChart;

void resetAll() {
Expand All @@ -103,17 +92,6 @@ class MemoryChartPaneController extends DisposableController
android.dirty = true;
}

/// Default is to display default tick width based on width of chart of the collected
/// data in the chart.
final _displayInterval =
ValueNotifier<ChartInterval>(ChartInterval.theDefault);

set displayInterval(ChartInterval interval) {
_displayInterval.value = interval;
}

ChartInterval get displayInterval => _displayInterval.value;

ValueListenable<bool> get paused => _paused;
final _paused = ValueNotifier<bool>(true);
void pause() => _paused.value = true;
Expand All @@ -127,16 +105,15 @@ class MemoryChartPaneController extends DisposableController
final isAndroidChartVisible = ValueNotifier<bool>(false);

void _updateAndroidChartVisibility() {
final isAndroid = isDeviceAndroid ?? _chartConnection!.isDeviceAndroid;
final isAndroid = data.isDeviceAndroid ?? _chartConnection!.isDeviceAndroid;
isAndroidChartVisible.value =
isAndroid && preferences.memory.androidCollectionEnabled.value;
}

@override
void dispose() {
super.dispose();
_legendVisibleNotifier.dispose();
_displayInterval.dispose();
data.dispose();
event.dispose();
vm.dispose();
android.dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class _ChartControlPaneState extends State<ChartControlPane>
void _clearTimeline() {
ga.select(gac.memory, gac.clear);

widget.chart.memoryTimeline.reset();
widget.chart.data.timeline.reset();

// Remove history of all plotted data in all charts.
widget.chart.resetAll();
Expand Down Expand Up @@ -105,9 +105,9 @@ class _LegendButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return ValueListenableBuilder<bool>(
valueListenable: chartController.isLegendVisible,
valueListenable: chartController.data.isLegendVisible,
builder: (_, legendVisible, __) => GaDevToolsButton(
onPressed: chartController.toggleLegendVisibility,
onPressed: chartController.data.toggleLegendVisibility,
gaScreen: gac.memory,
gaSelection: legendVisible
? gac.MemoryEvent.hideChartLegend
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class _MemoryChartPaneState extends State<MemoryChartPane>
}

final allValues = ChartsValues(
widget.chart.memoryTimeline,
widget.chart.data.timeline,
isAndroidChartVisible: widget.chart.isAndroidChartVisible,
index: value.index,
timestamp: value.timestamp ?? _timestamp,
Expand Down Expand Up @@ -176,7 +176,7 @@ class _MemoryChartPaneState extends State<MemoryChartPane>
height: defaultChartHeight,
child: MemoryAndroidChart(
widget.chart.android,
widget.chart.memoryTimeline,
widget.chart.data.timeline,
),
),
],
Expand All @@ -185,7 +185,7 @@ class _MemoryChartPaneState extends State<MemoryChartPane>
// The legend.
MultiValueListenableBuilder(
listenables: [
widget.chart.isLegendVisible,
widget.chart.data.isLegendVisible,
widget.chart.isAndroidChartVisible,
],
builder: (_, values, __) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,15 @@ class _IntervalDropdownState extends State<IntervalDropdown> {

return RoundedDropDownButton<ChartInterval>(
isDense: true,
value: widget.chartController.displayInterval,
value: widget.chartController.data.displayInterval,
onChanged: (ChartInterval? newValue) {
final value = newValue!;
setState(() {
ga.select(
gac.memory,
'${gac.MemoryEvent.chartInterval}-${value.displayName}',
);
widget.chartController.displayInterval = value;
widget.chartController.data.displayInterval = value;
final duration = value.duration;

widget.chartController.event.zoomDuration = duration;
Expand Down
Loading

0 comments on commit b7a3d73

Please sign in to comment.