How to update Bokeh source with CustomJS - javascript

I am having some troubles while trying to update my Bokeh source when using a Select widget and CustomJS. CustomJS is a mandatory requirement in this case, so no def: function can be used.
The below code returns the data visualisation but it does not refresh as, I guess, the JS code is not properly written and I got no way to debug it (if someone knows how, please its indeed the best answer I could get).
The main idea is to filter my source based on the value selected on the Select widget.
Any ideas??
source = ColumnDataSource(data=dict(
x=gx,
y=gy,
recty=recty,
colors=colors,
filter_info= filter_info))
select = Select(title="Option:", value="All", options=["All", "1", "2", "3", "4", "5", "6+"])
renderer_source = source
# Add the slider
code = """
var value_filter_info = cb_obj.value;
if value_assignments == 'All' {
new_source_data['x'] = source.data['x'];
new_source_data['y'] = source.data['y'];
new_source_data['recty'] = source.data['recty'];
new_source_data['colors'] = source.data['colors'];
} else {
new_source_data['x'] = source.data['x'][source.data['filter_info']==value_filter_info];
new_source_data['y'] = source.data['y'][source.data['filter_info']==value_filter_info];
new_source_data['recty'] = source.data['recty'][source.data['filter_info']==value_filter_info];
new_source_data['colors'] = source.data['colors'][source.data['filter_info']==value_filter_info];
}
renderer_source.data= new_source_data;
renderer_source.change.emit();
"""
callback = CustomJS(args=dict(source=source, renderer_source=renderer_source), code=code)
select.js_on_change('value', callback)
p = figure(plot_width=1200, plot_height=400, x_range=(0,100), y_range=(0,1000))
p.rect(x='x', y='recty', width=1, height=1, color='colors', source=renderer_source, line_color=None, fill_alpha=1, width_units="data", height_units="data")
plot_layout = column(select,p)
show(plot_layout)
output_notebook()
Many thanks!

So I found a solution that can be aesthetically, programatically, and visually improved but at least the outcome is shown.
Following the advice by #bigreddot on indexing and overwriting, I managed to write the current CustomJS code:
code = """
var render=renderer_source.data;
var data=source.data;
var data_assignment = data['assignments'];
var value_assignments = cb_obj.value;
var data_x=data['x'];
var data_y=data['y'];
var data_recty=data['recty'];
var data_colors=data['colors'];
var render_x=render['x'];
var render_y=render['y'];
var render_recty=render['recty'];
var render_colors=render['colors'];
var x = [];
var y = [];
var recty = [];
var colors = [];
render_x=[];
render_y=[];
render_recty=[];
render_colors=[];
for (var i=0;i<data_assignment.length; i++){
if (value_assignments == 'All') {
x.push(data_x[i]);
y.push(data_y[i]);
recty.push(data_recty[i]);
colors.push(data_colors[i]);
} else if (data_assignment[i]==value_assignments) {
x.push(data_x[i]);
y.push(data_y[i]);
recty.push(data_recty[i]);
colors.push(data_colors[i]);
}
}
renderer_source.data['x']=x;
renderer_source.data['y']=y;
renderer_source.data['recty']=recty;
renderer_source.data['colors']=colors;
renderer_source.change.emit();
"""

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.

copy paste range into next column and update

column B gets data updated
column C onwards is used to store consolidated data
im trying to copy a range of data to right next column
and update column C with data from column B
function doUpBCL() {
var ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('BLC');
var data_new = ss.getRange('B1').getDisplayValue();
var data_old = ss.getRange('C1').getDisplayValue();
if( data_new !== data_old ) // check if data changed
{
var lr = ss.getLastRow();
var lc = ss.getLastColumn();
var data = ss.getRange(1,3,lr,lc - 3).getValues();
ss.getRange(1,4,lr,lc - 4).setValues(data);
var data_ = ss.getRange(lr,2,1,1).getValues();
ss.getRange(lr,3,1,1).setValues(data_);
}
};
macro (created by Google Sheets) as EXAMPLE to ilustrate what i want is (i need help with above function, not this)
function upblc_macro() {
var spreadsheet = SpreadsheetApp.getActive();
spreadsheet.setActiveSheet(spreadsheet.getSheetByName('BLC'), true);
spreadsheet.getRange('D:D').activate();
spreadsheet.getRange('C:Z').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_NORMAL, false);
spreadsheet.getRange('C:C').activate();
spreadsheet.getRange('B:B').copyTo(spreadsheet.getActiveRange(), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
};
using last row cos im going to use similar funcions to other pages and im trying to funcion where i dont have to adjust everytime
simply add new column, move or append to last column wont work the way i need
help is much appreciated, thanks
with lots of tries and errors, with a few tweaks and minor changes, i managed to make it work as i wanted
function doUpBCL() {
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('BLC');
const data_new = ss.getRange('B1').getDisplayValue();
const data_old = ss.getRange('C1').getDisplayValue();
if( data_new !== data_old ) // check if data changed
{
var lr = ss.getLastRow();
var lc = ss.getLastColumn();
const data = ss.getRange(1,3,lr,lc-2).getValues();
ss.getRange(1,4,lr,lc-2).setValues(data);
const data_ = ss.getRange(1,2,lr,1).getValues();
ss.getRange(1,3,lr,1).setValues(data_);
}
else
{
}
};
not sure why of some stuff i changed, some other stuff i learned, but still learning

Add marking to JSViz Visualization in Spotfire

I am stuck on an issue where I need to add marking to D3 VennDiagram Visualization in Spotfire, I tried adding below code but it fails to execute marking:
Hi Team,
I am not able to add marking to VennDiagram or any other JSViz samples provided by TIBCO for D3.
You can download the DXP file from : https://drive.google.com/folderview?id=0B7rSzsao8vgUUlEyc0hWUk13WmM
I am using the following code to add marking, but it fails:
function markModel(markMode, rectangle) {
if (svg) {
// No point in continuing if we don't have an svg object
// Start collecting indexes of svg objects marked.
var indicesToMark = [];
var markData = {};
markData.markMode = markMode;
svgElem = svg[0][0];
var rpos = svgElem.createSVGRect();
rpos.x = rectangle.x;
rpos.y = rectangle.y;
rpos.height = rectangle.height; // + one to get the item under the click
rpos.width = rectangle.width; // + one to get the item under the click
var elements = svgElem.getIntersectionList(rpos, svgElem);
for (var index = 0; index < elements.length; index = index + 1) {
if (elements[index].id) {
indicesToMark.push(elements[index].id);
}
}
markData.indexSet = indicesToMark;
markIndices ( markData );
}
Please let me know your thoughts on this

restructure CSV data to create correct format in JSON

I'm working with some CSV data. Right now the CSV has a column called 'characteristic' which is one of three types, and a column called 'value', which contains the numerical value for the characteristic.
I'd like to change the structure of the data so that the columns are the characteristics themselves, and the values fall directly under those columns.
Here are screenshots of the tables, for clarity:
Currently:
What I'd like:
I changed things manually to give an example. The actual table I'll need to change is thousands of lines, so I'm hoping I can do this programmatically in some way.
The reason I need to restructure is that I need to transform the CSV to JSON, and the JSON needs to look like this:
[
{
"country":"afghanistan",
"iso3":"afg",
"first_indicator":3,
"second_indicator":5,
"third_indicator":3
},
{
"country":"united states",
"iso3":"usa",
"first_indicator":8,
"second_indicator":6,
"third_indicator":7
},
{
"country":"china",
"iso3":"chn",
"first_indicator":6,
"second_indicator":0.7,
"third_indicator":2
}
]
So - is there any way to take my CSV as it is now (first screenshot), and transform it to the JSON I want, without doing it all manually?
I've done a lot of searching, and I think maybe I just don't know what to search for. Ideally I would use javascript for this, but any suggestions welcome.
Thank you.
I made a JSFiddle for you, something like this should be what you want.
JavaScript
function Country(name, short){
this["country"] = name;
this["iso3"] = short;
}
function getCountryByName(name) {
for(var i = 0; i < countries.length; i++){
var country = countries[i];
if(country["country"] == name){
return country;
}
}
return null;
}
var csv = "country,shortname,characteristics,value\nafghanistan,afg,first_characteristic,3\nunited states,usa,first_characteristic,8\nchina,chn,first_characteristic,6\nafghanistan,afg,second_characteristic,5\nunited states,usa,second_characteristic,6\nchina,chn,second_characteristic,0.7\nafghanistan,afg,third_characteristic,3\nunited states,usa,third_characteristic,7\nchina,chn,third_characteristic,2"
var rows = csv.split("\n");
var countries = [];
if(rows.length > 0){
var header = rows[0];
var columns = header.split(",");
var countryIndex = columns.indexOf("country");
var shortnameIndex = columns.indexOf("shortname");
var characteristicsIndex = columns.indexOf("characteristics");
var valueIndex = columns.indexOf("value");
for(var i = 1; i < rows.length; i++) {
var row = rows[i];
var columns = row.split(",");
var name = columns[countryIndex];
var short = columns[shortnameIndex];
var characteristic = columns[characteristicsIndex];
var value = columns[valueIndex];
var country = getCountryByName(name);
if(!country){
country = new Country(name, short);
countries.push(country);
}
country[characteristic.replace("characteristic", "indicator")] = +value;
}
}
console.log(countries);
console.log(JSON.stringify(countries));
Output from the last line is this:
[{"country":"afghanistan","iso3":"afg","first_indicator":"3","second_indicator":"5","third_indicator":"3"},
{"country":"united states","iso3":"usa","first_indicator":"8","second_indicator":"6","third_indicator":"7"},
{"country":"china","iso3":"chn","first_indicator":"6","second_indicator":"0.7","third_indicator":"2"}]
My suggestion is to convert the CSV to JSON first. You can use an online tool.
When you have the JSON you can write a Javascript code to modify the JSON in the format you want.

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.

Categories

Resources