DimpleJS chart with multiple series - dimple.js

I'm trying to draw a chart with multiple lines, but as not every series on it has the same time coordinates, one of the lines is drawn scattered, with points not connected.
You can see what I'm trying to explain here: My chart
When dates changes using the provided slider, the 'Previsiones' input or even clicking over the lines, you can see how lines redraw.
And here's the data I'm using:
[{ "Fecha": "01-Jan-14","Dato": 13.53,"Tipo": "Previsión"},
{ "Fecha": "01-Feb-14","Dato": 13.49,"Tipo": "Previsión"},
{ "Fecha": "01-Mar-14","Dato": 13.77,"Tipo": "Previsión"},
{ "Fecha": "01-Apr-14","Dato": 13.93,"Tipo": "Previsión"},
{ "Fecha": "01-May-14","Dato": 13.94,"Tipo": "Previsión"},
{ "Fecha": "01-Jun-14","Dato": 14.09,"Tipo": "Previsión"},
{ "Fecha": "01-Jan-14","Dato": 13.53,"Tipo": "Dato Observado (futuro)"},
{ "Fecha": "01-Nov-10","Dato": 5.68,"Tipo": "Dato Observado"},
{ "Fecha": "01-Dec-10","Dato": 5.81,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jan-11","Dato": 6.06,"Tipo": "Dato Observado"},
{ "Fecha": "01-Feb-11","Dato": 6.19,"Tipo": "Dato Observado"},
{ "Fecha": "01-Mar-11","Dato": 6.11,"Tipo": "Dato Observado"},
{ "Fecha": "01-Apr-11","Dato": 6.36,"Tipo": "Dato Observado"},
{ "Fecha": "01-May-11","Dato": 6.49,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jun-11","Dato": 6.69,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jul-11","Dato": 6.94,"Tipo": "Dato Observado"},
{ "Fecha": "01-Aug-11","Dato": 7.15,"Tipo": "Dato Observado"},
{ "Fecha": "01-Sep-11","Dato": 7.16,"Tipo": "Dato Observado"},
{ "Fecha": "01-Oct-11","Dato": 7.42,"Tipo": "Dato Observado"},
{ "Fecha": "01-Nov-11","Dato": 7.51,"Tipo": "Dato Observado"},
{ "Fecha": "01-Dec-11","Dato": 7.61,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jan-12","Dato": 7.91,"Tipo": "Dato Observado"},
{ "Fecha": "01-Feb-12","Dato": 8.27,"Tipo": "Dato Observado"},
{ "Fecha": "01-Mar-12","Dato": 8.37,"Tipo": "Dato Observado"},
{ "Fecha": "01-Apr-12","Dato": 8.72,"Tipo": "Dato Observado"},
{ "Fecha": "01-May-12","Dato": 8.96,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jun-12","Dato": 9.65,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jul-12","Dato": 9.86,"Tipo": "Dato Observado"},
{ "Fecha": "01-Aug-12","Dato": 10.51,"Tipo": "Dato Observado"},
{ "Fecha": "01-Sep-12","Dato": 10.71,"Tipo": "Dato Observado"},
{ "Fecha": "01-Oct-12","Dato": 11.23,"Tipo": "Dato Observado"},
{ "Fecha": "01-Nov-12","Dato": 11.38,"Tipo": "Dato Observado"},
{ "Fecha": "01-Dec-12","Dato": 10.44,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jan-13","Dato": 10.78,"Tipo": "Dato Observado"},
{ "Fecha": "01-Feb-13","Dato": 10.4,"Tipo": "Dato Observado"},
{ "Fecha": "01-Mar-13","Dato": 10.47,"Tipo": "Dato Observado"},
{ "Fecha": "01-Apr-13","Dato": 10.88,"Tipo": "Dato Observado"},
{ "Fecha": "01-May-13","Dato": 11.22,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jun-13","Dato": 11.63,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jul-13","Dato": 11.98,"Tipo": "Dato Observado"},
{ "Fecha": "01-Aug-13","Dato": 12.14,"Tipo": "Dato Observado"},
{ "Fecha": "01-Sep-13","Dato": 12.67,"Tipo": "Dato Observado"},
{ "Fecha": "01-Oct-13","Dato": 13,"Tipo": "Dato Observado"},
{ "Fecha": "01-Nov-13","Dato": 13.07,"Tipo": "Dato Observado"},
{ "Fecha": "01-Dec-13","Dato": 13.61,"Tipo": "Dato Observado"},
{ "Fecha": "01-Jan-14","Dato": 13.53,"Tipo": "Dato Observado"}]
What am I doing wrong?
Edit: This is a better dataset to understand the problem. Basically is any date presentation in between first and last.
[{ "Fecha" : "01-Dec-12", "Dato" : 10.44, "tipo" : "Previsión" },
{ "Fecha" : "01-Jan-13", "Dato" : 10.21, "tipo" : "Previsión" },
{ "Fecha" : "01-Feb-13", "Dato" : 10.16, "tipo" : "Previsión" },
{ "Fecha" : "01-Mar-13", "Dato" : 9.57, "tipo" : "Previsión" },
{ "Fecha" : "01-Apr-13", "Dato" : 9.53, "tipo" : "Previsión" },
{ "Fecha" : "01-May-13", "Dato" : 9.5, "tipo" : "Previsión" },
{ "Fecha" : "01-Dec-12", "Dato" : 10.44, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Jan-13", "Dato" : 10.78, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Feb-13", "Dato" : 10.4, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Mar-13", "Dato" : 10.47, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Apr-13", "Dato" : 10.88, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-May-13", "Dato" : 11.22, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Jun-13", "Dato" : 11.63, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Jul-13", "Dato" : 11.98, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Aug-13", "Dato" : 12.14, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Sep-13", "Dato" : 12.67, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Oct-13", "Dato" : 13, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Nov-13", "Dato" : 13.07, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Dec-13", "Dato" : 13.61, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Jan-14", "Dato" : 13.53, "tipo" : "Dato Observado (futuro)"},
{ "Fecha" : "01-Nov-10", "Dato" : 5.68, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Dec-10", "Dato" : 5.81, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Jan-11", "Dato" : 6.06, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Feb-11", "Dato" : 6.19, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Mar-11", "Dato" : 6.11, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Apr-11", "Dato" : 6.36, "tipo" : "Dato Observado"},
{ "Fecha" : "01-May-11", "Dato" : 6.49, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Jun-11", "Dato" : 6.69, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Jul-11", "Dato" : 6.94, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Aug-11", "Dato" : 7.15, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Sep-11", "Dato" : 7.16, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Oct-11", "Dato" : 7.42, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Nov-11", "Dato" : 7.51, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Dec-11", "Dato" : 7.61, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Jan-12", "Dato" : 7.91, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Feb-12", "Dato" : 8.27, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Mar-12", "Dato" : 8.37, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Apr-12", "Dato" : 8.72, "tipo" : "Dato Observado"},
{ "Fecha" : "01-May-12", "Dato" : 8.96, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Jun-12", "Dato" : 9.65, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Jul-12", "Dato" : 9.86, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Aug-12", "Dato" : 10.51, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Sep-12", "Dato" : 10.71, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Oct-12", "Dato" : 11.23, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Nov-12", "Dato" : 11.38, "tipo" : "Dato Observado"},
{ "Fecha" : "01-Dec-12", "Dato" : 10.44, "tipo" : "Dato Observado"}]

Nice graphic! If I understand correctly your issue is with the missing connecting line in some charts. I think this is a bug with the line re-drawing in dimple. I suggest you clear and redraw the chart every time, it should render quick enough to not be a problem. I've recreated your chart in a fiddle here and it seems to render fine:
Example in question: http://jsfiddle.net/T6ZDL/6/
Having said that, that example seems ok in your original page. Do you have a dataset for one of the views which fails.

Related

Is there a edge weighted spring embedded layout in cytoscape.js?

We have a requirement to show nodes and edges graph in our Angular application and we chose to do it in cytoscape over high charts/amCharts/D3. Cytoscape is faster in loading and is the only library to handle 1000s of nodes that we have. Others break or lags.
We downloaded cytoscape app and were able to see a layout 'Edge weighted spring embedded'. It shows our interconnected nodes in a overall globe-like layout.
Now I want the same in cytoscape js and looks like we only have handful of layouts in https://js.cytoscape.org/
Does this layout possible in cytoscape js? How to achieve this? (Currently using fcose layout but we really like the globe look that 'Edge weighted spring embedded layout brings.
EDIT:
Here is another example: I want to achieve this layout in cytoscape.js.
What layout I should follow? Or is this something not available in js and only available in desktop App
There are three options I think:
The Compound Spring Embedder layout cose
The Compound Spring Embedder layout by Bilkent (for an enhanced compound node placement) cose-bilkent
The Constraint-Based Layout cola.js
They all use some sort of force directed layout, I think you should give them a try and use the one most fitting to your needs. There are many parameters you can set for each layout, so take a closer look at them too. For example, if you set infinite to true in the cola.js layout, you will see that you can move the nodes around and see the layout force them back to or to a fitting position:
document.addEventListener("DOMContentLoaded", function() {
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
autounselectify: true,
boxSelectionEnabled: false,
layout: {
name: "cola",
infinite: true,
fit: false
},
style: [{
selector: "node",
css: {
"background-color": "#f92411"
}
},
{
selector: "edge",
css: {
"line-color": "#f92411"
}
}
],
elements: {
nodes: [{
data: {
id: "1",
label: "P"
}
},
{
data: {
id: "2",
label: "sucrose phosphate phosphatase"
}
},
{
data: {
id: "4",
label: "sucrose 6-phosphate"
}
},
{
data: {
id: "6",
label: "sucrose"
}
},
{
data: {
id: "8",
label: "invertase"
}
},
{
data: {
id: "10",
label: "fructose"
}
},
{
data: {
id: "12",
label: "fructokinase"
}
},
{
data: {
id: "14",
label: "fructose 6-phosphate"
}
},
{
data: {
id: "20",
label: "phosphoglucose isomerase"
}
},
{
data: {
id: "22",
label: "glucose 6-phosphate"
}
},
{
data: {
id: "28",
label: "glucose"
}
},
{
data: {
id: "30",
label: "hexokinase"
}
},
{
data: {
id: "33",
label: "sucrose synthase"
}
},
{
data: {
id: "36",
label: "UDP - glucose"
}
},
{
data: {
id: "38",
label: "sucrose phosphate synthase"
}
},
{
data: {
id: "41",
label: "UDP"
}
},
{
data: {
id: "44",
label: "fructose 6-phosphate"
}
},
{
data: {
id: "46",
label: "ATP"
}
},
{
data: {
id: "47",
label: "ATP"
}
},
{
data: {
id: "52",
label: "ATP"
}
},
{
data: {
id: "57",
label: "ADP"
}
},
{
data: {
id: "66",
label: "PP"
}
},
{
data: {
id: "71",
label: "UTP"
}
},
{
data: {
id: "76",
label: "UDP glucose pyrophosphorylase"
}
},
{
data: {
id: "80",
label: "glucose 1-phosphate"
}
},
{
data: {
id: "86",
label: "phospho- glucomutase (cPGM)"
}
},
{
data: {
id: "89",
label: "G1P transporter"
}
},
{
data: {
id: "90",
label: "P"
}
},
{
data: {
id: "95",
label: "P"
}
},
{
data: {
id: "102",
label: "P"
}
},
{
data: {
id: "103",
label: "P"
}
},
{
data: {
id: "104",
label: "G6P transporter"
}
},
{
data: {
id: "109",
label: "glucose 6-phosphate"
}
},
{
data: {
id: "115",
label: "phospho- glucomutase (cPGM)"
}
},
{
data: {
id: "121",
label: "glucose 1-phosphate"
}
},
{
data: {
id: "128",
label: "ADPglucose pyrophosphorylase (pAGPase)"
}
},
{
data: {
id: "130",
label: "ADP - glucose"
}
},
{
data: {
id: "136",
label: "PP"
}
},
{
data: {
id: "141",
label: "ATP"
}
},
{
data: {
id: "148",
label: "inorganic diphosphatase"
}
},
{
data: {
id: "149",
label: "P"
}
},
{
data: {
id: "156",
label: "phosphate transporter"
}
},
{
data: {
id: "158",
label: "P"
}
},
{
data: {
id: "164",
label: "starch synthase (simpl.)"
}
},
{
data: {
id: "166",
label: "ADP"
}
},
{
data: {
id: "172",
label: "starch"
}
},
{
data: {
id: "178",
label: "ATP/ADP transporter"
}
},
{
data: {
id: "179",
label: "ADP"
}
},
{
data: {
id: "184",
label: "ADP"
}
},
{
data: {
id: "189",
label: "ATP"
}
}
],
edges: [{
data: {
source: "2",
target: "1"
}
},
{
data: {
source: "4",
target: "2"
}
},
{
data: {
source: "2",
target: "6"
}
},
{
data: {
source: "6",
target: "8"
}
},
{
data: {
source: "8",
target: "10"
}
},
{
data: {
source: "12",
target: "14"
}
},
{
data: {
source: "14",
target: "20"
}
},
{
data: {
source: "20",
target: "22"
}
},
{
data: {
source: "8",
target: "28"
}
},
{
data: {
source: "28",
target: "30"
}
},
{
data: {
source: "30",
target: "22"
}
},
{
data: {
source: "6",
target: "33"
}
},
{
data: {
source: "33",
target: "10"
}
},
{
data: {
source: "33",
target: "36"
}
},
{
data: {
source: "36",
target: "38"
}
},
{
data: {
source: "38",
target: "4"
}
},
{
data: {
source: "38",
target: "41"
}
},
{
data: {
source: "41",
target: "33"
}
},
{
data: {
source: "44",
target: "38"
}
},
{
data: {
source: "52",
target: "12"
}
},
{
data: {
source: "12",
target: "57"
}
},
{
data: {
source: "46",
target: "30"
}
},
{
data: {
source: "30",
target: "47"
}
},
{
data: {
source: "71",
target: "76"
}
},
{
data: {
source: "76",
target: "66"
}
},
{
data: {
source: "76",
target: "36"
}
},
{
data: {
source: "80",
target: "76"
}
},
{
data: {
source: "22",
target: "86"
}
},
{
data: {
source: "86",
target: "80"
}
},
{
data: {
source: "95",
target: "89"
}
},
{
data: {
source: "89",
target: "90"
}
},
{
data: {
source: "102",
target: "104"
}
},
{
data: {
source: "80",
target: "89"
}
},
{
data: {
source: "104",
target: "109"
}
},
{
data: {
source: "115",
target: "109"
}
},
{
data: {
source: "121",
target: "89"
}
},
{
data: {
source: "121",
target: "115"
}
},
{
data: {
source: "121",
target: "128"
}
},
{
data: {
source: "128",
target: "130"
}
},
{
data: {
source: "141",
target: "128"
}
},
{
data: {
source: "128",
target: "136"
}
},
{
data: {
source: "136",
target: "148"
}
},
{
data: {
source: "148",
target: "149"
}
},
{
data: {
source: "149",
target: "156"
}
},
{
data: {
source: "156",
target: "158"
}
},
{
data: {
source: "130",
target: "164"
}
},
{
data: {
source: "164",
target: "166"
}
},
{
data: {
source: "178",
target: "179"
}
},
{
data: {
source: "184",
target: "178"
}
},
{
data: {
source: "178",
target: "189"
}
},
{
data: {
source: "141",
target: "178"
}
},
{
data: {
source: "104",
target: "103"
}
},
{
data: {
source: "10",
target: "12"
}
},
{
data: {
source: "164",
target: "172"
}
},
{
data: {
source: "22",
target: "104"
}
}
]
}
}));
cy.unbind("tapend");
cy.bind("tapend", "node", function() {
cy.animate({
fit: {
eles: cy.elements(),
padding: 20
},
center: {
eles: cy.elements()
}
}, {
duration: 500
});
});
});
body {
font-family: helvetica;
font-size: 14px;
}
#cy {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
}
<!DOCTYPE>
<html>
<head>
<title>cytoscape-cola.js demo</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<!-- for testing with local version of cytoscape.js -->
<!--<script src="../cytoscape.js/build/cytoscape.js"></script>-->
<script src="https://unpkg.com/webcola/WebCola/cola.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-cola#2.3.0/cytoscape-cola.min.js"></script>
</head>
<body>
<h1>cytoscape-cola demo</h1>
<div id="cy"></div>
</body>
</html>
You can try "Euler" layout, it might give the same expected layout that you wanted. It is euler.js. I am using this layout for my own data set and is giving similar layout that you have shown above.

ARCore Sceneform SDK linking materials Error?

I just have a simple table model has a 3 segments Top,Brick,Bottom. I applied Normal maps to the bottom part and it was successful but when i tried to apply normal map for the Brick and Top part it says, duplicate field name. I can figure it out what error it says. I was doing what says in this documentation. https://developers.google.com/sceneform/develop/sfa
{
animations: [
{
path: 'sampledata/models/sculpting-table/source/SculptingTable.fbx',
},
],
materials: [
{
name: 'TableTop',
parameters: [
{
baseColor: [
1,
1,
1,
1,
],
},
{
baseColorMap: 'SculptingTable_TableTop_AlbedoTransparency',
},
{
normalMap: null,
},
{
interpolatedColor: null,
},
{
metallic: 0,
},
{
metallicMap: null,
},
{
roughness: 1,
},
{
roughnessMap: null,
},
{
opacity: null,
},
],
source: 'build/sceneform_sdk/default_materials/fbx_material.sfm',
},
{
name: 'TableBottom',
parameters: [
{
baseColor: [
1,
1,
1,
1,
],
},
{
baseColorMap: 'SculptingTable_TableBottom_AlbedoTranspare',
},
{
normalMap: 'bumps',
},
{
interpolatedColor: null,
},
{
metallic: 0,
},
{
metallicMap: null,
},
{
roughness: 1,
},
{
roughnessMap: null,
},
{
opacity: null,
},
],
source: 'build/sceneform_sdk/default_materials/fbx_material.sfm',
},
{
name: 'TableBricks',
parameters: [
{
baseColor: [
1,
1,
1,
1,
],
},
{
baseColorMap: 'SculptingTable_TableBricks_AlbedoTranspare',
},
{
normalMap: null,
},
{
interpolatedColor: null,
},
{
metallic: 0,
},
{
metallicMap: null,
},
{
roughness: 1,
},
{
roughnessMap: null,
},
{
opacity: null,
},
],
source: 'build/sceneform_sdk/default_materials/fbx_material.sfm',
},
],
model: {
attributes: [
'Position',
'TexCoord',
'Orientation',
'BoneIndices',
'BoneWeights',
],
collision: {},
file: 'sampledata/models/sculpting-table/source/SculptingTable.fbx',
name: 'SculptingTable',
recenter: 'root',
},
samplers: [
{
file: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableBricks_AlbedoTranspare.png',
name: 'SculptingTable_TableBricks_AlbedoTranspare',
pipeline_name: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableBricks_AlbedoTranspare.png',
},
{
file: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableBottom_AlbedoTranspare.png',
name: 'SculptingTable_TableBottom_AlbedoTranspare',
pipeline_name: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableBottom_AlbedoTranspare.png',
},
{
file: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableTop_AlbedoTransparency.png',
name: 'SculptingTable_TableTop_AlbedoTransparency',
pipeline_name: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableTop_AlbedoTransparency.png',
},
{
file: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableBottom_Normal.png',
name: 'bumps',
injections: [
{usage: "Normal",},
],
},
{
file: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableBricks_Normal.png',
name: 'bumpsBrick',
injections: [
{usage: "Normal",},
],
},
],
version: '0.54:2',
}
About is the SFA file of the model.
Validating Materials: Validating material: Jsonnet Error: [1]: RUNTIME ERROR: duplicate field name: "Normal"
This is the log error that appears.
I got the answer we needed to add material_name attribute inside the injection block too. This will get rid of the duplication of "Normal" keyword.
{
file: '/Users/vishweshwaran/Downloads/sculpting-table/textures/SculptingTable_TableBottom_Normal.png',
name: 'bumps',
injections: [
{
material_name:"name_of_your_material",
usage: "Normal",},
],
},

Elastic (animated) edges in graph with nodes exerting gravitational pull on neighbours?

Is there a layout extension for Cytoscape that enables a dynamic behavior similar to that of the Neo4j Browser, i.e. when you drag a node, its edges are elastic to some extend, but that also drag connected nodes along part of the way (I'd call it localized gravity)?
Update:
The example I'm working on uses the CoSE Bilkent (compound) layout extension, but it doesn't seem to support the effect/animation I'm after out of the box. I had hoped the scarcely documented { gravity: 1 } option might be related - after all, when a node pulls other nodes along, that could well be described as gravity - but changing the setting on a small sample graph had no such effect; some digging ensued and I now think that setting has to do with how close to the graph's center nodes are displayed. I then looked at all layout demos, none seem to display the effect I'm after out of the box. AllegroViva appears to implement similar behavior (video), but from my understanding, it's rendering a time series in that video (so might just be manually redrawing the graph). Their website seems to be disfunct, too.
What I'm looking for is something easy, ideally out of the box, or something that can be implemented quickly. Unfortunately, I'm not quite sure what the right search term would be for what I want (especially in Cytoscape's domain). Hence me asking what is admittedly a very high-level question. Today, I found out Visjs calls it physics events (or at least uses the effect I'm after as part of that demo) - but as I mentioned, gravity in Cytoscape is apparently not what I'm looking for. At this point, however, I'm merely trying to establish if Cytoscape is the right library, or whether I need to look at others, like Alchemy (cf. its Philosophers' Relatedness example).
Answer:
Thank you for editing the question, I think i can help you with this one. Cytoscape.js has this feature buried deep in the extension layouts, specifically in cytoscape.js-cola. The layout is a physics layout with "springy" like nodes, so that the distance between them stays the same. The catch here is, that in the paragraph Notes, the author describes this:
If you want to maintain interactivity, you probably should not mix infinite: true with fit: true. Fitting naturally changes the zoom level, making dragging misaligned and feel weird to users --- though it still works technically. Better to just fit: false when infinite: true, and cy.center() or cy.fit() on layoutready.
The alignment option isn't as flexible as the raw Cola option. Here, only integers can be used to specify relative positioning, so it's a bit limited. If you'd like to see a more sophisticated implementation, please send a pull request.
Code:
So this example should work (note that the nodes can be moved, but they tend to stay in formation because of their already optimal position):
document.addEventListener("DOMContentLoaded", function() {
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
autounselectify: true,
boxSelectionEnabled: false,
layout: {
name: "cola",
infinite: true,
fit: false
},
style: [{
selector: "node",
css: {
"background-color": "#f92411"
}
},
{
selector: "edge",
css: {
"line-color": "#f92411"
}
}
],
elements: {
nodes: [{
data: {
id: "1",
label: "P"
}
},
{
data: {
id: "2",
label: "sucrose phosphate phosphatase"
}
},
{
data: {
id: "4",
label: "sucrose 6-phosphate"
}
},
{
data: {
id: "6",
label: "sucrose"
}
},
{
data: {
id: "8",
label: "invertase"
}
},
{
data: {
id: "10",
label: "fructose"
}
},
{
data: {
id: "12",
label: "fructokinase"
}
},
{
data: {
id: "14",
label: "fructose 6-phosphate"
}
},
{
data: {
id: "20",
label: "phosphoglucose isomerase"
}
},
{
data: {
id: "22",
label: "glucose 6-phosphate"
}
},
{
data: {
id: "28",
label: "glucose"
}
},
{
data: {
id: "30",
label: "hexokinase"
}
},
{
data: {
id: "33",
label: "sucrose synthase"
}
},
{
data: {
id: "36",
label: "UDP - glucose"
}
},
{
data: {
id: "38",
label: "sucrose phosphate synthase"
}
},
{
data: {
id: "41",
label: "UDP"
}
},
{
data: {
id: "44",
label: "fructose 6-phosphate"
}
},
{
data: {
id: "46",
label: "ATP"
}
},
{
data: {
id: "47",
label: "ATP"
}
},
{
data: {
id: "52",
label: "ATP"
}
},
{
data: {
id: "57",
label: "ADP"
}
},
{
data: {
id: "66",
label: "PP"
}
},
{
data: {
id: "71",
label: "UTP"
}
},
{
data: {
id: "76",
label: "UDP glucose pyrophosphorylase"
}
},
{
data: {
id: "80",
label: "glucose 1-phosphate"
}
},
{
data: {
id: "86",
label: "phospho- glucomutase (cPGM)"
}
},
{
data: {
id: "89",
label: "G1P transporter"
}
},
{
data: {
id: "90",
label: "P"
}
},
{
data: {
id: "95",
label: "P"
}
},
{
data: {
id: "102",
label: "P"
}
},
{
data: {
id: "103",
label: "P"
}
},
{
data: {
id: "104",
label: "G6P transporter"
}
},
{
data: {
id: "109",
label: "glucose 6-phosphate"
}
},
{
data: {
id: "115",
label: "phospho- glucomutase (cPGM)"
}
},
{
data: {
id: "121",
label: "glucose 1-phosphate"
}
},
{
data: {
id: "128",
label: "ADPglucose pyrophosphorylase (pAGPase)"
}
},
{
data: {
id: "130",
label: "ADP - glucose"
}
},
{
data: {
id: "136",
label: "PP"
}
},
{
data: {
id: "141",
label: "ATP"
}
},
{
data: {
id: "148",
label: "inorganic diphosphatase"
}
},
{
data: {
id: "149",
label: "P"
}
},
{
data: {
id: "156",
label: "phosphate transporter"
}
},
{
data: {
id: "158",
label: "P"
}
},
{
data: {
id: "164",
label: "starch synthase (simpl.)"
}
},
{
data: {
id: "166",
label: "ADP"
}
},
{
data: {
id: "172",
label: "starch"
}
},
{
data: {
id: "178",
label: "ATP/ADP transporter"
}
},
{
data: {
id: "179",
label: "ADP"
}
},
{
data: {
id: "184",
label: "ADP"
}
},
{
data: {
id: "189",
label: "ATP"
}
}
],
edges: [{
data: {
source: "2",
target: "1"
}
},
{
data: {
source: "4",
target: "2"
}
},
{
data: {
source: "2",
target: "6"
}
},
{
data: {
source: "6",
target: "8"
}
},
{
data: {
source: "8",
target: "10"
}
},
{
data: {
source: "12",
target: "14"
}
},
{
data: {
source: "14",
target: "20"
}
},
{
data: {
source: "20",
target: "22"
}
},
{
data: {
source: "8",
target: "28"
}
},
{
data: {
source: "28",
target: "30"
}
},
{
data: {
source: "30",
target: "22"
}
},
{
data: {
source: "6",
target: "33"
}
},
{
data: {
source: "33",
target: "10"
}
},
{
data: {
source: "33",
target: "36"
}
},
{
data: {
source: "36",
target: "38"
}
},
{
data: {
source: "38",
target: "4"
}
},
{
data: {
source: "38",
target: "41"
}
},
{
data: {
source: "41",
target: "33"
}
},
{
data: {
source: "44",
target: "38"
}
},
{
data: {
source: "52",
target: "12"
}
},
{
data: {
source: "12",
target: "57"
}
},
{
data: {
source: "46",
target: "30"
}
},
{
data: {
source: "30",
target: "47"
}
},
{
data: {
source: "71",
target: "76"
}
},
{
data: {
source: "76",
target: "66"
}
},
{
data: {
source: "76",
target: "36"
}
},
{
data: {
source: "80",
target: "76"
}
},
{
data: {
source: "22",
target: "86"
}
},
{
data: {
source: "86",
target: "80"
}
},
{
data: {
source: "95",
target: "89"
}
},
{
data: {
source: "89",
target: "90"
}
},
{
data: {
source: "102",
target: "104"
}
},
{
data: {
source: "80",
target: "89"
}
},
{
data: {
source: "104",
target: "109"
}
},
{
data: {
source: "115",
target: "109"
}
},
{
data: {
source: "121",
target: "89"
}
},
{
data: {
source: "121",
target: "115"
}
},
{
data: {
source: "121",
target: "128"
}
},
{
data: {
source: "128",
target: "130"
}
},
{
data: {
source: "141",
target: "128"
}
},
{
data: {
source: "128",
target: "136"
}
},
{
data: {
source: "136",
target: "148"
}
},
{
data: {
source: "148",
target: "149"
}
},
{
data: {
source: "149",
target: "156"
}
},
{
data: {
source: "156",
target: "158"
}
},
{
data: {
source: "130",
target: "164"
}
},
{
data: {
source: "164",
target: "166"
}
},
{
data: {
source: "178",
target: "179"
}
},
{
data: {
source: "184",
target: "178"
}
},
{
data: {
source: "178",
target: "189"
}
},
{
data: {
source: "141",
target: "178"
}
},
{
data: {
source: "104",
target: "103"
}
},
{
data: {
source: "10",
target: "12"
}
},
{
data: {
source: "164",
target: "172"
}
},
{
data: {
source: "22",
target: "104"
}
}
]
}
}));
cy.unbind("tapend");
cy.bind("tapend", "node", function() {
cy.animate({
fit: {
eles: cy.elements(),
padding: 20
},
center: {
eles: cy.elements()
}
}, {
duration: 500
});
});
});
body {
font-family: helvetica;
font-size: 14px;
}
#cy {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
}
<!DOCTYPE>
<html>
<head>
<title>cytoscape-cola.js demo</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<!-- for testing with local version of cytoscape.js -->
<!--<script src="../cytoscape.js/build/cytoscape.js"></script>-->
<script src="https://unpkg.com/webcola/WebCola/cola.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-cola#2.3.0/cytoscape-cola.min.js"></script>
</head>
<body>
<h1>cytoscape-cola demo</h1>
<div id="cy"></div>
</body>
</html>
Conclusion:
Cytoscape.js has the ability to display the force layout, but it is a little worse than the two examples you provided (they can display the graph without moving the nodes to their optimal position but the user preferred one). If you like to use cytoscape.js, you can do that just fine, but always consider which use cases you need and check, if any other application can handle the situation better (cytoscape.js has so many awesome features you can use, so if you can make it work, cytoscape would be my way to go).
Best of luck!
You can use force-directed layout of d3.js Here is an example graph.
I believe Neo4j Browser also uses d3.js
From the official website:
The default Neo4j Server has a powerful, customizable data visualization tool based on the built-in D3.js library.
I found a video that may be similar as your questionUse of Cytoscape.js for Client project, also there is another extension LAYOUT with d3.js cytoscape.js-d3-forcethat may be a good reference.

How do I test a localhost url in nightwatch js

I am trying to run UI regression tests against a local project.
I am running the project with Browsersync, which ends up at localhost:3000.
I have tried setting the url to the directory of my distributed files but this also does not work. Internet Explorer opens but cannot connect to the page.
Here is my nightwatch.json
{
"src_folders" : ["nightwatch/tests"],
"output_folder" : "nightwatch/reports",
"custom_commands_path" : "nightwatch/commands",
"custom_assertions_path" : "nightwatch/assertions",
"page_objects_path" : "",
"globals_path" : "",
"selenium" : {
"start_process" : true,
"start_session" : true,
"server_path" : "C:\\Selenium\\selenium-server-standalone-2.52.0.jar",
"log_path" : "",
"host" : "127.0.0.1",
"port" : 4444,
"cli_args" : {
"webdriver.chrome.driver" : "",
"webdriver.ie.driver" : "C:\\Selenium\\IEDriverServer.exe"
}
},
"test_settings" : {
"default" : {
"launch_url" : "http://localhost",
"selenium_port" : 4444,
"selenium_host" : "localhost",
"silent": true,
"screenshots" : {
"enabled" : false,
"on_failure" : false,
"on_error" : false,
"path" : "test/screenshots/"
},
"desiredCapabilities": {
"browserName": "internet explorer",
"javascriptEnabled": true,
"acceptSslCerts": true
}
},
"chrome" : {
"desiredCapabilities": {
"browserName": "chrome",
"javascriptEnabled": true,
"acceptSslCerts": true
}
}
}
}
Here's my test
module.exports = {
before : function (browser) {
browser.resizeWindow(1024, 800);
},
'OOBE Homepage': function(browser) {
browser
.url('http://localhost:3000/index.html')
.waitForElementVisible('body', 5000)
.compareScreenshot('desktop-index.png')
.end();
},
};
Changing the launch_url to localhost:3000 worked.
{
"src_folders" : ["nightwatch/tests"],
"output_folder" : "nightwatch/reports",
"custom_commands_path" : "nightwatch/commands",
"custom_assertions_path" : "nightwatch/assertions",
"page_objects_path" : "",
"globals_path" : "",
"selenium" : {
"start_process" : true,
"start_session" : true,
"server_path" : "C:\\Selenium\\selenium-server-standalone-2.52.0.jar",
"log_path" : "",
"host" : "127.0.0.1",
"port" : 4444,
"cli_args" : {
"webdriver.chrome.driver" : "",
"webdriver.ie.driver" : "C:\\Selenium\\IEDriverServer.exe"
}
},
"test_settings" : {
"default" : {
"launch_url" : "http://localhost:3000",
"selenium_port" : 4444,
"selenium_host" : "localhost",
"silent": true,
"screenshots" : {
"enabled" : false,
"on_failure" : false,
"on_error" : false,
"path" : "test/screenshots/"
},
"desiredCapabilities": {
"browserName": "internet explorer",
"javascriptEnabled": true,
"acceptSslCerts": true
}
},
"chrome" : {
"desiredCapabilities": {
"browserName": "chrome",
"javascriptEnabled": true,
"acceptSslCerts": true
}
}
}
}

using Select2 with Durandal

Hi I am trying to use Select2 (multiselect) with Durandal (http://jsfiddle.net/anasnakawa/6XvqX/381/),
but the popup does not work below is part of my VM and HTML, here I am trying to bind a list of states to an input it should work as an auto complete but there seems to a issue showing the selection popup, can someone please help
define(['durandal/app', 'services/datacontext', 'plugins/router', 'services/bindinghandlers'],
function (app, datacontext, router) {
var withs = ko.observableArray(),
states = [
{ id: "AL", text: "Alabama" },
{ id: "AK", text: "Alaska" },
{ id: "AZ", text: "Arizona" },
{ id: "AR", text: "Arkansas" },
{ id: "CA", text: "California" },
{ id: "CO", text: "Colorado" },
{ id: "CT", text: "Connecticut" },
{ id: "DE", text: "Delaware" },
{ id: "FL", text: "Florida" },
{ id: "GA", text: "Georgia" },
{ id: "HI", text: "Hawaii" },
{ id: "ID", text: "Idaho" },
{ id: "IL", text: "Illinois" },
{ id: "IN", text: "Indiana" },
{ id: "IA", text: "Iowa" },
{ id: "KS", text: "Kansas" },
{ id: "KY", text: "Kentucky" },
{ id: "LA", text: "Louisiana" },
{ id: "ME", text: "Maine" },
{ id: "MD", text: "Maryland" },
{ id: "MA", text: "Massachusetts" },
{ id: "MI", text: "Michigan" },
{ id: "MN", text: "Minnesota" },
{ id: "MS", text: "Mississippi" },
{ id: "MO", text: "Missouri" },
{ id: "MT", text: "Montana" },
{ id: "NE", text: "Nebraska" },
{ id: "NV", text: "Nevada" },
{ id: "NH", text: "New Hampshire" },
{ id: "NJ", text: "New Jersey" },
{ id: "NM", text: "New Mexico" },
{ id: "NY", text: "New York" },
{ id: "NC", text: "North Carolina" },
{ id: "ND", text: "North Dakota" },
{ id: "OH", text: "Ohio" },
{ id: "OK", text: "Oklahoma" },
{ id: "OR", text: "Oregon" },
{ id: "PA", text: "Pennsylvania" },
{ id: "RI", text: "Rhode Island" },
{ id: "SC", text: "South Carolina" },
{ id: "SD", text: "South Dakota" },
{ id: "TN", text: "Tennessee" },
{ id: "TX", text: "Texas" },
{ id: "UT", text: "Utah" },
{ id: "VT", text: "Vermont" },
{ id: "VA", text: "Virginia" },
{ id: "WA", text: "Washington" },
{ id: "WV", text: "West Virginia" },
{ id: "WI", text: "Wisconsin" },
{ id: "WY", text: "Wyoming" }
];
var vm = {
withs: withs,
states: states,
};
return vm;
});
<select multiple="true" data-bind="options: states, optionsValue: 'id', optionsText: 'text', selectedOptions: withs, select2: {}" style="width: 300px"></select>
Register select2 in the Require.js configuration inside main.js:
requirejs.config({
paths: {
'select2': 'path/to/select2'
}
});
Define it in your view model:
define(['select2'], function (select2) {
// ...
});
Don't forget to declare it. You'll have to use the attached callback:
var vm = {
withs: withs,
states: states,
attached: function() {
$('select').select2();
}
};