0

Essentially what I'm trying to do is have a button .push a line into an array and I want JUMflot to keep redrawing those but not affect the line being pushed in.

What I had done initially was have something like this (the generator ID is my button and options are defined however not relevant to my question so I didn't include them):

var genVector=[[0,1],[6,6]]; //line being pushed in

var data = [];

$("#generator").click(function(){ 
    data.push({data: genVector, editable: true});
    var p = $.plot($("#graph"),data,options); 
});

$("#graph").bind("datadrop", function(event,pos,item) { 
    data[item.seriesIndex].data[item.dataIndex] = [Math.round(pos.x1),Math.round(pos.y1)];
    p = $.plot($("#graph"), data, options);
};

What I realized would end up happening, is that every time I chose to move the point my genVector coordinates would change. So to work around this I did the following:

var vectorCounter=0;

var genVector=[[0,1],[6,6]];

var data = [];

var vectorArray=[];

$("#generator").click(function(){
    vectorArray.push(genVector);
    data.push({data: vectorArray[vectorCounter], editable: true});
    vectorCounter++;
    var p = $.plot($("#graph"),data,options);
});

$("#graph").bind("datadrop", function(event,pos,item) { 
    data[item.seriesIndex].data[item.dataIndex] = [Math.round(pos.x1),Math.round(pos.y1)];
    p = $.plot($("#graph"), data, options);
};

I thought adding the vector to a separate array and modifying it from there would leave the genVector alone. It did not.

I'm assuming this has something to do with how the JUMflot code is written? Even if it does not, how can I achieve what I'm doing? Thanks in advance!

dajavinator
  • 81
  • 1
  • 6

1 Answers1

2

This has nothing to do with JUMflot but it rather a question on object references.

When push genVector into vectorArray:

vectorArray.push(genVector);

This does not create a new array inside vector array, but rather vectorArray now holds a reference to genVector.

So when you push vectorArray[0], into data you are just getting the reference to the orginal genVector. Illustrated by:

> data[0].data[0] = "Mark is Awesome";
  "Mark is Awesome"
> genVector
  ["Mark is Awesome", 
    Array[2]
  ]

This whole concept can be more simply shown with:

> x = [1,2,3];
  [1, 2, 3]
> y = x
  [1, 2, 3]
> y[0] = "Mark is Awesome"
  "Mark is Awesome"
> x
  ["Mark is Awesome", 2, 3]

So the question becomes, how do you copy or clone an array? The easiest is using the slice trick:

> x = [1,2,3];
  [1, 2, 3]
> y = x.slice(0);
  [1, 2, 3]
> y[0] = "Mark is Awesome"
  "Mark is Awesome"
> x
  [1, 2, 3]

This is a shallow copy, though, if the array contains an object reference, it won't clone it:

> x = [{'a':'b'},2,3];
  [Object, 2, 3]
> y = x.slice(0);
  [Object, 2, 3]
> y[0]['a'] = "Mark is Awesome"
  "Mark is Awesome"
> x
  [Object
     a: "Mark is Awesome"
     __proto__: Object
     , 2, 3]

If you want to clone everything, you need to use a deep copy. I won't go into details on that as I'd just be duplicating the excellent discussion here.

Community
  • 1
  • 1
Mark
  • 106,305
  • 20
  • 172
  • 230
  • Thank you so much for teaching me this. The only other language I've used was C++ and things were passed by value by default. I didn't know Javascript was different. Thanks! – dajavinator Jun 27 '14 at 14:28