lbry-sdk/dart/packages/ver/lib/time_series_chart.dart
2019-07-16 00:57:53 -04:00

226 lines
8.8 KiB
Dart

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:charts_flutter/src/base_chart_state.dart' as state;
import 'package:charts_common/common.dart' as common;
import 'package:lbry/lbry.dart';
class SimpleTimeSeriesChart extends StatefulWidget {
SimpleTimeSeriesChart({Key key}) : super(key: key);
@override
_SimpleTimeSeriesChartState createState() => _SimpleTimeSeriesChartState();
}
class _SimpleTimeSeriesChartState extends State<SimpleTimeSeriesChart> {
final List<MetricDataPoint> metricData = [];
final List<LoadDataPoint> loadData = [];
final List<charts.Series<LoadDataPoint, DateTime>> loadSeries = [];
final List<charts.Series<LoadDataPoint, DateTime>> timeSeries = [];
final List<charts.Series<MetricDataPoint, DateTime>> metricSeries = [];
final List<charts.Series<MetricDataPoint, DateTime>> metricTimeSeries = [];
final Random rand = Random();
LoadGenerator loadGenerator;
Client client;
@override
void initState() {
super.initState();
metricSeries.add(
charts.Series<MetricDataPoint, DateTime>(
id: 'Searches Started',
colorFn: (_, __) => charts.MaterialPalette.deepOrange.shadeDefault.lighter,
domainFn: (MetricDataPoint load, _) => load.time,
measureFn: (MetricDataPoint load, _) => load.search.started,
data: metricData,
)
);
metricSeries.add(
charts.Series<MetricDataPoint, DateTime>(
id: 'Searches Finished',
colorFn: (_, __) => charts.MaterialPalette.deepOrange.shadeDefault.darker,
domainFn: (MetricDataPoint load, _) => load.time,
measureFn: (MetricDataPoint load, _) => load.search.finished,
data: metricData,
)
);
metricSeries.add(
charts.Series<MetricDataPoint, DateTime>(
id: 'Resolves Started',
colorFn: (_, __) => charts.MaterialPalette.teal.shadeDefault.lighter,
domainFn: (MetricDataPoint load, _) => load.time,
measureFn: (MetricDataPoint load, _) => load.resolve.started,
data: metricData,
)
);
metricSeries.add(
charts.Series<MetricDataPoint, DateTime>(
id: 'Resolves Finished',
colorFn: (_, __) => charts.MaterialPalette.teal.shadeDefault.darker,
domainFn: (MetricDataPoint load, _) => load.time,
measureFn: (MetricDataPoint load, _) => load.resolve.finished,
data: metricData,
)
);
metricTimeSeries.add(
charts.Series<MetricDataPoint, DateTime>(
id: 'Avg. Waiting',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault.darker,
domainFn: (MetricDataPoint load, _) => load.time,
measureFn: (MetricDataPoint load, _) => load.search.avg_wait_time,
data: metricData,
)
);
metricTimeSeries.add(
charts.Series<MetricDataPoint, DateTime>(
id: 'Avg. Executing',
colorFn: (_, __) => charts.MaterialPalette.teal.shadeDefault.lighter,
domainFn: (MetricDataPoint load, _) => load.time,
measureFn: (MetricDataPoint load, _) => load.search.avg_execution_time,
data: metricData,
)
);
metricTimeSeries.add(
charts.Series<MetricDataPoint, DateTime>(
id: 'Avg. SQLite',
colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault.darker,
domainFn: (MetricDataPoint load, _) => load.time,
measureFn: (MetricDataPoint load, _) => load.search.avg_query_time_per_search,
data: metricData,
)
);
loadSeries.add(
charts.Series<LoadDataPoint, DateTime>(
id: 'Load',
colorFn: (_, __) => charts.MaterialPalette.black.darker,
domainFn: (LoadDataPoint load, _) => load.time,
measureFn: (LoadDataPoint load, _) => load.load,
data: loadData,
)
);
loadSeries.add(
charts.Series<LoadDataPoint, DateTime>(
id: 'Success',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LoadDataPoint load, _) => load.time,
measureFn: (LoadDataPoint load, _) => load.success,
data: loadData,
)
);
loadSeries.add(
charts.Series<LoadDataPoint, DateTime>(
id: 'Backlog',
colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
domainFn: (LoadDataPoint load, _) => load.time,
measureFn: (LoadDataPoint load, _) => load.backlog,
data: loadData,
)
);
loadSeries.add(
charts.Series<LoadDataPoint, DateTime>(
id: 'Catch-up',
colorFn: (_, __) => charts.MaterialPalette.yellow.shadeDefault,
domainFn: (LoadDataPoint load, _) => load.time,
measureFn: (LoadDataPoint load, _) => load.catchup,
data: loadData,
)
);
timeSeries.add(
charts.Series<LoadDataPoint, DateTime>(
id: 'Avg. Success Time',
colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
domainFn: (LoadDataPoint load, _) => load.time,
measureFn: (LoadDataPoint load, _) => load.avg_success,
data: loadData,
)
);
timeSeries.add(
charts.Series<LoadDataPoint, DateTime>(
id: 'Avg. Catch-up Time',
colorFn: (_, __) => charts.MaterialPalette.yellow.shadeDefault,
domainFn: (LoadDataPoint load, _) => load.time,
measureFn: (LoadDataPoint load, _) => load.avg_catchup,
data: loadData,
)
);
var increase = 1;
loadData.add(LoadDataPoint());
loadGenerator = LoadGenerator('localhost', 50001, {
'id': 1,
'method': 'blockchain.claimtrie.search',
'params': {
'no_totals': true,
'offset': 0,
'limit': 20,
'fee_amount': '<1',
//'all_tags': ['funny'],
'any_tags': [
'crypto',
'outdoors',
'cars',
'automotive'
]
}
}, (t, stats) {
setState(() {
//if (loadData.length > 60) loadData.removeAt(0);
loadData.add(stats);
});
increase = max(1, min(100, increase+2)-stats.backlog);
//increase += 1;
//t.query['params']['offset'] = (increase/2).ceil()*t.query['params']['limit'];
t.load = increase;//rand.nextInt(10)+5;
return true;
})..start();
metricData.add(MetricDataPoint.empty());
client = Client('ws://localhost:8181/')..open()..metrics.listen((m) {
setState(() {
metricData.add(m);
});
});
}
@override
void dispose() {
if (client != null) client.close();
if (loadGenerator != null) loadGenerator.stop();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(children: <Widget>[
SizedBox(height: 220.0, child: BetterTimeSeriesChart(loadSeries)),
SizedBox(height: 220.0, child: BetterTimeSeriesChart(timeSeries)),
SizedBox(height: 220.0, child: BetterTimeSeriesChart(metricSeries)),
SizedBox(height: 220.0, child: BetterTimeSeriesChart(metricTimeSeries)),
]);
}
}
class BetterTimeSeriesChart extends charts.TimeSeriesChart {
final int itemCount;
final Object lastItem;
BetterTimeSeriesChart(
List<charts.Series<dynamic, DateTime>> seriesList):
itemCount = seriesList[0].data.length,
lastItem = seriesList[0].data.last,
super(seriesList, behaviors: [charts.SeriesLegend()]);
@override
void updateCommonChart(common.BaseChart baseChart, charts.BaseChart oldWidget,
state.BaseChartState chartState) {
super.updateCommonChart(baseChart, oldWidget, chartState);
final prev = oldWidget as BetterTimeSeriesChart;
if (itemCount != prev?.itemCount || lastItem != prev?.lastItem) {
chartState.markChartDirty();
}
}
}