This requires some genius, experience & knowledge I don't yet have in Dart, so I'm looking for help.
I am trying to populate a line chart, when users first begin using software there will be "empty" entries in the chart data. There also may be "zero" entries or no entry at all for some weeks or entries. I want to ensure that my line chart shows zero (for sales income - yAxis) for any missing entries based on a graph with 13 entries shown always.
For example mockupGraphData would be an existing situation where a couple sales dates are missing entries (based on weekly entries) and there are not enough entries to satisfy the graph appetite.
I would like to automatically enter "zeroed" dates. Where the date would be the index of missing date and GraphData.yAxis (income) would be zero.
Below does not compile of course, consider the last loop pseudo code of what I think would work if I could get around the index not existing in the mockupGraphData...
void main() {
// Actual "mock" input data
List<GraphData> mockupGraphData = [
GraphData(1586761200000, 145333),
GraphData(1587366000000, 433343),
GraphData(1587970800000, 223432),
GraphData(1589180400000, 122221),
GraphData(1589785200000, 982347),
GraphData(1590994800000, 234322),
];
// Required graph dates as per below calculations (13 entries):
// 1583737200000
// 1584342000000
// 1584946800000
// 1585551600000
// 1586156400000
// 1586761200000
// 1587366000000
// 1587970800000
// 1588575600000
// 1589180400000
// 1589785200000
// 1590390000000
// 1590994800000
int entries = 13;
int latestDateReported = DateTime(2020, 6, 1).millisecondsSinceEpoch;
int oneWeek = Duration(days: 7).inMilliseconds;
int earliestEntryDate = latestDateReported - (oneWeek * entries);
List<int> graphRequiredDates = [];
List<GraphData> finalData = [];
for (int i = 0; i < entries; i ) {
earliestEntryDate = oneWeek;
graphRequiredDates.add(earliestEntryDate);
}
// What I would like to do
for (int i = 0; i < entries; i ) {
if (!mockupGraphData.contains(GraphData(graphRequiredDates[i]))) {
finalData.add(GraphData(graphRequiredDates[i], 0));
}
}
print(finalData);
}
class GraphData {
int xAxis; // Sale date
int yAxis; // Sale income
GraphData(this.xAxis, this.yAxis);
@override
String toString() {
return '$xAxis $yAxis';
}
}
// IDEAL OUTPUT:
List<GraphData> mockupGraphData = [
GraphData(1583737200000, 0),
GraphData(1584342000000, 0),
GraphData(1584946800000, 0),
GraphData(1585551600000, 0),
GraphData(1586156400000, 0),
GraphData(1586761200000, 145333),
GraphData(1587366000000, 433343),
GraphData(1587970800000, 223432),
GraphData(1588575600000, 0),
GraphData(1589180400000, 122221),
GraphData(1589785200000, 982347),
GraphData(1590390000000, 0),
GraphData(1590994800000, 234322),
];
CodePudding user response:
Instead of storing mockupGraphData
as a List<GraphData>
, I would use a Map<int, int>
that maps timestamps to values. From there, it's easy to iterate over your list of expected timestamps, check if a timestamp already exists in mockupGraphData
, and then construct GraphData
objects appropriately.
You additionally can use collection-for
to make some of your code neater:
void main() {
// Actual "mock" input data
var mockupGraphData = <int, int>{
1586761200000: 145333,
1587366000000: 433343,
1587970800000: 223432,
1589180400000: 122221,
1589785200000: 982347,
1590994800000: 234322,
};
int entries = 13;
int latestDateReported = DateTime(2020, 6, 1).millisecondsSinceEpoch;
int oneWeek = Duration(days: 7).inMilliseconds;
int earliestEntryDate = latestDateReported - (oneWeek * (entries - 1));
List<int> graphRequiredDates = [
for (var i = 0; i < entries; i )
earliestEntryDate i * oneWeek,
];
List<GraphData> finalData = [
for (var requiredDate in graphRequiredDates)
GraphData(requiredDate, mockupGraphData[requiredDate] ?? 0),
];
finalData.forEach(print);
}
class GraphData {
int xAxis; // Sale date
int yAxis; // Sale income
GraphData(this.xAxis, this.yAxis);
@override
String toString() {
return 'GraphData($xAxis, $yAxis)';
}
}
CodePudding user response:
You could try something like this:
void main() {
List<GraphData> mockupGraphData = [
GraphData(1586761200000, 145333),
GraphData(1587366000000, 433343),
GraphData(1587970800000, 223432),
GraphData(1589180400000, 122221),
GraphData(1589785200000, 982347),
GraphData(1590994800000, 234322),
];
int entries = 13;
int latestDateReported = DateTime(2020, 6, 1).millisecondsSinceEpoch;
int oneWeek = Duration(days: 7).inMilliseconds;
int earliestEntryDate = 1583737200000;
final result = [
for (int i = 0, v = 0; i < entries; i , earliestEntryDate = oneWeek)
if (mockupGraphData[v].xAxis == earliestEntryDate)
mockupGraphData[v ]
else
GraphData(earliestEntryDate, 0),
];
result.forEach(print);
}
class GraphData {
int xAxis; // Sale date
int yAxis; // Sale income
GraphData(this.xAxis, this.yAxis);
@override
String toString() {
return '$xAxis $yAxis';
}
}
I hardcoded the value of earliestEntryDate
since the calculation didn't seem to match with the expected output. The above solution assumes mockupGraphData
is in sorted order, and that the values are at least a week apart.