Plotly data from nested for loop - javascript

In c# codebehind I define a few Lists this way:
public List<string> divs = new List<string>();
public List<List<string>> names = new List<List<string>>();
public List<List<List<string>>> labels = new List<List<List<string>>>();
public List<List<List<double>>> longitude = new List<List<List<double>>>();
Quite large lists I know but I feel it's necessary for getting all my info from my source organized correctly.
in JS I serialize these like this:
var divArr = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(divs)%>;
var names = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(names)%>;
var lbl = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(labels)%>;
var long = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(longitude)%>;
And then I try to do a function to plot all this on separate graphs. 10 graphs in total on my page that can have several lines on all of them. Trying to make my page as dynamic as possible. So I have a function to loop through all of this and try to plot it all.
function doGraph(){
for(index = 0; index < divArr.length; ++index){
(function() {
var data = [];
for(indx = 0; indx < lbl[index].length; ++indx){
var trace = {
name: names[index][indx],
x: lbl[index][indx],
y: long[index][indx],
mode:'lines'
};
data.push(trace);
}
var gd = document.getElementById(divArr[index]);
plotly.newPlot(gd,data);
})();
}
}
And it ALMOST works. Every graph seems to plot the first set of data given to it but nothing afterwords. Maybe I've been staring at this too long but I just can't see what I'm doing wrong here but I'm sure it's something I've just over looked. Or maybe I'm overreaching and I can't do this sort of thing? Any insight is appreciated!

So I found out the problem was with the serialization from my lists to js arrays. Apparently js serialize can't quite handle the level of multidimensional list I was going crazy with. So I fixed it by making the lists one level less deep and made another list to keep track of how "deep" they are in this fashion:
C# Codebehind:
public List<List<string>> names = new List<List<string>>();
public List<int> numObjs = new List<int>();
public List<List<string>> labels = new List<List<string>>();
public List<List<double>> longitude = new List<List<double>>();
JS Serialization:
var divArr = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(divs)%>;
var names = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(names)%>;
var numO = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(numObjs)%>;
var lbl = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(labels)%>;
var long = <%=new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(longitude)%>;
Then the JS function has the real changes with a loop in this way:
function doGraph(){
var cur = 0;
for(var index = 0; index < divArr.length; ++index){
var data = [];
var top = cur + numO[index];
for(var indx = cur; indx < top; ++indx){
data.push({
name: names[indx],
mode:'lines',
x: lbl[indx],
y: long[indx],
});
cur++;
}
var gd = document.getElementById(divArr[index]);
Plotly.newPlot(gd, data,
layout , {scrollZoom:true,modeBarButtonsToRemove:['sendDataToCloud'],showLink:false,displaylogo:false});
}
}
Also my function within a function was definitely unnecessary as #flipperweid said.

Related

Indesign Script for PDF Object Layer Options

I have an indesign document with multiple pages. each page has a linked pdf in it. each pdf has 3 layers within it and in order to turn these layers on or off, you have to right click, select Object Layer Options, and then manually turn on or off layers.
I would like to loop through all my pages and turn on a layer in the PDF using a script. i have been messing with graphicLayerOptions.graphicLayers but keep running into an error when telling it to turn the currentVisibilty=true;
var myDocument = app.activeDocument;
var docLength = myDocument.pages.length;
var myPages = myDocument.pages
for (var i = 0; i < docLength; i++) {
var labelPlaceholder = myDocument.allGraphics;
var labelArtwork = labelPlaceholder[0];
var artworkLayers = labelArtwork.graphicLayerOptions.graphicLayers;
artworkLayers.item("Die Copy").currentVisibility = true;
}
i got it working...l
var myDocument = app.activeDocument;
var docLength = myDocument.pages.length;
var myPages = myDocument.pages
for (var i = 0; i < docLength; i++) {
var labelPlaceholder = myPages[i].allGraphics;
var labelArtwork = labelPlaceholder[0];
var artworkLayers = labelArtwork.graphicLayerOptions.graphicLayers;
artworkLayers[0].currentVisibility = true;
}
Just in case. In InDesing (Illustrator, etc) you have two options to get an item from a collection.
By its number:
var layer = app.activeDocument.layers[0];
By its name:
var layer = app.activeDocument.layers.itemByName("Die Copy");
Later options is less reliable. Not all collections has this method. I don't know if it (PDF layers) is the case, though.

How to dynamically add object to array (closure in loop)

I read couple posts about the closure in loop but still not really get it how to apply to my situation.
I have three feed urls defined in HTML and using JavaScript promise to return the response when it's ready without blocking the UI. I am able to get two blog entries data per feed url. Now, each returned blog entry has its published date and I would like to sort them from latest to oldest. However, I keep getting the last value when I pushed the object to array. I know this is something to do with closure and since I'm not familiar with closure, I have difficulty to solve this problem. Any help is great appreciated!
var itemArray = [];
var entryObj = {};
promise.then(function (response) {
var parser = new DOMParser();
xml = parser.parseFromString(response, "text/xml");
var items = xml.getElementsByTagName("item");
for (var x = 0; x < items.length && x < limits; x++) {
title = items[x].getElementsByTagName("title")[0].innerHTML;
link = items[x].getElementsByTagName("link")[0].innerHTML;
pubDate = items[x].getElementsByTagName("pubDate")[0].innerHTML;
creator = items[x].getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", "creator")[0].innerHTML;
entryObj.title = title;
entryObj.link = link;
entryObj.pubDate = pubDate;
entryObj.creator = creator;
itemArray.push(entryObj);
// output: all 6 objects contain last value
console.log(itemArray);
}
});
In short : Move the object creation inside the loop.
It's nothing to do with closure. The issue is, you are pushing the same object.
You need a new object to be pushed. So create the object inside the for loop. So that every time you get a new object and it gets pushed to the array.
Code-
var itemArray = [];
promise.then(function (response) {
var parser = new DOMParser();
xml = parser.parseFromString(response, "text/xml");
var items = xml.getElementsByTagName("item");
for (var x = 0; x < items.length && x < limits; x++) {
var entryObj = {};
title = items[x].getElementsByTagName("title")[0].innerHTML;
link = items[x].getElementsByTagName("link")[0].innerHTML;
pubDate = items[x].getElementsByTagName("pubDate")[0].innerHTML;
creator = items[x].getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", "creator")[0].innerHTML;
entryObj.title = title;
entryObj.link = link;
entryObj.pubDate = pubDate;
entryObj.creator = creator;
itemArray.push(entryObj);
// output: Now all values are unique
console.log(itemArray);
}
});
Move var entryObj = {}; into your for loop.

Parse all values from a XML element using Google Apps Script?

I am trying to parse forex values (all of them) for http://indicador.eof.cl/rss XML feed into a Gooogle Sites trough Google Apps Script.
The script as follow>
function doGet(){
var response = UrlFetchApp.fetch("http://indicador.eof.cl/rss").getContentText();
var parsedResponse = Xml.parse(response, false);
var root = parsedResponse.getElement();
var entries = root.getElement('channel').getElements("item");
for (var i=0; i<entries.length; i++) {
var e = entries[i];
var title = e.getElement("title").getText();
var description = e.getElement("description").getText();
}
var app = UiApp.createApplication();
var TopVar = app.createHorizontalPanel();
TopVar.add(app.createLabel(title).setStyleAttribute("fontSize","12px"));
TopVar.add(app.createLabel(description).setStyleAttribute("fontSize","12px"));
app.add(TopVar);
return app;
}
The issue is the code just bring me the first value no all of them, what i am forgetting?
Best Regards,
Try to move TopVar.add(...); lines inside for loop :
var app = UiApp.createApplication();
var TopVar = app.createHorizontalPanel();
for (var i=0; i<entries.length; i++) {
var e = entries[i];
var title = e.getElement("title").getText();
var description = e.getElement("description").getText();
TopVar.add(app.createLabel(title).setStyleAttribute("fontSize","12px"));
TopVar.add(app.createLabel(description).setStyleAttribute("fontSize","12px"));
}
Actually, I know nothing about google-apps-script. But your current code logic seems a bit off. It doesn't make use of values of local variables declare inside for loop (e, title, and description). Value of those variables changed in every iteration without any code using it.

How do I copy a foundset?

So I have the following issue:
I have a Foundset with a bunch of records, and I'd like to (deep) copy them to a new location, including all values but without the IDs. What's the best way to do this?
If you want to do an deep copy of an foundset you need the follow steps:
Create an empty foundset over retrieveOrCreateFoundset()
iterate over all records of the foundset, that should copied to a new one
get the dataProviders with something like rec.dataprovider()
get the value of each dataprovider on a record rec.value()
be sure that the uuid dataprovider isnt copy to the new Record
set the values to a the new record over the dataproviders
persist the changes
Full code example would be:
var vMobileController = plugins.iBizClientWebService.mobileController();
var vFoundset = vMobileController.currentFoundset();
var vDatabaseManager = vMobileController.dataManager();
var copyFoundSet = vDatabaseManager.retrieveOrCreateFoundset("<datasource>:<label>");
for (var index = 0; index < vFoundset.size(); index++) {
var rec = vFoundset.record(index);
var loc = copyFoundSet.newRecord();
var newRecord = copyFoundSet.record(loc);
var allDataproviders = rec.dataprovider();
for(var i=0;i<allDataproviders.length;i++)
{
var dataProvider = allDataproviders[i];
var dataValue = rec.value(dataProvider);
if(dataProvider != "attribute_id")
{
newRecord.setValue(dataProvider, dataValue);
}
}
}
copyFoundSet.saveData();

Create several instances of a module with different values

This is probably a simple problem but I need to create the JavaScript equivalent to N instances of a 'class' whose state must be totally separate.
like:
var car = new Car('Ford');
var car = new Car('Toyota');
How can I achieve this?
You can use an array object to store them:
var cars = [];
cars.push(new Car('Ford'));
cars.push(new Car('Toyota'));
cars[0].beep();
You can iterate over all the stored instances using a for loop:
for (var i = 0; i < cars.length; i++) {
var car = cars[i];
car.beep();
}
It if very difficult to see what the problem is here.
From your code snippet I can see the only problem that you may have in creating new instances is that you'r giving it a the same name.
Give it some other var name:
var ford = new Car('Ford');
var toyota = new Car('Toyota');
Otherwise if you have an array of different makes and want to convert it into an array of car objects you can do this:
var types = ["Ford", "Toyota", "VW", "renault"];
var cars = {};
for (var i = 0; i != types.length ; i++)
cars[types[i]] = new Car(types[i]);
You can access these cars like this:
var ford = cars.Ford;
or like this:
var ford = cars["Ford"];

Categories

Resources