RangeSelector display error when data is updated on zoomCallback - javascript

I am trying to update the charts data after zooming. This works so far using the zoomCallback. But when I use the range selector for zooming,
the range selector is not displayed correctly anymore. See the fiddle when using the range selector.
var data = [[1, 4, 5, 6], [2, 5, 6, 8], [3, 7, 4, 2], [4, 9, 6, 4]];
var gra = new Dygraph(
document.getElementById("chart"),
data,
{
labels: ["X", "Y1", "Y2", "Y3"],
hideOverlayOnMouseOut : false,
showRangeSelector: true,
interactionModel: Dygraph.defaultInteractionModel,
rangeSelectorHeight: 30,
connectSeparatedPoints: true,
legend: 'always',
labelsDivWidth: 350,
zoomCallback: function (minX, maxX, yRanges) {
console.log("ZoomCallback!");
updateDataOnZoom();
},
}
);
function updateDataOnZoom() {
var newData = [];
for (var i = 0; i < data.length; i++) {
var newDataElement = [data[i][0]]; // use old Y-Value
for (var j = 1; j < data[i].length; j++) {
newDataElement.push(data[i][j] + 100); // calculate new X-Values
}
newData.push(newDataElement);
}
gra.updateOptions({
file: newData
});
}
Is there a way to solve this display error of the range selector?
Thanks in advance

Related

Javascript Basic Logic - print each three and four cycle from 1 to n

I want to see the output like
[0, 1, 2]
[3, 4, 5, 6]
[7, 8, 9]
[10, 11, 12, 13]
[14, 15, 16]
...
recognize every three(a cycle) and four(b cycle) to do something.
I have only figure out some bad way I think like following:
var arr = [];
function a(n) {
var eachCycle = 7;
var aCycle = 3;
var bCycle = 0;
arr.push(0);
for (var i = 1; i < n; i += 1) {
if (i % eachCycle === aCycle || i % eachCycle === bCycle) {
if(i % eachCycle === aCycle) {
// print three column
} else if(i % eachCycle === bCycle) {
// print four column
}
console.log(arr);
arr.length = 0;
}
arr.push(i)
}
}
is there any good idea to improve this function for the output !?
Thanks
How about this:
function a(n)
{
// keep track of all the cycles
var total = [];
// hold values for the current cycle
var temp = [];
// cycle sizes
var cycleSizes = [3, 4];
// index of the current cycle
var currentCycleIndex = 0;
// iterate through numbers
for(var i = 0; i < n; ++i)
{
// push the value into the temp
temp.push(i);
// if the length of the temp array is the length we want for the current cycle then
if(temp.length == cycleSizes[currentCycleIndex])
{
// save the cycle data
total.push(temp);
// reset the cycle
temp = [];
// change the cycle
currentCycleIndex = currentCycleIndex ^ 1;
}
}
return total;
}
a(9);
[
[0, 1, 2],
[3, 4, 5, 6],
[7, 8]
];
a(17);
[
[0, 1, 2],
[3, 4, 5, 6],
[7, 8, 9],
[10, 11, 12, 13],
[14, 15, 16],
];

Iterating over rows of 2-dimensional array containing arrays of different length

I have a function that picks all elements from a 2-dimensional array by its rows and returns a 1-dimensional array.
The array has a variable amount of columns and rows.
Example:
let arr = [
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
];
Returns:
[1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12]
The function i came up with:
convertList = (list) => {
let result = [];
let listTotalEntries = R.sum(R.map(R.length)(list));
let mod = R.modulo(R.__, list.length);
let counterRow = -1;
for (let i = 0; i < listTotalEntries; i++) {
if (mod(i) === 0) {
counterRow++;
}
if (list[mod(i)][counterRow]) {
result.push(list[mod(i)][counterRow]);
console.log(list[mod(i)][counterRow]);
}
}
console.log(result);
return result;
};
Question: This function works only with square matrices - how can i make it work with a variable length of the contained arrays?
Example:
let arr = [
[1, 2],
[],
[9, 10, 11, 12]
];
Should return:
[1, 9, 2, 10, 11, 12]
Thanks for your help!
Muff
You had a ramda.js tag in here. With Ramda, it's pretty simple, since there are two functions that will help:
const convertList = compose(flatten, transpose);
convertList(arr); //=> [1, 9, 2, 10, 11, 12]
transpose flips a matrix over its main diagonal, that is, changing rows to columns and vice versa. flatten turns a list of lists into a plain list. So composeing like this essentially creates the equivalent of list => flatten(transpose(list)).
You can see this in action on the Ramda REPL.
I suggest to go step-by-step through the arrays
var arr1 = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]],
arr2 = [[1, 2], [], [9, 10, 11, 12]];
function single(array) {
var r = [],
max = Math.max.apply(null, array.map(function (a) { return a.length; })),
i = 0, j,
l = array.length;
while (i < max) {
for (j = 0; j < l ; j++) {
i in array[j] && r.push(array[j][i]);
}
i++;
}
return r;
}
document.write('<pre>' + JSON.stringify(single(arr1), 0, 4) + '</pre>');
document.write('<pre>' + JSON.stringify(single(arr2), 0, 4) + '</pre>');
Did you try this simple one?
var singleDimensionArr = arr.reduce(function(prev,current){return prev.concat(current)});
For example
[
[1, 2],
[],
[9, 10, 11, 12]
].reduce(function(prev,current){return prev.concat(current)});
outputs [1, 2, 9, 10, 11, 12]
Edit:
Based on the inputs from OP below, since the concatenation needs to happen column wise
var max = Math.max.apply(null, arr.map(function (a) { return a.length; }));
var finalArr = []; for( var i = 0; i < max; i++)
{
for( var j = 0; j < arr.length; j++)
{
arr[j][i] ? finalArr.push(arr[j][i]) : "";
}
}
console.log(arr);
This example makes a big sparse array putting each item where it would belong if the array were square. Then it filters out null values which occur where no input item was present.
let arr = [
[1, 2],
[],
[9, 10, 11, 12]
];
var out = arr.reduce(function(o,n,i,a) {
for (var j=0;j<n.length;j++){
o[a.length * j + i] = n[j];
}
return o;
},[]).filter(function(n) {
return n !== null;
});
alert(JSON.stringify(out));

Create an array of first element of each array

I have an array in maxtrix form like this
var costs = [
[4, 6, 8, 8],
[6, 8, 6, 7],
[5, 7, 6, 8],
];
how do i transform it to this
[[4,6,5], [6,8,7], [8,6,5], [8,7,5]]
This is what am trying
var cols = [];
for(var i = 0; i<costs.length; i++)
{
cols.push(costs[i][0]);
}
return col;
And this gives me [4,6,5]. I know am missing something, any help will be great. Thanks
You need another for loop inside the first one:
var costs = [
[4, 6, 8, 8],
[6, 8, 6, 7],
[5, 7, 6, 8],
];
alert("Original: " + JSON.stringify(costs));
// Prepare array...
var cols = new Array(costs[0].length);
for(var i = 0; i < costs[0].length; i++) {
cols[i] = new Array(costs.length);
}
// Assign values...
for(var i = 0; i < costs.length; i++) {
for(var k = 0; k < costs[i].length; k++) {
cols[k][i] = costs[i][k];
}
}
alert("New: " + JSON.stringify(cols));

Generating an matrix from a set of arrays

var set1 = [14, 9, 1, 6, 16],
set2 = [4, 15, 16, 14, 11],
set3 = [16, 10, 2, 3, 8],
set4 = [3, 17, 16, 6, 14],
set5 = [19, 18, 14, 6, 20],
set6 = [6, 15, 8, 7, 2],
set7 = [15, 14, 2, 19, 3],
set8 = [8, 2, 14, 10, 5],
set9 = [11, 6, 8, 10, 18],
set10 = [14, 10, 12, 4, 18],
input = [set1, set2, set3, set4, set5, set6, set7, set8, set9, set10];
// Sort function
function sortFunction(a) {
var len = a.length,
temp, i, j;
for (i = 0; i < len; i++) {
for (j = i + 1; j < len; j++) {
if (a[j] < a[i]) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
return a;
}
// Sorting each sets and finding range of each sets
for (var i = 0; i < len; i++) {
input[i] = sortFunction(input[i]);
minRange.push(Math.min.apply(null, input[i]));
maxRange.push(Math.max.apply(null, input[i]));
}
// Finding the range of input
var minimum = Math.min.apply(null, minRange);
var maximum = Math.max.apply(null, maxRange);
var range = maximum - minimum + 1;
// Matrix table function
var tableArray = [];
function table() {
for (var i = 0; i < len; i++) {
for (var j = 0; j < range; j++) {
if (input[i][j] == j) {
tableArray[i].push(input[i][j]);
} else {
tableArray[i].push(0);
}
}
tableArray.push(tableArray[i]);
}
return tableArray;
}
I am having problem solving this problem: the input is a set of 10 arrays where each array contains 5 different number in range of 1 - 20.
input =[ [14, 9, 1, 6, 16], [4, 15, 16, 14, 11], [16, 10, 2, 3, 8], [3, 17, 16, 6, 14], [19, 18, 14, 6, 20], [6, 15, 8, 7, 2], [15, 14, 2, 19, 3], [8, 2, 14, 10, 5], [11, 6, 8, 10, 18], [14, 10, 12, 4, 18] ]
I would like to generate a 10x20 matrix as output where each row has has 20 numbers with the following pattern:
output = [ [ 1, 0, 0, 0, 0, 6, 0, 0, 9, 0, 0, 0, 0, 14, 0, 16, 0, 0, 0, 0], [ 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 11, 0, 0, 14, 15, 16, 0, 0, 0, 0], [... ], ... ]
Im using JavaScript to solve this...
Create a new output array:
var out = [];
Loop over the input array. For each nested array create a new array in the output array padded with 20 zeros, and then just replace those elements in the output array with the value of the element in the nest input array in the right position. Since you know the size of the nested array, and it's small, its easier just to list each element rather than use an inner loop.
for (var i = 0, l = arr.length; i < l; i++) {
var el = arr[i];
out[i] = Uint8Array(20);
out[i][el[0] - 1] = el[0];
out[i][el[1] - 1] = el[1];
out[i][el[2] - 1] = el[2];
out[i][el[3] - 1] = el[3];
out[i][el[4] - 1] = el[4];
}
DEMO
If your browser doesn't support Uint8Array you can use a separate function to create a padded array:
function padArray() {
var out = [];
for (var i = 0, l = 20; i < l; i++) {
out.push(0);
}
return out;
}
And use:
out[i] = padArray();
You really should have tried it yourself. It's rather easy. Start with an array of 20 zeros, then fill the slots with the values from the array:
function posArray(arr, max) {
var res = [];
for (var i = 0; i < max; i++) res.push(0);
for (var i = 0; i < arr.length; i++) {
var a = arr[i];
if (a > 0 && a <= max) res[a - 1] = a;
}
return res;
}
var output = [];
for (var i = 0; i < input.length; i++) {
output.push(posArray(input[i], 20));
}
Something like this would also work (not tested):
var set1 = [14, 9, 1, 6, 16],
set2 = [4, 15, 16, 14, 11],
set3 = [16, 10, 2, 3, 8],
set4 = [3, 17, 16, 6, 14],
set5 = [19, 18, 14, 6, 20],
set6 = [6, 15, 8, 7, 2],
set7 = [15, 14, 2, 19, 3],
set8 = [8, 2, 14, 10, 5],
set9 = [11, 6, 8, 10, 18],
set10 = [14, 10, 12, 4, 18],
input = [set1, set2, set3, set4, set5, set6, set7, set8, set9, set10];
var output = [];
for (var e=0; e<input.length; e++) {
newRow = [];
for (var i=0;i<20; i++) {
if (input[e].indexOf(i) > -1) {
newRow.push(i);
}
else {
newRow.push(0);
}
}
output.push(newRow);
}
alert(output);

JavaScript Nested for showing wrong results

I am having trouble with this code and can not figure it out. It appears to add to "data" rather than to "ticket" from "data" like it should. Using code in Google Script
function consolidate(){
var data = [[1,1,1,1,1,1],[1,1,1,1,1,1],[1,2,1,2,1,2],[1,2,1,2,1,2],[1,1,1,1,1,1],[1,2,1,2,1,2],[1,1,1,1,1,1],[1,2,1,2,1,2],[1,2,1,2,1,2]];
var ticket = [];
ticket[0] = data[0];
for(var x=0;x<data.length;x++){
for(var i=0;i<ticket.length;i++){
if(ticket[i][0]==data[x][0]&&ticket[i][1]==data[x][1]&&ticket[i][2]==data[x][2]&&ticket[i][4]==data[x][4]){
ticket[i][3]=ticket[i][3]+data[x][3];
ticket[i][5]=ticket[i][5]+data[x][5];
break;
}
}
ticket[i]=data[x];
}
}
my result for data is
[[1, 1, 1, 3, 1, 3], [1, 1, 1, 2, 1, 2], [1, 2, 1, 4, 1, 4], [1, 2, 1, 4, 1, 4], [1, 1, 1, 2, 1, 2], [1, 2, 1, 4, 1, 4], [1, 1, 1, 1, 1, 1], [1, 2, 1, 4, 1, 4], [1, 2, 1, 2, 1, 2]]
but data should not change
function consolidate(){
var data = [[1,1,1,1,1,1],[1,1,1,1,1,1],[1,2,1,2,1,2],
[1,2,1,2,1,2],[1,1,1,1,1,1],[1,2,1,2,1,2],
[1,1,1,1,1,1],[1,2,1,2,1,2],[1,2,1,2,1,2]];
var ticket = [];
ticket[0] = data[0].slice();
for(var x = 0; x < data.length; x++) {
for(var i = 0; i < ticket.length; i++) {
for(var k = 0; k < 5; k++) {
if (ticket[i][k] != data[x][k])
break;
else if (k != 4)
continue;
ticket[i][3] += data[x][3];
ticket[i][5] += data[x][5];
}
}
ticket[i] = data[x].slice();
}
console.log(data);
}
consolidate();
This is where I got and it works. If there is a way to make it better please let me know
function consolidate1(){// put data in here <-----()
var data = [[1,1,1,1,1,1],[2,1,1,1,1,1],[1,1,1,1,1,1],[2,1,1,1,1,1],[1,1,1,1,1,1],[3,1,1,1,1,1],[1,1,1,1,1,1],[3,1,1,1,1,1],[1,1,1,1,1,1]];
var ticket = [];
ticket[0]=[];
ticket[0][0]=data[0][0];
ticket[0][1]=data[0][1];
ticket[0][2]=data[0][2];
ticket[0][3]=data[0][3];
ticket[0][4]=data[0][4];
ticket[0][5]=data[0][5];
for(var x=1;x<data.length;x++){ //get all the unique rows based on columns 0,1,2,4
var indicator = 0;
for(var i=0;i<ticket.length;i++){
if(ticket[i][0]==data[x][0] && ticket[i][1]==data[x][1] && ticket[i][2]==data[x][2] && ticket[i][4]==data[x][4]){
ticket[i][3]=ticket[i][3]+data[x][3];
ticket[i][5]=ticket[i][5]+data[x][5];
indicator = 1;
break;
}
}
if(indicator==0){
ticket[i]=[];
ticket[i][0]=data[x][0];
ticket[i][1]=data[x][1];
ticket[i][2]=data[x][2];
ticket[i][3]=data[x][3];
ticket[i][4]=data[x][4];
ticket[i][5]=data[x][5];
}
}
Logger.log(ticket);
}

Categories

Resources