Hello I have this simple example with 2 data series and 2 trendiness.
http://jsfiddle.net/ttwqazav/
I want to have only 1 trendline for both of them, as an average! Is that possible?
google.load('visualization', '1.1', {packages: ['corechart']});
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['X', 'Y', 'Z'],
[0, 0, 2],
[1, 2, 4],
[2, 4, 5],
[3, 6, 8],
[4, 8, 10],
[5, 10, 12],
[6, 12, 14],
[7, 14, 16],
[8, 16, 18],
[9, 18, 20],
[10, 20, 22]
]);
var options = {
height: 500,
legend: 'none',
colors: ['#9575cd', '#33ac71'],
pointShape: 'diamond',
trendlines: {
0: {
color:'red',
type: 'linear',
pointsVisible: false
}
}
};
var chart = new google.visualization.ScatterChart(document.getElementById('chart'));
chart.draw(data, options);
}
google.load("visualization", "1", {packages:["corechart"]});
google.setOnLoadCallback(drawChart);
Just specify data points as below:
var data = google.visualization.arrayToDataTable([
['X', 'Y'],
[0, 0],
[1, 2],
[2, 4],
[3, 6],
[4, 8],
[5, 10],
[6, 12],
[7, 14],
[8, 16],
[9, 18],
[10, 20],
[0, 2],
[1, 4],
[2, 5],
[3, 8],
[4, 10],
[5, 12],
[6, 14],
[7, 16],
[8, 18],
[9, 20],
[10, 22]
]);
But you cannot differentiate between the two sets of data points!
If your aim is to get average best fit line, it'll work. :)
Related
Basically, I have a list of scores and their corresponding index. I want to sort "scores" by a value within that list.
scores = [[0, 340], [1, 69], [2, 485], [3, 194], [4, 91], [5, 130], [6, 110], [7, 655], [8, 45], [9, 445], [10, 34], [11, 385]]
I want to sort the list by the second value within that list. The end result should be something like:
scores = [[10,34], [8,45], [1,69].....]
scores.sort(); gives an error saying List is non-comparable
Thanks, Mason
void main() {
var scores = [[0, 340], [1, 69], [2, 485], [3, 194], [4, 91], [5, 130], [6, 110], [7, 655], [8, 45], [9, 445], [10, 34], [11, 385]];
print(scores);
scores.sort((a,b) => a[1].compareTo(b[1]));
print(scores);
}
Result:
[[10, 34], [8, 45], [1, 69], [4, 91], [6, 110], [5, 130], [3, 194], [0, 340], [11, 385], [9, 445], [2, 485], [7, 655]]
given this example array of triplets, real arrays would be very large data sets, hence the "need for speed":
let usedIndicies2 = [
[0, 1, 2]
[2, 1, 3],
[1, 4, 3],
[3, 4, 5],
[6, 7, 8],
[8, 7, 9],
[7, 10, 9],
[9, 10, 11],
[12, 2, 13],
[13, 2, 14],
[2, 3, 14],
[14, 3, 15],
[3, 5, 15],
[15, 5, 16],
[5, 17, 16],
[16, 17, 18],
[19, 8, 20],
[20, 8, 21],
[8, 9, 21],
[21, 9, 22],
[9, 11, 22],
[22, 11, 23],
[11, 24, 23],
[23, 24, 25],
[13, 14, 26],
[26, 14, 27],
[14, 15, 27],
[27, 15, 28],
[15, 16, 28],
[28, 16, 29],
[16, 18, 29],
[29, 18, 30],
[18, 20, 30],
[30, 20, 31],
[20, 21, 31],
[31, 21, 32],
[21, 22, 32],
[32, 22, 33],
[22, 23, 33],
[33, 23, 34],
[26, 27, 35],
[35, 27, 36],
[27, 28, 36],
[36, 28, 37],
[28, 29, 37],
[37, 29, 38],
[29, 30, 38],
[38, 30, 39],
[30, 31, 39],
[39, 31, 40],
[31, 32, 40],
[40, 32, 41],
[32, 33, 41],
[41, 33, 42],
[33, 34, 42],
[42, 34, 43],
[44, 35, 45],
[45, 35, 46],
[35, 36, 46],
[46, 36, 47],
[36, 37, 47],
[47, 37, 48],
[37, 38, 48],
[48, 38, 49],
[38, 39, 49],
[49, 39, 50],
[39, 40, 50],
[50, 40, 51],
[40, 41, 51],
[51, 41, 52],
[41, 42, 52],
[52, 42, 53],
[42, 43, 53],
[53, 43, 54],
[43, 55, 54],
[54, 55, 56],
]
Using swift, find the counts of each element of this type of array, while preserving the triplets, so the output would look like this:
let keyValuePairs =[
[[0: 1], [1: 3], [2: 5]],
[[2: 5], [1: 3], [3: 6]],
[[1: 3], [4: 2], [3: 6]],
[[3: 6], [4: 2], [5: 4]],
[[6: 1], [7: 3], [8: 5]],
[[8: 5], [7: 3], [9: 6]],
[[7: 3], [10: 2], [9: 6]],
[[9: 6], [10: 2], [11: 4]],
// etc. ...
]
I am only suggesting "reduce(into" as it feels like it is possible, but it maybe something else entirely that is better/faster/stronger.
(does not have to preserve the order of the triplet sets, but must preserver the order of elements inside the triplet: for instance the first and second one needs to stay [[0:x], [1:x], [2:x]], [[2:x], [1:x], [3:x]], or as an example the order could [[2:x], [1:x], [3:x]], [[0:x], [1:x], [2:x]] instead.
So far I've been able to produce the correct organization using this code below, it feels like this could be solved with reduce(into:_:) but I couldn't correctly "count" the elements.. i've left the code in that doesn't count correctly, obviously because it is intialized each time, but wanted to show what I had so far:
let keyValuePairs = usedIndicies2.reduce(into: [[[UInt32:Int]]]()) { (array, entry) in
var dict0:[UInt32:Int] = [UInt32:Int]()
var dict1:[UInt32:Int] = [UInt32:Int]()
var dict2:[UInt32:Int] = [UInt32:Int]()
dict0[entry[0], default: 0] += 1
dict1[entry[1], default: 0] += 1
dict2[entry[2], default: 0] += 1
var array012:[[UInt32:Int]] = [[UInt32:Int]]()
array012.append(dict0)
array012.append(dict1)
array012.append(dict2)
array.append(array012)
}
print("keyValuePairs:",keyValuePairs)
the output of this partially working code looks like this:
let keyValuePairs** = [
[[0: 1], [1: 1], [2: 1]],
[[2: 1], [1: 1], [3: 1]],
[[1: 1], [4: 1], [3: 1]],
[[3: 1], [4: 1], [5: 1]],
[[6: 1], [7: 1], [8: 1]],
[[8: 1], [7: 1], [9: 1]],
[[7: 1], [10: 1], [9: 1]],
[[9: 1], [10: 1], [11: 1]],
// etc...
]
would greatly appreciate your insights
Two steps:
Flatten the array and just make an ordinary histogram (count) for all values (that's a one-liner).
Now go back to the original array and map it into the array of pairs.
To demonstrate, I'll just operate on the opening piece of your data just to prove it works. I've given my own interpretation of the notion of a key value pair (I've used a tuple with labels), but feel free to patch that up as desired.
let original = [[0, 1, 2], [2, 1, 3], [1, 4, 3], [3, 4, 5]]
// step 1
var histo = [Int:Int]()
original.flatMap {$0}.forEach {histo[$0, default:0] += 1}
// step 2
let output = original.map {array in array.map {i in (item:i, count:histo[i]!)}}
Result:
[[(item: 0, count: 1), (item: 1, count: 3), (item: 2, count: 2)],
[(item: 2, count: 2), (item: 1, count: 3), (item: 3, count: 3)],
[(item: 1, count: 3), (item: 4, count: 2), (item: 3, count: 3)],
[(item: 3, count: 3), (item: 4, count: 2), (item: 5, count: 1)]]
And that is correct.
I use Google Chart as DataTable.
I try to make hAxis like as date format:
hAxis: {
title: '',
format: 'date',
viewWindow: {
min: [7, 30, 0],
max: [17, 30, 0]
}
}
And add rows as:
data.addRows([
[{v: [8, 0, 0], f: '03/02/13'}, 1],
[{v: [9, 0, 0], f: '04/02/13'}, 2],
[{v: [10, 0, 0], f:'05/02/13'}, 3],
[{v: [11, 0, 0], f: '06/02/13'}, 4],
[{v: [12, 0, 0], f: '07/02/13'}, 5]
]);
I need to get in horizontal line(hAxis) titles in date format: dd/mm/yy
hAxis.format expects a pattern, or pattern name
so it would be something like...
hAxis: {
format: 'short'
// or
format: 'dd/MM/yy'
}
however, as pointed out in the comments, the column type appears to be timeofday
to avoid changing the column type, you can provide your own custom hAxis.ticks,
using the data provided to the chart
see following, working snippet. uses rawData to populate chart data and ticks...
google.charts.load('current', {
callback: function () {
var rawData = [
[{v: [8, 0, 0], f: '03/02/13'}, 1],
[{v: [9, 0, 0], f: '04/02/13'}, 2],
[{v: [10, 0, 0], f:'05/02/13'}, 3],
[{v: [11, 0, 0], f: '06/02/13'}, 4],
[{v: [12, 0, 0], f: '07/02/13'}, 5]
];
var data = new google.visualization.DataTable();
data.addColumn({label: 'Date', type: 'timeofday'});
data.addColumn({label: 'Count', type: 'number'});
data.addRows(rawData);
var hTicks = [];
for (var i = 0; i < rawData.length; i++) {
hTicks.push(rawData[i][0]);
}
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, {
hAxis: {
ticks: hTicks,
title: '',
viewWindow: {
min: [7, 30, 0],
max: [17, 30, 0]
}
}
});
},
packages:['corechart']
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>
I have five arrays. I can use five for-loop to generate the result, but I need a recursive function so that I can generate the combinations from more arrays. How do I use a recursive function to generate the combinations? Each combination includes one element from the five arrays.
I'm not sure why you need it to be recursive, but there are a few ways to do it, anyway. You can use higher-order functions to make an Array extension that does what you want:
extension Array {
func everyOf<S: SequenceType where S.Generator.Element == T>(ar: S...) -> [[T]] {
return ar.reduce(self.map{[$0]}){
perms, items in perms.flatMap {
perm in Swift.map(items){ perm + [$0] }
}
}
}
}
This would work like:
[1, 2].everyOf([3, 4]) //[[1, 3], [1, 4], [2, 3], [2, 4]]
or:
[1, 2].everyOf([3, 4], [5, 6])
//[
// [1, 3, 5],
// [1, 3, 6],
// [1, 4, 5],
// [1, 4, 6],
// [2, 3, 5],
// [2, 3, 6],
// [2, 4, 5],
// [2, 4, 6]
//]
But the different arrays don't have to be the same length:
[1, 2].everyOf([3], [5, 6]) // [[1, 3, 5], [1, 3, 6], [2, 3, 5], [2, 3, 6]]
And you can do it as a non-method as well:
func everyOf<T>(ar: [[T]]) -> [[T]] {
return dropLast(ar).reduce(ar.last!.map{[$0]}){
perms, items in perms.flatMap{
perm in Swift.map(items){ perm + [$0] }
}
}
}
everyOf([[1, 2], [3, 4]]) // [[3, 1], [3, 2], [4, 1], [4, 2]]
If you're really into the 'aul recursion, though, here you go:
func everyOf<T>(seqs: [[T]]) -> [[T]] {
return last(seqs).map {
fSeq in everyOf(Array(dropLast(seqs))).flatMap {
seq in fSeq.map{ seq + [$0] }
}
} ?? [[]]
}
everyOf([[1, 2], [3, 4]]) // [[3, 1], [3, 2], [4, 1], [4, 2]]
I try to create a bar chart with percentage numbers on each bar number.
the following is my code, I want the Percentage to be shown in bar Numbers, also Count of each item in the tool tip (vise versa) .
I've tried stackedpercent but it didn't work.
For example these are my percentage values for data:
var dc20 = [[37, 0], [0, 1], [16, 2], [34, 3]];
var dc21 = [[58, 0], [0, 1], [80, 2], [62, 3]];
var dc22 = [[0, 0], [0, 1], [0, 2], [0, 3]];
var dc23 = [[5, 0], [100, 1], [4, 2], [4, 3]];
var dc24 = [[0, 0], [0, 1], [0, 2], [0, 3]];
and these values are for Count of records
var dc20 = [[16, 0], [0, 1], [5, 2], [11, 3]];
var dc21 = [[25, 0], [0, 1], [25, 2], [20, 3]];
var dc22 = [[0, 0], [0, 1], [0, 2], [0, 3]];
var dc23 = [[2, 0], [1, 1], [1, 2], [1, 3]];
var dc24 = [[0, 0], [0, 1], [0, 2], [0, 3]];
Update
This is the Fiddle link for that.
The simplest solution is to add the counts as a seperate array:
var counts = [
[16, 0, 5, 11],
[25, 0, 25, 20],
[0, 0, 0, 0],
[2, 1, 1, 1],
[0, 0, 0, 0]
];
and use that in the tooltipOpts:
content: function (label, xval, yval, flotItem) {
return '%' + xval + 'which has ' + counts[flotItem.seriesIndex][flotItem.dataIndex] + ' records ';
},
See the updated fiddle.