flutter - how do calculate average the data in list? - list

I have a List<Comment> about food from users.
It looks like this:
[
{userId: 1,
rating: 4.5
},
{userId: 2,
rating: 4.0
},
{userId: 3,
rating: 3.5
},
{userId: 4,
rating: 3.0
}
...
];
I want to get the average rating. AVERAGE = Number of ratings : total user, how do I apply this in dart?

var values = [
{'userId': 1, 'rating': 4.5},
{'userId': 2, 'rating': 4.0},
{'userId': 3, 'rating': 3.5},
{'userId': 4, 'rating': 3.0}
];
var result = values.map((m) => m['rating']).reduce((a, b) => a + b) / values.length;
print(result);

In 2021 dart has the built-in average method from the collection package which can be used on an Iterable.
import 'package:collection/collection.dart';
void main() {
var values = [
{'userId': 1, 'rating': 4.5},
{'userId': 2, 'rating': 4.0},
{'userId': 3, 'rating': 3.5},
{'userId': 4, 'rating': 3.0}
];
var result = values.map((m) => m['rating']!).average;
print(result); // prints 3.75
}
You might also be interested in the .sum method from the same package.

I did this by adding the values with the fold function and then dividing by the total. Here is an example:
var values = [
{'userId': 1, 'rating': 4.5},
{'userId': 2, 'rating': 4.0},
{'userId': 3, 'rating': 3.5},
{'userId': 4, 'rating': 3.0}
];
List<double> ratings = values.map((e) => e.price!).toList();
double sum = ratings.fold(0, (p, c) => p + c);
if (sum > 0) {
double average = sum / ratings.length;
}

Related

Dart split / compress Lists

This is the code for my list:
Future<List<Map>> queryDb() async {
List localList;
final db = await database;
final allRows = await db.query(TABLE_FAVORITE);
localList = allRows.toList(growable: true);
localList.removeWhere((item) => item[COLUMN_ISFAVORITE] == 0);
publicFavoriteList = localList;
print(localList);
return localList;
}
whenever it gets called it prints:
[{id: 0, isFavorite: 1}, {id: 1, isFavorite: 1}, {id: 2, isFavorite: 1}, {id: 4, isFavorite: 1}]
How can I "cut" this to
[{0}, {1}, {2}, {4}]
Use map to extract the values from the inner Map objects:
var localValues = localList.map((o) => o['id'] as int).toList();
print(localVales);
// Prints: [0, 1, 2, 4]

Setting colors for google visualization timeline not linked to dataTable rows

I have been having a lot of issues with coloring individual elements of a google visualization timeline object. I have tried ordering my colors[] object different ways, but it seems the current google visualization library processes the colors based on a horizontal-first approach to parsing the dates, but as I never know exactly how the dates will get arranged in the timeline, I cannot predict the color ordering.
I found a decent example of this in a previous post on Stack Overflow 23268616. The JSFiddle referenced on that page doesn't actually work for me (using Chrome 49.0.2623.87) with the current Google Visualization package. I also tried Firefox and get the same incorrect results.
Fiddle replicated here for reference:
function drawChart() {
var container = document.getElementById('example4.2');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Group' });
dataTable.addColumn({ type: 'string', id: 'Category' });
dataTable.addColumn({ type: 'string', id: 'ID' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
[ 'GROUP #1', 'CategoryA', 'C00001', new Date(2014, 0, 1), new Date(2014, 0, 31) ],
[ 'GROUP #1', 'CategoryA', 'C00002', new Date(2014, 1, 1), new Date(2014, 1, 28) ],
[ 'GROUP #1', 'CategoryA', 'C00003', new Date(2014, 3, 1), new Date(2014, 3, 15) ],
[ 'GROUP #1', 'CategoryB', 'C00003', new Date(2014, 0, 21), new Date(2014, 2, 19) ],
[ 'GROUP #1', 'CategoryA', 'C00004', new Date(2014, 0, 1), new Date(2014, 0, 15) ],
[ 'GROUP #2', 'CategoryC', 'C00005', new Date(2014, 2, 8), new Date(2014, 2, 15) ],
[ 'GROUP #3', 'CategoryC', 'C00006', new Date(2014, 5, 1), new Date(2014, 5, 15) ],
[ 'GROUP #4', 'CategoryA', 'C00007', new Date(2014, 1, 15), new Date(2014, 1, 25) ]
]);
var colors = [];
var colorMap = {
// should contain a map of category -> color for every category
CategoryA: '#e63b6f',
CategoryB: '#19c362',
CategoryC: '#592df7'
}
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
colors.push(colorMap[dataTable.getValue(i, 1)]);
}
var rowHeight = 41;
var chartHeight = (dataTable.getNumberOfRows() + 1) * rowHeight;
var options = {
timeline: {
groupByRowLabel: true,
rowLabelStyle: {
fontName: 'Roboto Condensed',
fontSize: 14,
color: '#333333'
},
barLabelStyle: {
fontName: 'Roboto Condensed',
fontSize: 14
}
},
avoidOverlappingGridLines: true,
height: chartHeight,
width: '100%',
colors: colors
};
// use a DataView to hide the category column from the Timeline
var view = new google.visualization.DataView(dataTable);
view.setColumns([0, 2, 3, 4]);
chart.draw(view, options);
}
google.load('visualization', '1', {packages:['timeline'], callback: drawChart});
<script src="http://www.google.com/jsapi?.js"></script>
<div id='example4.2'></div>
For example, in this code, according to the colormap, line C00004 is supposed to be category A, but in my browser it is colored like category B! C0007 is supposed to be category A as well, but is category C In color! I cannot even figure out the pattern which is coloring the objects the way it is. Re-arranging the addRows([]) list leads to more crazy results... is this feature of Google Visualization just plain broken?
I have also tried referencing the library via https://www.gstatic.com/charts.loader.js but get the same results.

Show/hide lines in Google Chart and show grayed text in legend

Trying to do a chart to show/hide the lines on click (I think the original code is from #asgallant), but it only works after the first interaction.
PS.: Is it possible to gray out the text in the legend too?
FIDDLE
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable
([
['Time', 'One', 'Two', 'Three', 'Four', 'Five'],
['05/2013', 0, 3, 0, 0, 8],
['06/2013', 0, 3, 1, 0, 7],
['07/2013', 0, 3, 1, 0, 7],
['08/2013', 0, 3, 1, 0, 7],
['09/2013', 0, 3, 1, 0, 7],
['10/2013', 0, 3, 1, 0, 7],
['11/2013', 0, 3, 1, 0, 7],
['12/2013', 0, 3, 1, 0, 7],
['01/2014', 0, 3, 1, 0, 7],
['02/2014', 0, 3, 1, 0, 7],
['03/2014', 0, 3, 1, 0, 7],
['04/2014', 0, 2, 1, 0, 7],
['05/2014', 0, 2, 1, 0, 7]
]);
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
var columns = [];
var series = {};
for (var i = 0; i < data.getNumberOfColumns(); i++) {
columns.push(i);
if (i > 0) {
series[i - 1] = {};
}
}
var options = {
chartArea: {width: '80%', height: '70%'},
fontSize: ['13'],
lineWidth: 3,
pointSize: 10,
series: series
};
google.visualization.events.addListener(chart, 'select', function () {
var sel = chart.getSelection();
// if selection length is 0, we deselected an element
if (sel.length > 0) {
// if row is undefined, we clicked on the legend
if (sel[0].row === null) {
var col = sel[0].column;
if (columns[col] == col) {
// hide the data series
columns[col] = {
label: data.getColumnLabel(col),
type: data.getColumnType(col),
calc: function () {
return null;
}
};
// grey out the legend entry
series[col - 1].color = '#CCCCCC';
}
else {
// show the data series
columns[col] = col;
series[col - 1].color = null;
}
var view = new google.visualization.DataView(data);
view.setColumns(columns);
chart.draw(view, options);
}
}
});
}

Column Chart in Google Charts is displaying bars 10 times proper height

I can't figure out why, I've triple checked that I'm passing in the right values. When I hover over any of the bars it displays the right data, but every single one of them displays at 10x scale on the graph and I can't figure out why. Here's my code if it helps:
var dashboard2 = new google.visualization.Dashboard(
document.getElementById('dashboard'));
var control2 = new google.visualization.ControlWrapper({
'controlType': 'ChartRangeFilter',
'containerId': 'control2',
'options': {
// Filter by the date axis.
'filterColumnIndex': 0,
'ui': {
'chartType': 'LineChart',
'chartOptions': {
'chartArea': {'width': '80%'},
'hAxis': {'baselineColor': 'none'}
},
// Display a single series that shows the closing value of the stock.
// Thus, this view has two columns: the date (axis) and the stock value (line series).
'chartView': {
'columns': [0, 1, 14]
},
// 1 day in milliseconds = 24 * 60 * 60 * 1000 = 86,400,000
'minRangeSize': 259200000
}
},
// Initial range: 2012-02-09 to 2012-03-20.
'state': {'range': {'start': new Date(2012, 11, 7), 'end': new Date()}}
});
var chart2 = new google.visualization.ChartWrapper({
'chartType': 'ComboChart',
'containerId': 'chart2',
'options': {
// Use the same chart area width as the control for axis alignment.
'chartArea': {'height': '80%', 'width': '80%'},
'hAxis': {'slantedText': false},
'vAxis': {'viewWindow': {'min': 0, 'max': 400}},
'title': 'Sales Made by Affiliate Name',
'seriesType': "bars",
'series': {0: {type: "line"}, 13: {type: "line"}},
'isStacked': true
},
// Convert the first column from 'date' to 'string'.
'view': {
'columns': [
{
'calc': function(dataTable, rowIndex) {
return dataTable.getFormattedValue(rowIndex, 0);
},
'type': 'string'
}, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
}
});
var jsonData2 = $.ajax({
url: "getData.php",
dataType:"json",
async: false
}).responseText;
// Create our data table out of JSON data loaded from server
var data2 = new google.visualization.DataTable(jsonData2);
dashboard2.bind(control2, chart2);
dashboard2.draw(data2);
Edit: Here's a small bit of the data at the very beginning, because I don't want to give out our data, but I suppose it might be necessary to get an idea for what is being passed in. I cut out the starting bracket for readability:
"cols":[ {"id":"","label":"Date","pattern":"","type":"date"}, {"id":"","label":"Total","pattern":"","type":"number"}, {"id":"","label":"andersce99","pattern":"","type":"number"}, {"id":"","label":"sojourn","pattern":"","type":"number"}, {"id":"","label":"warriorplus","pattern":"","type":"number"}, {"id":"","label":"potpie queen","pattern":"","type":"number"}, {"id":"","label":"60minuteaffiliate","pattern":"","type":"number"}, {"id":"","label":"bob voges","pattern":"","type":"number"}, {"id":"","label":"Grayth","pattern":"","type":"number"}, {"id":"","label":"TiffanyDow","pattern":"","type":"number"}, {"id":"","label":"AmandaT","pattern":"","type":"number"}, {"id":"","label":"Gaz Cooper","pattern":"","type":"number"}, {"id":"","label":"Sam England","pattern":"","type":"number"}, {"id":"","label":"Matthew Olson","pattern":"","type":"number"}, {"id":"","label":"Average Per Day Over Time","pattern":"","type":"number"} ],
"rows": [ {"c":[{"v":"Date(2012,11,7)","f":null},{"v":"387","f":null},{"v":"19","f":null},{"v":"275","f":null},{"v":"8","f":null},{"v":"0","f":null},{"v":"35","f":null},{"v":"3","f":null},{"v":"21","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"11","f":null},{"v":"6","f":null},{"v":"387","f":null}]},
{"c":[{"v":"Date(2012,11,8)","f":null},{"v":"98","f":null},{"v":"11","f":null},{"v":"39","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"15","f":null},{"v":"0","f":null},{"v":"7","f":null},{"v":"9","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"3","f":null},{"v":"6","f":null},{"v":"242.5","f":null}]},
{"c":[{"v":"Date(2012,11,9)","f":null},{"v":"58","f":null},{"v":"7","f":null},{"v":"16","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"4","f":null},{"v":"0","f":null},{"v":"3","f":null},{"v":"10","f":null},{"v":"2","f":null},{"v":"9","f":null},{"v":"0","f":null},{"v":"2","f":null},{"v":"181","f":null}]},
{"c":[{"v":"Date(2012,11,10)","f":null},{"v":"196","f":null},{"v":"5","f":null},{"v":"8","f":null},{"v":"126","f":null},{"v":"0","f":null},{"v":"2","f":null},{"v":"35","f":null},{"v":"0","f":null},{"v":"7","f":null},{"v":"4","f":null},{"v":"3","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"184.75","f":null}]},
{"c":[{"v":"Date(2012,11,11)","f":null},{"v":"76","f":null},{"v":"7","f":null},{"v":"5","f":null},{"v":"17","f":null},{"v":"30","f":null},{"v":"7","f":null},{"v":"1","f":null},{"v":"1","f":null},{"v":"2","f":null},{"v":"1","f":null},{"v":"4","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"163","f":null}]},
{"c":[{"v":"Date(2012,11,12)","f":null},{"v":"48","f":null},{"v":"4","f":null},{"v":"5","f":null},{"v":"9","f":null},{"v":"20","f":null},{"v":"7","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"143.833333333","f":null}]},
{"c":[{"v":"Date(2012,11,13)","f":null},{"v":"21","f":null},{"v":"3","f":null},{"v":"2","f":null},{"v":"5","f":null},{"v":"4","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"2","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"126.285714286","f":null}]},
{"c":[{"v":"Date(2012,11,14)","f":null},{"v":"12","f":null},{"v":"1","f":null},{"v":"1","f":null},{"v":"2","f":null},{"v":"4","f":null},{"v":"2","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"112","f":null}]},
{"c":[{"v":"Date(2012,11,15)","f":null},{"v":"8","f":null},{"v":"3","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"2","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"1","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"0","f":null},{"v":"100.444444444","f":null}]}
Your data is formatted incorrectly: numbers need to be stored as numbers in the JSON, not as strings. As an example, this:
{"v":"387","f":null}
should be like this:
{"v":387,"f":null}
If you are using PHP's json_encode function to build the JSON, you can add JSON_NUMERIC_CHECK as an argument to the function call to output the numbers properly:
json_encode($myData, JSON_NUMERIC_CHECK);

What's an efficient way to filter this array?

My data structure is
companies = [
{name: 'A', ramps: [1, 2]},
{name: 'B', ramps: [3, 4, 5]}
...
]
ramps = [
{id: 1, division: 'accounting', amount: 500},
{id: 2, division: 'sale', amount: 200},
...
]
My goal is to end up with the following data:
groupedByDivision = [
{division: accounting, total: 12000},
{division: sales, total: 6500},
..
]
My first brute-force approach is something like this (note: I've extended Ember.Array with this flatten method:
var ramps = this.get('controller.companies') // this is the array of companies
.get('model')
.mapProperty('ramps')
.flatten();
var temp = {}, data = [];
$.each(ramps, function(index, ramp) {
if ( !(ramp.billingDiv in tempCompanies) ) {
temp[ramp.billingDiv] = ramp.feeChange;
} else {
temp[ramp.billingDiv] += ramp.feeChange;
}
});
$.each(temp, function(division, amount) {
data.push({
'category': division,
'count': amount
});
});
return data;
Any other suggestions? I'm not too familiar with the Ember.Array methods yet, so I'm not aware of all their use cases.