Need to pass node object created in loop to edges - javascript

I am reading in and looping through a json file to create a graph with nodes and edges using a JavaScript library cytoscape, but am having some newbie problems. Here is my pseudo code w/pseudo bugs.
1) Create new node for each node with label 'x'
2) For each edge in edges, create edge with 'source', 'target'.
The problem that I am having is that to create the edge I need to pass each node object as the argument, (sourceNode, targetNode, {weight: 'y'} so something like this will not work
var edge = graph.newEdge({source: graphP.elements.edges[j].data.source},
{target: graphP.elements.edges[j].data.target});
I tried creating an array and writing each new node to it, but I just end up over-writing the value of the variable name and end up with an array of length 1. While all my nodes are created, I need a way to go back and access the nodes in order to create the edges ( and obviously not have them point to themselves).
I am guessing it will be some sort of nodeObject.hasKey[label] and match on that label to retrieve node ID, then create new edge?
I've thought myself in a knot here. Any advice is appreciated. Below is my current code with abbreviated json file read in.
<html>
<head>
<title>Springy.js image node demo</title>
</head>
<body>
<script src="jquery-1.11.3.js"></script>
<script src="springy.js"></script>
<script src="springyui.js"></script>
<!--<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>-->
<script/>
$(document).ready(function(){
$.ajax({
url: 'https://rawgit.com/theresajbecker/CompBio/master/SuperSmallNodes.json',
type: 'GET',
dataType: 'json'
}).done(function(graphP) {
console.log(graphP);
var graph = new Springy.Graph();
for ( i = 0 ; i < graphP.elements.nodes.length ; i++ ) {
var nodeArray = []
var Nlabel1 = graphP.elements.nodes[i].data.label
var Nlabel2 = graphP.elements.nodes[i++].data.label
console.log('Nlabel1')
console.log(Nlabel1)
console.log('Nlabel2')
console.log(Nlabel2)
var NN1 = graph.newNode({label: Nlabel1})
var NN2 = graph.newNode({label: Nlabel2})
nodeArray.push(NN1)
nodeArray.push(NN2)
graph.newEdge(NN1,NN2, {weight: .5})
}
console.log('NODE ARRAY')
console.log(nodeArray)
console.log('WINDOW')
jQuery(function(){
var springy = window.springy = jQuery('#springydemo').springy({
graph: graph,
nodeSelected: function(node){
console.log('Node selected: ' + JSON.stringify(node.data));
}
});
});
});
});
</script>
<div>
<canvas id="springydemo" width="800" height="400" style="border: 1px solid black;"></canvas>
</div>
</body>
</html>

At minimum, I would think you'd want to initialize nodeArray outside of the loop:
var nodeArray = []
for ( i = 0 ; i < graphP.elements.nodes.length ; i++ ) {
As is, the re-initialization in each loop would explain the length of 1.

I apparently got so focused on other problems that I didn't see that I was initializing my array inside the loop. Genius. However, for reference, here is how I was able to pass the sourceNode and targetNode objects to the newEdge function.
<html>
<head>
<title>Springy.js image node demo</title>
</head>
<body>
<script src="jquery-1.11.3.js"></script>
<script src="springy.js"></script>
<script src="springyui.js"></script>
<!--<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>-->
<script/>
$(document).ready(function(){
$.ajax({
url: 'https://rawgit.com/theresajbecker/CompBio/master/SuperSmallNodes.json',
type: 'GET',
dataType: 'json'
}).done(function(graphP) {
console.log(graphP);
var graph = new Springy.Graph();
var nodeArray = []
for ( i = 0 ; i < graphP.elements.nodes.length ; i++ ) {
var Nlabel1 = graphP.elements.nodes[i].data.label
var Nmass = graphP.elements.nodes[i].data.mass
var NN1 = graph.newNode({label: Nlabel1}, {'text-outline-width': Nmass});
nodeArray.push(NN1)
}
console.log(nodeArray)
function getByValue(arr, value) {
for (var n=0; n < nodeArray.length; n++) {
if (arr[n].data.label == value) {
console.log("below should be the object of element")
return arr[n];
}
}
}
function getSourceNode(graphP) {
for (var s=0; s < graphP.elements.edges.length; s++) {
var getSource = graphP.elements.edges[s].data.source
var getTarget = graphP.elements.edges[s].data.target
graph.newEdge(getByValue(nodeArray, getSource),getByValue(nodeArray, getTarget));
}
}
getSourceNode(graphP)
console.log('WINDOW')
jQuery(function(){
var springy = window.springy = jQuery('#springydemo').springy({
graph: graph,
nodeSelected: function(node){
console.log('Node selected: ' + JSON.stringify(node.data));
}
});
});
});
});
</script>
<div>
<canvas id="springydemo" width="800" height="400" style="border: 1px solid black;"></canvas>
</div>
</body>
</html>

Related

Plotly js live update from online data

I would like my Plotly graph to update automatically every 1 seconds by reading data from an online CSV file.
This is what I have so far:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="graph"></div>
<script>
function read_data() {
d3.csv(
"https://docs.google.com/spreadsheets/d/e/2PACX-1vTkbRgvvBwM0tMheEziQC4ldtYoMVCgIek67Y5Lcjnu1WH0tTLLCzJPse-pL5OTR9U58Gk8VBD65L3u/pub?gid=0&single=true&output=csv",
function (data) {
processData(data);
}
);
}
function processData(allRows) {
console.log(allRows);
var x = [];
var y = [];
for (var i = 0; i < allRows.length; i++) {
row = allRows[i];
x.push(row["x"]);
y.push(row["y"]);
}
console.log("Y", y);
return y;
}
Plotly.newPlot(graph, [
{
y: [1, 2, 3],
mode: "lines",
line: { color: "#80CAF6" },
},
]);
var interval = setInterval(function () {
Plotly.restyle(
graph,
{
y: [[read_data()]],
},
[0]
);
}, 1000);
</script>
</body>
</html>
Although the y data is printed in the console, the plot is not updated.
My script is based on these two tutorials:
Streaming in JavaScript
Read CSV Data from an Ajax Call in JavaScript
Additional question: is there a way to automatically update the graph each time the data is updated in the CSV document? That is, without having to loop over each second.
In your code, read_data() returns undefined. It also schedules processData() to run later, and that function returns some data, but it was called by the JavaScript runtime which ignores this returned value.
You could stick the Plotly.restyle(... code in a function that processData calls, or you could stick that code inside processData. See the code sample below.
However, there's another issue here (watch the code sample below fail). This file can't be loaded by a browser page right now. Google sheets links like
https://docs.google.com/spreadsheets/d/e/2PACX-1vTkbRgvvBwM0tMheEziQC4ldtYoMVCgIek67Y5Lcjnu1WH0tTLLCzJPse-pL5OTR9U58Gk8VBD65L3u/pub?gid=0&single=true&output=csv no longer work in the browser as of about 18 months ago.
You'll need to use another method to get your data into a web page (see linked questions above for some suggestions).
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="graph"></div>
<script>
function read_data() {
d3.csv(
"https://docs.google.com/spreadsheets/d/e/2PACX-1vTkbRgvvBwM0tMheEziQC4ldtYoMVCgIek67Y5Lcjnu1WH0tTLLCzJPse-pL5OTR9U58Gk8VBD65L3u/pub?gid=0&single=true&output=csv",
function (data) {
processData(data);
}
);
}
function processData(allRows) {
console.log(allRows);
var x = [];
var y = [];
for (var i = 0; i < allRows.length; i++) {
row = allRows[i];
x.push(row["x"]);
y.push(row["y"]);
}
console.log("Y", y);
Plotly.restyle(
graph,
{
y: y,
},
[0]
);
}
Plotly.newPlot(graph, [
{
y: [1, 2, 3],
mode: "lines",
line: { color: "#80CAF6" },
},
]);
var interval = setInterval(read_data, 1000);
</script>
</body>
</html>

How to transfer something(i.e variable) from a JavaScript file to a HTML file?

I'm trying to code a web-page that will display a pie-chart with results but the code for my pie-chart is in a HTML file (read_data.html) and the figures I would like to use for the pie-chart are in a JavaScript file (read_data.js)
The figures I want are stored in 4 variables - Booth1,Booth2,Booth3,Booth4
How could I go about transferring these variables to my HTML file?
Here is the code for the pie-chart in the HTML file
<!DOCTYPE html>
<html lang="en-US">
<body>
<h1>My Web Page</h1>
<div id="piechart"></div>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
// Load google charts
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart);
// Draw the chart and set the chart values
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Students', 'Votes'],
['Canidate1', Booth1],
['Canidate2', Booth2],
['Canidate3', Booth3],
['Canidate4', Booth4],
]);
// Optional; add a title and set the width and height of the chart
var options = {'title':'Election Results', 'width':550, 'height':400};
// Display the chart inside the <div> element with id="piechart"
var chart = new google.visualization.PieChart(document.getElementById('piechart'));
chart.draw(data, options);
}
</script>
</body>
</html>
Here is the code in the JavaScript file
// Lists to hold the well being states and their corresponding times
var myVotes = [];
var myTimes = [];
// Variables to hold the count for each state
var Booth1 = 0;
var Booth2 = 0;
var Booth3 = 0;
var Booth4 = 0;
// Define database connection to correct child branch, ElectionResults
var myDBConn = firebase.database().ref("ElectionResults");
// Function that acts when a 'new child is added to the DB' - i.e. new data is added this function runs.
myDBConn.on("child_added", function(data, prevChildKey) {
Booth1 = 0;
Booth2 = 0;
Booth3 = 0;
Booth4 = 0;
// The data returned from the branch is put into a variable, dataPoint
var dataPoint = data.val();
// Populate the lists with the various data from the database
myVotes.push(dataPoint.ElectionResults);
myTimes.push(dataPoint.Time);
// Loop each returned state and add 1 to the appropriate counter
for (i = 0; i < myVotes.length; i++) {
if (myVotes[i] == "Canidate1") {
Booth1 = Booth1 + 1;
}
if (myVotes[i] == "Canidate2") {
Booth2 = Booth2 + 1;
}
if (myVotes[i] == "Canidate3") {
Booth3 = Booth3 + 1;
}
if (myVotes[i] == "Canidate4") {
Booth4 = Booth4 + 1;
}
}
// Update the page elements with the average and the last item (most rescent) off the list
document.getElementById("TimeID").innerHTML = myTimes[myTimes.length - 1];
// Update the page elements with the results of each count
document.getElementById("Booth1").innerHTML = Booth1;
document.getElementById("Booth2").innerHTML = Booth2;
document.getElementById("Booth3").innerHTML = Booth3;
document.getElementById("Booth4").innerHTML = Booth4;
});
I think that you can just include the JS file into the HTML file by useing the <script /> tag;
<script type="something" src="read_data.js"></script>
With this tag you inculded the file and can use the variables by opening another script tag;
<script>
//import variables here
</script>

D3 collapsible trees without flare.json

I am trying to integrate a collapsible tree with a visualization tool :
http://bl.ocks.org/robschmuecker/7880033
Can someone please tell me how to make this code run without a flare.json file. I have the data in json format and I need to use that json output to make this code run. The code I have that converts a string into a json format is as follows:
<html>
<body>
<script>
//example dat
var str = "Charles Johnson\t4184\nCharles Johnson-Donald Williams\t8385\nCharles Johnson-Donald Williams-Daniel Fertig\t428\nCharles Johnson-Donald Williams-Daniel Fertig-Lino Walling\t1091\nCharles Johnson-Donald Williams-Daniel Fertig-Lino Walling-Jim Cooke\t318";
var lines = str.split("\n");
var name_ = lines[0].split("\t")[0];
var val_ = lines[0].split("\t")[1];
//alert(val_);
var obj = {name: name_,
children: [],
value: val_};
//process all lines
for (var i=1;i<lines.length;i++) {
var addr = lines[i].split("\t")[0].split("-");
var val = lines[i].split("\t")[1];
//alert(val);
var local_obj = obj;
var recursive_obj;
//alert(addr.length);
for (var j=1;j<addr.length;j++) {
recursive_obj = null;
for (var k=0;k<local_obj.children.length;k++) { //Doest get used for first instance
if (local_obj.children[k].name==addr[j]) {
recursive_obj=local_obj.children[k];
}
}
if (recursive_obj==null) {
recursive_obj = {name: addr[j],
children: [],
value: null
};
local_obj.children.push(recursive_obj);
}
local_obj=recursive_obj;
}
recursive_obj.value=val;
}
//print a json result
alert(JSON.stringify(obj));
</script>
</body>
</html>
This code converts the string into Json Format. Can someone please help me out in using this code instead of
treeJSON = d3.json("flare.json", function(error, treeData){}
and making the collapsible tree run. I would be very grateful if someone can assist me with this. Thank you :)
Best Regards
Mohd
<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="try.js"></script>
<body>
<div id="tree-container"></div>
</body>
</html>
Right now you have obj, which is already an object, similar to what treeData needs to be inside the callback to the d3.json function. You can take everything out of that function, converting from this:
d3.json("flare.json", function(error, treeData){
//Do some stuff with treeData
})
to this:
var treeData = obj;
//Do some stuff with treeData;
Working fiddle: fiddle

Modifying street view code, cannot substitute variable as argument

edit1= clearifying sample code
edit2= well this is getting embarassing, now I will post the actual code
I am trying to make a custom interior streetview. I am attempting to convert custom interior shot to be relative to arbitrary starting position by substituting the argument of the function below with variable, but would break the streetview. I am not familiar with javascript.
description:"TEST TEST TEST TSET",latLng:new google.maps.LatLng(54.156654,69.696969)
runs fine.
var demolat = 34.995348; // declared at beginning of function
var demolon = 135.7395;
var wlat = demolat;
var wlon = demolon;
.. lots of code .. // lots of code goes here
description:"TEST TEST TEST TSET",latLng:new google.maps.LatLng(wlat,wlon)
does not work.
full code
the script would not work properly when replaced line described above.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=utf-8"/>
<script src="http://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry" type="text/javascript"></script>
<script type="text/javascript" code="maps_code">
var initPosPanoID,initPosPanoData,streetView,map_canvas;
function initialize(){
var neeclat = 35.564157;
var neeclon = 139.714947;
//var demolat = 34.995138;
//var demolon = 135.739689;
var demolat = 34.995348;
var demolon = 135.7395;
var wlat = demolat;
var wlon = demolon;
swbound = new google.maps.LatLng(wlat-0.0003,wlon-0.0003);
nebound = new google.maps.LatLng(wlat+0.0003,wlon+0.0003);
var initPos=new google.maps.LatLng(wlat,wlon);
var mapOptions={zoom:14,center:initPos,mapTypeId:google.maps.MapTypeId.ROADMAP};
var mapDiv=document.getElementById("map_canvas");
map_canvas=new google.maps.Map(mapDiv,mapOptions);
var bounds=new google.maps.LatLngBounds(swbound,nebound);
var overlay=new google.maps.GroundOverlay("./5Bc3IIj.jpg",bounds);
overlay.setMap(map_canvas);
var streetViewOptions={pov:{zoom:1,heading:161,pitch:-2.6}};
var streetViewDiv=document.getElementById('streetview_canvas');
streetViewDiv.style.fontSize="15px";
streetView=new google.maps.StreetViewPanorama(streetViewDiv,streetViewOptions);
streetView.controls[google.maps.ControlPosition.RIGHT_BOTTOM].push(mapDiv);
google.maps.event.trigger(map_canvas,"resize");
map_canvas.setStreetView(streetView);
streetView.registerPanoProvider(getCustomPanorama);
var streetViewInitPos=new google.maps.LatLng(wlat,wlon);
// var streetViewInitPos=new google.maps.LatLng(34.995348,135.7395);
var streetviewService=new google.maps.StreetViewService();
var radius=50;
streetviewService.getPanoramaByLocation(streetViewInitPos,radius,function(result,status){
if(status==google.maps.StreetViewStatus.OK){
initPosPanoID=result.location.pano;
initPosPanoData=result;
streetView.setPosition(result.location.latLng);
map_canvas.panTo(result.location.latLng);
}
}
);
google.maps.event.addListener(streetView,"links_changed",createCustomLink);
var map_marker=new google.maps.Marker({map:map_canvas});
google.maps.event.addListener(streetView,"position_changed",function(){
var position=this.getPosition();
var map_bounds=map_canvas.getBounds();
map_canvas.panTo(position);
});
}
function getCustomPanoramaTileUrl(panoID,zoom,tileX,tileY){
return"./"+panoID+'/'+tileX+'-'+tileY+'_s1.jpg';
}
function getCustomPanorama(panoID){
var streetViewPanoramaData={
links:[],copyright:'',tiles:{
tileSize:new google.maps.Size(2048,1024),worldSize:new google.maps.Size(2048,1024),centerHeading:0,getTileUrl:getCustomPanoramaTileUrl
}
};
switch(panoID){
case initPosPanoID:
return initPosPanoData;
case"Position_S":
//var tmp = new google.maps.LatLng(wlat,wlon);
streetViewPanoramaData["location"]={
description:"TEST TEST TEST TSET",latLng:new google.maps.LatLng(3,3)
};
streetViewPanoramaData["copyright"]=""
break;
case"Position_SW":
streetViewPanoramaData["location"]={
description:"TEST TEST TEST TSET",latLng:new google.maps.LatLng(3,3)
};
streetViewPanoramaData["copyright"]=""
break;
}
if("location"in streetViewPanoramaData){
streetViewPanoramaData.location.pano=panoID;
return streetViewPanoramaData;
}
}
function createCustomLink(){
var links=streetView.getLinks();
var panoID=streetView.getPano();
var currentPos=streetView.getPosition();
switch(panoID){
case initPosPanoID:
links.push({description:"テストエリアへ",pano:"Position_S"});
break;
case"Position_S":
links.push({description:"外へ",pano:initPosPanoID});
links.push({description:"SWへ",pano:"Position_SW"});
break;
case"Position_SW":
links.push({description:"Sへ",pano:"Position_S"});
break;
}
if(links.length){ //compute directional pointer label.
var linkPano;
for(var i=0;i<links.length;i++){
linkPano=getCustomPanorama(links[i].pano);
if(linkPano!==undefined){
links[i].heading=google.maps.geometry.spherical.computeHeading(currentPos,linkPano.location.latLng);
}
}
return links;
}
}
google.maps.event.addDomListener(window,'load',initialize);
</script>
<style type="text/css">html,body{width:100%;
height:100%;
margin:0;
position:absolute}#frame,#streetview_canvas{width:100%;
height:100%;
position:relative}#map_canvas{width:250px;
height:250px;
border:2px solid gray;
background-color:#fff}</style>
</head>
<body>
<div id="streetview_canvas"></div>
<div id="map_canvas"></div>
</body>
</html>

Simple Javascript not working in IE, works in Firefox

The following is a simple piece of code to have javascript open up a soundcloud audio player in a pop-up window. It works perfectly in firefox and chrome, but doesn't work in IE7; it just shows a blank black screen. Does anyone know why?
I get the yellow drop down that says "to help protect.. IE has restricted this webpage from running scripts or ActiveX controls...." Even when I click on it and say allow, the soundcloud player still doesn't appear.
<HTML>
<HEAD>
<script type='text/javascript'>
function fetchArguments() {
var arg = window.location.href.split("?")[1].split("&"); // arguments
var len = arg.length; // length of arguments
var obj = {}; // object that maps argument id to argument value
var i; // iterator
var arr; // array
for (var i = 0; i < len; i++) {
arr = arg[i].split("="); // split the argument
obj[arr[0]] = arr[1]; // e.g. obj["song"] = "3"
}
return obj;
}
function loadTitle() {
var args = fetchArguments();
document.title = "Audio: Accidential Seabirds - " + args["name"];
}
function loadMusic() {
var args = fetchArguments();
var height = "100";
object = document.createElement("object");
object.height = height;
object.width = "100%";
nameParam = document.createElement("param");
nameParam.name="movie";
nameParam.value ="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F" + args["song"];
scriptParam = document.createElement("param");
scriptParam.name="allowscriptaccess";
scriptParam.value="always";
embedTag = document.createElement("embed");
embedTag.allowscriptaccess="always";
embedTag.height= height;
embedTag.src="http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F" + args["song"];
embedTag.type="application/x-shockwave-flash";
embedTag.width="100%";
object.appendChild(nameParam);
object.appendChild(scriptParam);
object.appendChild(embedTag);
document.getElementsByTagName("body")[0].appendChild(object); // we append the iframe to the document's body
window.innerHeight=100;
window.innerWidth=600;
self.focus();
}
</script>
<script type='text/javascript'>
loadTitle();
</script>
</HEAD>
<BODY bgcolor="#000000" topmargin="0" marginheight="0" leftmargin="0" marginwidth="0">
<center>
<script type='text/javascript'>
loadMusic();
</script>
</center>
</BODY>
</HTML>
The code to call this window might be
function PopupMusic(song, name) {
var ptr = window.open("musicplayer.htm?song="+song+"&name='"+name+"'", song, "resizable='false', HEIGHT=90,WIDTH=600");
if(ptr) ptr.focus();
return false;
}
Listen
I figured it out. You need to use the setAttributeFunction:
function loadVideo() {
var args = fetchArguments();
var videoFrame = document.createElement("iframe");
videoFrame.setAttribute('id', 'videoFrame');
videoFrame.setAttribute('title', 'YouTube video player');
videoFrame.setAttribute('class', 'youtube-player');
videoFrame.setAttribute('type', 'text/html');
videoFrame.setAttribute('width', args["width"]);
videoFrame.setAttribute('height', args["height"]);
videoFrame.setAttribute('src', 'http://www.youtube.com/embed/' + args["vid"]);
videoFrame.setAttribute('frameborder', '0');
videoFrame.allowFullScreen;
document.getElementsByTagName("body")[0].appendChild(videoFrame); // we append the iframe to the document's body
self.focus();
}
Following code works fine in IE/FF/Chrome:
<script type='text/javascript'>
var musicSrc = 'http://player.soundcloud.com/player.swf?url=http%3A%2F%2Fsoundcloud.com%2Frjchevalier%2Fjust-one-day-ft-deni-hlavinka&color=3b5998&auto_play=true&show_artwork=false';
document.write('<object type="application/x-shockwave-flash" width="100%" height="100%" data="'+musicSrc+'"><param name="movie" value="'+musicSrc+'" /></object>');
</script>

Categories

Resources