I modified this component in a seperate project. It was working just fine. Then i copied that segment into my main project. The graph is rendered with no problem however, when i try to change position of any node it does not work and creates these errors.
enter image description here
The versions of d3 are the same in both of the projects. I thought it might be caused by some other component and i tried to render it in app.js on its own and it still did not work. I wonder what causes this and cannot find it.
import * as React from "react";
import { Graph } from "react-d3-graph";
const data = { nodes: [
{ id: "NEWS1", color: "black", size: 800 },
{ id: "NEWS2", color: "black", size: 800 },
{ id: "NEWS3", color: "black", size: 800 },
{ id: "NEWS4", color: "black", size: 800 },
{ id: "Sharer1", color: "red", size: 300 },
{ id: "Sharer2", color: "green", size: 300 },
{ id: "Sharer3", color: "red", size: 300 },
{ id: "Sharer4", color: "red", size: 300 },
{ id: "Sharer11", color: "red", size: 300 },
{ id: "Sharer12", color: "red", size: 300 },
{ id: "Sharer13", color: "red", size: 300 },
{ id: "Sharer21", color: "red", size: 300 },
{ id: "Sharer22", color: "red", size: 300 },
{ id: "Sharer23", color: "red", size: 300 },
{ id: "Sharer31", color: "red", size: 300 },
{ id: "Sharer32", color: "red", size: 300 },
{ id: "Sharer33", color: "red", size: 300 },
{ id: "Sharer41", color: "red", size: 300 },
{ id: "Sharer411", color: "red", size: 300 },
{ id: "Sharer4111", color: "red", size: 300 } ],
links: [
{ source: "NEWS1", target: "Sharer1" },
{ source: "NEWS2", target: "Sharer2" },
{ source: "NEWS3", target: "Sharer3" },
{ source: "NEWS4", target: "Sharer4" },
{ source: "Sharer1", target: "Sharer11" },
{ source: "Sharer1", target: "Sharer12" },
{ source: "Sharer1", target: "Sharer13" },
{ source: "Sharer2", target: "Sharer21" },
{ source: "Sharer2", target: "Sharer22" },
{ source: "Sharer2", target: "Sharer23" },
{ source: "Sharer3", target: "Sharer31" },
{ source: "Sharer3", target: "Sharer32" },
{ source: "Sharer3", target: "Sharer33" },
{ source: "Sharer4", target: "Sharer41" },
{ source: "Sharer41", target: "Sharer411" },
{ source: "Sharer411", target: "Sharer4111" } ] };
const myConfig = { nodeHighlightBehavior: true, node: {
color: "lightgreen",
size: 120,
labelProperty: "id",
highlightStrokeColor: "blue" }, link: {
type: "LINE_SMOOTH",
highlightColor: "red" } };
function NetworkGraph() {
const [state,showModal] = React.useState(false)
const handleShowMessageClick = (id) => showModal(true);
const handleCloseModal = (id) => showModal(false); const onClickGraph = () => {
// window.alert(`Clicked the graph background`); };
const onClickNode = (nodeId) => {
// };
const onDoubleClickNode = (nodeId) => {
// window.alert(`Double clicked node ${nodeId}`); };
const onRightClickNode = (event, nodeId) => {
// window.alert(`Right clicked node ${nodeId}`); };
const onMouseOverNode = (nodeId) => {
//handleShowMessageClick(nodeId); };
const onMouseOutNode = (nodeId) => {
//handleCloseModal(nodeId); };
const onClickLink = (source, target) => {
// window.alert(`Clicked link between ${source} and ${target}`); };
const onRightClickLink = (event, source, target) => {
// window.alert(`Right clicked link between ${source} and ${target}`); };
const onMouseOverLink = (source, target) => {
// window.alert(`Mouse over in link between ${source} and ${target}`); };
const onMouseOutLink = (source, target) => {
// window.alert(`Mouse out link between ${source} and ${target}`); };
return (
<div>
<Graph
id="graph-id"
data={data}
config={myConfig}
onClickNode={onClickNode}
onRightClickNode={onRightClickNode}
onClickGraph={onClickGraph}
onClickLink={onClickLink}
onRightClickLink={onRightClickLink}
onMouseOverNode={onMouseOverNode}
onMouseOutNode={onMouseOutNode}
onMouseOverLink={onMouseOverLink}
onMouseOutLink={onMouseOutLink}
/>
</div> ); }
export default NetworkGraph
Related
I am trying to add multiple values to a label in cytoscape.js like so -
{
"selector": "edge",
"style": {
"curve-style": "haystack",
"text-wrap": "wrap",
"label": "data(count)" + "data(edgevalue)",
"font-size": "8px",
"color": "black",
"haystack-radius": "0.5",
"opacity": "0.4",
"line-color": "#bbb",
"width": "mapData(weight, 0, 1, 1, 8)",
}
},
However this is literally just displaying -
data(count)data(edgevalue)
As the label text. If I remove one or the other it prints the correct value for each.
I tried adding a '\n' for a line break, which created a line break but the values were just the same as above.
I also tried data(count + edgevalue) to no avail.
How can I achieve multiple data attributes in a label text?
You can use mappers to get the correct data into your styles: mappers
Also, I usually use template strings:
{
label: function (element) {
return `${element.data("attribute_01")} + ${element.data("attribute_02")}`
}
}
Here you can see a simple example:
document.addEventListener("DOMContentLoaded", function() {
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
// demo your layout
layout: {
name: "klay"
// some more options here...
},
style: [{
selector: "node",
style: {
"background-color": "#dd4de2"
}
},
{
selector: ".leaf",
style: {
"background-color": "#000"
}
},
{
selector: "edge",
style: {
"curve-style": "bezier",
"target-arrow-shape": "triangle",
"line-color": "#dd4de2",
"target-arrow-color": "#dd4de2",
"opacity": "0.5",
"label": function(node) {
return `${node.data("source")} -> ${node.data("target")}`
}
}
}
],
elements: {
nodes: [{
data: {
id: "n0"
}
},
{
data: {
id: "n1"
}
},
{
data: {
id: "n2"
}
},
{
data: {
id: "n3"
}
},
{
data: {
id: "n4"
}
},
{
data: {
id: "n5"
}
},
{
data: {
id: "n6"
}
},
{
data: {
id: "n7"
}
},
{
data: {
id: "n8"
}
},
{
data: {
id: "n9"
}
},
{
data: {
id: "n10"
}
},
{
data: {
id: "n11"
}
},
{
data: {
id: "n12"
}
},
{
data: {
id: "n13"
}
},
{
data: {
id: "n14"
}
},
{
data: {
id: "n15"
}
}
],
edges: [{
data: {
source: "n0",
target: "n1"
}
},
{
data: {
source: "n1",
target: "n2"
}
},
{
data: {
source: "n1",
target: "n3"
}
},
{
data: {
source: "n2",
target: "n4"
}
},
{
data: {
source: "n4",
target: "n5"
}
},
{
data: {
source: "n4",
target: "n6"
}
},
{
data: {
source: "n6",
target: "n7"
}
},
{
data: {
source: "n6",
target: "n8"
}
},
{
data: {
source: "n8",
target: "n9"
}
},
{
data: {
source: "n8",
target: "n10"
}
},
{
data: {
source: "n10",
target: "n11"
}
},
{
data: {
source: "n11",
target: "n12"
}
},
{
data: {
source: "n12",
target: "n13"
}
},
{
data: {
source: "n13",
target: "n14"
}
},
{
data: {
source: "n13",
target: "n15"
}
}
]
}
}));
cy.nodes().leaves().addClass("leaf");
});
body {
font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
font-size: 14px;
}
#cy {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 999;
}
<html>
<head>
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://unpkg.com/klayjs#0.4.1/klay.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-klay#3.1.3/cytoscape-klay.min.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>
Key Words: vue echarts graph drag
I want to make a graph chart with draggable nodes.
I use graphic to create circles with the dragging function on nodes.
there are two bugs:
When I move one node, the other nodes will move too.
Although I update the option immediately when the data change, but the chart always change a few seconds later.
You can init a vue-project with vue-cli3 and npm install echarts.
Then you can copy the codes to instead of the App.vue.
<template>
<div id="app">
<div id="charts" ref="chart" style="height:70vh;"></div>
</div>
</template>
<script>
import echarts from 'echarts'
export default {
data () {
return {
myChart: null,
option: {},
graph: {
nodes: [
{
name: 'Node1',
x: 300,
y: 300
},
{
name: 'Node2',
x: 800,
y: 300
},
{
name: 'Node3',
x: 550,
y: 100
},
{
name: 'Node4',
x: 550,
y: 500
}
],
links: [
{
source: 0,
target: 1,
symbolSize: [5, 20],
label: {
normal: {
show: true
}
},
lineStyle: {
normal: {
width: 5,
curveness: 0.2
}
}
},
{
source: 'Node2',
target: 'Node1',
label: {
normal: {
show: true
}
},
lineStyle: {
normal: { curveness: 0.2 }
}
},
{
source: 'Node1',
target: 'Node3'
},
{
source: 'Node2',
target: 'Node3'
},
{
source: 'Node2',
target: 'Node4'
},
{
source: 'Node1',
target: 'Node4'
}
]
}
}
},
mounted () {
this.initChart()
this.renderChart()
},
methods: {
initChart () {
this.myChart = echarts.init(document.getElementById('charts'));
},
renderChart() {
this.myChart.showLoading();
this.formatOption();
this.initDrag();
},
formatOption () {
this.option = {
title: {
text: 'Graph 简单示例'
},
tooltip: {},
animationDurationUpdate: 1500,
animationEasingUpdate: 'quinticInOut',
series : [
{
type: 'graph',
layout: 'none',
symbolSize: 50,
roam: 'scale',
label: {
normal: {
show: true
}
},
edgeSymbol: ['circle', 'arrow'],
edgeSymbolSize: [4, 10],
edgeLabel: {
normal: {
textStyle: {
fontSize: 20
}
}
},
nodes: this.graph.nodes,
links: this.graph.links,
lineStyle: {
normal: {
opacity: 0.9,
width: 2,
curveness: 0
}
}
}
]
};
this.myChart.hideLoading();
this.myChart.setOption(this.option, true);
},
initDrag () {
this.option.graphic = echarts.util.map(this.graph.nodes, (item, dataIndex) => {
return {
type: 'circle',
position: this.myChart.convertToPixel({seriesIndex: 0}, [item.x, item.y]),
shape: {
r: 10
},
// invisible: true,
style: {
fill: 'blue'
},
draggable: true,
ondrag: echarts.util.curry(this.onPointDragging, dataIndex),
z: 100
}
});
this.myChart.setOption(this.option);
window.addEventListener('resize', this.updatePosition);
},
updatePosition () {
this.myChart.setOption({
graphic: echarts.util.map(this.graph.nodes, (item, dataIndex) => {
return {
position: this.myChart.convertToPixel({seriesIndex: 0}, [item.x, item.y])
};
})
});
},
onPointDragging (dataIndex, event) {
let pos = this.myChart.convertFromPixel({seriesIndex: 0}, [event.offsetX, event.offsetY]) // 将graphic的像素坐标转化为坐标系坐标
this.graph.nodes[dataIndex].x = pos[0] // 将新的坐标系坐标赋值给node
this.graph.nodes[dataIndex].y = pos[1]
this.myChart.setOption({
series: {
nodes: this.graph.nodes
}
})
this.updatePosition()
}
}
}
</script>
<style scoped>
#charts {
flex: 1;
border: 1px solid;
box-shadow: 0 0 20px rgba(18,208,253,.5);
}
</style>
I'm displaying a flowchart with values from a JSON file.
When I create my element in a static way, like this :
elements: {
nodes: [
{ data: { id: 'INIT' } },
{ data: { id: 'BUSINESS_RULES_1' } },
{ data: { id: 'EXPORT_STC' } },
{ data: { id: 'EXPORT_SPEC' } },
{ data: { id: 'COPY' } },
{ data: { id: 'MERGE' } },
{ data: { id: 'BUSINESS_RULES_2' } },
{ data: { id: 'TRANSFORM_ARP' } },
{ data: { id: 'TRANSFORM_APS' } },
{ data: { id: 'PUBLISH_APS' } },
{ data: { id: 'PUBLISH_ARP' } },
{ data: { id: 'ARCHIVE' } }
],
edges: [
{ data: { source: 'INIT', target: 'BUSINESS_RULES_1' } },
{ data: { source: 'BUSINESS_RULES_1', target: 'EXPORT_SPEC' } },
{ data: { source: 'BUSINESS_RULES_1', target: 'EXPORT_STC' } },
{ data: { source: 'EXPORT_STC', target: 'COPY' } },
{ data: { source: 'EXPORT_SPEC', target: 'COPY' } },
{ data: { source: 'COPY', target: 'MERGE' } },
{ data: { source: 'MERGE', target: 'BUSINESS_RULES_2' } },
{ data: { source: 'BUSINESS_RULES_2', target: 'TRANSFORM_APS' } },
{ data: { source: 'BUSINESS_RULES_2', target: 'TRANSFORM_ARP' } },
{ data: { source: 'TRANSFORM_ARP', target: 'PUBLISH_ARP' } },
{ data: { source: 'TRANSFORM_APS', target: 'PUBLISH_APS' } },
{ data: { source: 'PUBLISH_APS', target: 'ARCHIVE' } },
{ data: { source: 'PUBLISH_ARP', target: 'ARCHIVE' } }
]
}
It is well displayed as you can see :
But when I create the element in a dynamic way, like this :
// Fill array with nodes and edges
var arrayNodesAndEdges = [];
for (var i = 0; i < myJSONdata.length; i++) {
if(i < myJSONdata.length - 1 && (myJSONdata[i].OPERATION_NAME != myJSONdata[i+1].OPERATION_NAME)) {
console.log(i + " " +myJSONdata[i].OPERATION_NAME);
arrayNodesAndEdges.push({
group: "nodes",
data: {
id: myJSONdata[i].OPERATION_NAME
}
});
} else if(i == myJSONdata.length - 1) {
console.log(i + " " +myJSONdata[i].OPERATION_NAME);
arrayNodesAndEdges.push({
group: "nodes",
data: {
id: myJSONdata[i].OPERATION_NAME
}
});
}
}
for (var i = 0; i < myJSONdata.length; i++) {
var source = myJSONdata[i].OPERATION_NAME;
if(myJSONdata[i].NEXT_OPERATION_NAME !== "" && myJSONdata[i].NEXT_OPERATION_NAME !== null) {
console.log("Source: " + myJSONdata[i].OPERATION_NAME + ", " + "Target: " +myJSONdata[i].NEXT_OPERATION_NAME);
arrayNodesAndEdges.push({
group: "edges",
data: {
id: "e"+i,
source: source,
target: myJSONdata[i].NEXT_OPERATION_NAME
}
});
}
}
cy.add(arrayNodesAndEdges);
It is bad displayed, all nodes are on top of each other, as you can see:
(I moved some to explain how they are positionned, but they are all on top of each other)
Here's the console log, you can see this is the same structure in static or dynamic way :
NODES
0 INIT
2 BUSINESS_RULES_1
3 EXPORT_STC
4 EXPORT_SPEC
5 COPY
6 MERGE
8 BUSINESS_RULES_2
9 TRANSFORM_ARP
10 TRANSFORM_APS
11 PUBLISH_APS
12 PUBLISH_ARP
13 ARCHIVE
EDGES
Source: INIT, Target: BUSINESS_RULES_1
Source: BUSINESS_RULES_1, Target: EXPORT_SPEC
Source: BUSINESS_RULES_1, Target: EXPORT_STC
Source: EXPORT_STC, Target: COPY
Source: EXPORT_SPEC, Target: COPY
Source: COPY, Target: MERGE
Source: MERGE, Target: BUSINESS_RULES_2
Source: BUSINESS_RULES_2, Target: TRANSFORM_APS
Source: BUSINESS_RULES_2, Target: TRANSFORM_ARP
Source: TRANSFORM_ARP, Target: PUBLISH_ARP
Source: TRANSFORM_APS, Target: PUBLISH_APS
Source: PUBLISH_APS, Target: ARCHIVE
Source: PUBLISH_ARP, Target: ARCHIVE
I can't understand what I'm doing wrong ?
Thank you
EDIT ----------
This is my whole code :
var myJSONdata = data;
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
boxSelectionEnabled: true,
autounselectify: true,
layout: {
name: 'dagre',
rankDir: 'LR' // 'TB' for top to bottom flow, 'LR' for left to right. default is undefined, making it plot top-bottom
},
style: [
{
selector: 'node',
style: {
'content': 'data(id)',
'width': 200,
'height': 50,
'text-opacity': 1,
'text-valign': 'center',
'text-halign': 'center',
'shape': 'square',
'label': 'data(id)',
'background-color': '#11479e',
'color': 'white'
}
},
{
selector: 'edge',
style: {
'width': 7,
'target-arrow-color': '#ccc',
'target-arrow-shape': 'triangle',
'curve-style': 'bezier',
'line-color': '#9dbaea'
}
},
{
selector: ':selected',
style: {
'background-color': 'yellow',
'line-color': 'yellow',
'target-arrow-color': 'yellow',
'source-arrow-color': 'yellow',
}
}
]
/*,elements: {
nodes: [
{ data: { id: 'INIT' } },
{ data: { id: 'BUSINESS_RULES_1' } },
{ data: { id: 'EXPORT_STC' } },
{ data: { id: 'EXPORT_SPEC' } },
{ data: { id: 'COPY' } },
{ data: { id: 'MERGE' } },
{ data: { id: 'BUSINESS_RULES_2' } },
{ data: { id: 'TRANSFORM_ARP' } },
{ data: { id: 'TRANSFORM_APS' } },
{ data: { id: 'PUBLISH_APS' } },
{ data: { id: 'PUBLISH_ARP' } },
{ data: { id: 'ARCHIVE' } }
],
edges: [
{ data: { source: 'INIT', target: 'BUSINESS_RULES_1' } },
{ data: { source: 'BUSINESS_RULES_1', target: 'EXPORT_SPEC' } },
{ data: { source: 'BUSINESS_RULES_1', target: 'EXPORT_STC' } },
{ data: { source: 'EXPORT_STC', target: 'COPY' } },
{ data: { source: 'EXPORT_SPEC', target: 'COPY' } },
{ data: { source: 'COPY', target: 'MERGE' } },
{ data: { source: 'MERGE', target: 'BUSINESS_RULES_2' } },
{ data: { source: 'BUSINESS_RULES_2', target: 'TRANSFORM_APS' } },
{ data: { source: 'BUSINESS_RULES_2', target: 'TRANSFORM_ARP' } },
{ data: { source: 'TRANSFORM_ARP', target: 'PUBLISH_ARP' } },
{ data: { source: 'TRANSFORM_APS', target: 'PUBLISH_APS' } },
{ data: { source: 'PUBLISH_APS', target: 'ARCHIVE' } },
{ data: { source: 'PUBLISH_ARP', target: 'ARCHIVE' } }
]
}*/
});
// Fill array with nodes and edges
var arrayNodesAndEdges = [];
for (var i = 0; i < myJSONdata.length; i++) {
if(i < myJSONdata.length - 1 && (myJSONdata[i].OPERATION_NAME != myJSONdata[i+1].OPERATION_NAME)) {
console.log(i + " " +myJSONdata[i].OPERATION_NAME);
arrayNodesAndEdges.push({
group: "nodes",
data: {
id: myJSONdata[i].OPERATION_NAME
}
});
} else if(i == myJSONdata.length - 1) {
console.log(i + " " +myJSONdata[i].OPERATION_NAME);
arrayNodesAndEdges.push({
group: "nodes",
data: {
id: myJSONdata[i].OPERATION_NAME
}
});
}
}
for (var i = 0; i < myJSONdata.length; i++) {
var source = myJSONdata[i].OPERATION_NAME;
if(myJSONdata[i].NEXT_OPERATION_NAME !== "" && myJSONdata[i].NEXT_OPERATION_NAME !== null) {
console.log("Source: " + myJSONdata[i].OPERATION_NAME + ", " + "Target: " +myJSONdata[i].NEXT_OPERATION_NAME);
arrayNodesAndEdges.push({
group: "edges",
data: {
id: "e"+i,
source: source,
target: myJSONdata[i].NEXT_OPERATION_NAME
}
});
}
}
cy.add(arrayNodesAndEdges);
I finally manage to solve it thanks to this post right here
I created the array at the beginning and add them to the "element" property. But I still do not know why it was not working in the previous version.
This is my final code :
var myJSONdata = data;
// Fill array with nodes and edges
var arrayNodes = [];
for (var i = 0; i < myJSONdata.length; i++) {
if(i < myJSONdata.length - 1 && (myJSONdata[i].OPERATION_NAME != myJSONdata[i+1].OPERATION_NAME)) {
console.log(i + " " +myJSONdata[i].OPERATION_NAME);
arrayNodes.push({
group: "nodes",
data: {
id: myJSONdata[i].OPERATION_NAME
}
});
} else if(i == myJSONdata.length - 1) {
console.log(i + " " +myJSONdata[i].OPERATION_NAME);
arrayNodes.push({
group: "nodes",
data: {
id: myJSONdata[i].OPERATION_NAME
}
});
}
}
var arrayEdges = [];
for (var i = 0; i < myJSONdata.length; i++) {
var source = myJSONdata[i].OPERATION_NAME;
if(myJSONdata[i].NEXT_OPERATION_NAME !== "" && myJSONdata[i].NEXT_OPERATION_NAME !== null) {
console.log("Source: " + myJSONdata[i].OPERATION_NAME + ", " + "Target: " +myJSONdata[i].NEXT_OPERATION_NAME);
arrayEdges.push({
group: "edges",
data: {
id: "e"+i,
source: source,
target: myJSONdata[i].NEXT_OPERATION_NAME
}
});
}
}
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
boxSelectionEnabled: true,
autounselectify: true,
layout: {
name: 'dagre',
rankDir: 'LR' // 'TB' for top to bottom flow, 'LR' for left to right. default is undefined, making it plot top-bottom
},
style: [
{
selector: 'node',
style: {
'content': 'data(id)',
'width': 200,
'height': 50,
'text-opacity': 1,
'text-valign': 'center',
'text-halign': 'center',
'shape': 'square',
'label': 'data(id)',
'background-color': '#11479e',
'color': 'white'
}
},
{
selector: 'edge',
style: {
'width': 7,
'target-arrow-color': '#ccc',
'target-arrow-shape': 'triangle',
'curve-style': 'bezier',
'line-color': '#9dbaea'
}
},
{
selector: ':selected',
style: {
'background-color': 'yellow',
'line-color': 'yellow',
'target-arrow-color': 'yellow',
'source-arrow-color': 'yellow',
}
}
]
,elements: {
nodes: arrayNodes,
edges: arrayEdges
}
});
CYTOSCAPE.JS
I can't manage to apply styles to a class defined in node-data (clLevel0). I wrote a function to work around the problem. So, the function also explains what i want to do, in a much simpler way that is ;-)
function setNodesClassStyles(cy, clas, styleobject)
{
var all = cy.nodes();
for (i = 0; i < all.length; i++) {
the_node = all[i];
all_classes = the_node.data().classes;
//alert(all_classes);
if (all_classes != undefined) {
all_classes = all_classes.split(' ');
for (i = 0; i < all_classes.length; i++) {
alert(all_classes[i]);
if (clas == all_classes[i]) {
the_node.style(styleobject)
}
}
}
}
};
setNodesClassStyles(cy, "clLevel0", {'background-color':'#00E'});
I tried this (not working):
{
selector: ".clLevel0",
style: {
'background-color': '#EAA',
}
},
What's the right way to apply styles on a node with a class 'clas'?
More code:
var cy = cytoscape({
container: document.getElementById('cy'), // container to render in
elements: [ // list of graph elements to start with
// LEVEL 0 NODE
{ // node
data: { id: 'me', name: 'Dirk\n#dickschrauwen', classes: 'clLevel0 clRoot', weight: 10000},
"position": {
"x": 600,
"y": 400 },
},
// LEVEL 1 NODES
{
data: { id: 'skills', name: 'Skills', }
},
{
data: { id: 'education', name: 'School' }
},
{
data: { id: 'work', name: 'Jobs\nProjects' }
},
{
data: { id: 'passion', name: 'Passions' }
},
// ....
style: [
{
selector: 'node',
style: {
'height': 40,
'width': 40,
//'height': 20,
//'width': 20,
'background-color': '#EE0',
// ....
{
selector: ".clLevel0",
style: {
'background-color': '#EAA',
}
},
],
//...
document.addEventListener("DOMContentLoaded", function() {
var cy = cytoscape({
container: document.getElementById('cy'),
elements: {
nodes: [
{ data: { id: 'n', label: 'Olo' } },
{ data: { id: 'c'}, classes: 'className'}
]}
});
cy.style.fromJson([
{
selector: 'node',
style: {
'color': 'red'
}
},{
selector: '.className',
style: {
'label': 'this has a class',
'color': 'blue'
}
}
])
});
I am currently using GOjs library's new graph which is the swimlane.
My problem is I want to add DIFFERENT styles to each node (like, one node has a bg-color of red, the other is blue, others are green and etc). Anyone knows how to do this?
Any help is greatly appreciated. Or anyone can suggest another library that does my thing.
As you haven't posted your code Ill be working off the swinlane examples (http://www.gojs.net/latest/samples/swimlanes.html).
If you have a look at the documentation for nodes (http://gojs.net/beta/intro/nodes.html) you can see how they are changing the color there.
diagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, "Rectangle",
new go.Binding("fill", "color")),
$(go.TextBlock,
{ margin: 5 },
new go.Binding("text", "key"))
);
diagram.model.nodeDataArray = [
{ key: "Alpha", color: "lightblue" }
];
In the swimlane example they have the following relevant code:
myDiagram.nodeTemplate =
$(go.Node, "Auto",
$(go.Shape, "Rectangle",
{ fill: "white", portId: "", cursor: "pointer", fromLinkable: true, toLinkable: true }),
$(go.TextBlock, { margin: 5 },
new go.Binding("text", "key")),
// limit dragging of Nodes to stay within the containing Group, defined above
{
dragComputation: stayInGroup,
mouseDrop: function (e, node) { // dropping a copy of some Nodes and Links onto this Node adds them to this Node's Group
if (!e.shift && !e.control) return; // cannot change groups with an unmodified drag-and-drop
var grp = node.containingGroup;
if (grp !== null) {
var ok = grp.addMembers(node.diagram.selection, true);
if (!ok) grp.diagram.currentTool.doCancel();
}
},
layoutConditions: go.Part.LayoutAdded | go.Part.LayoutNodeSized
}
);
myDiagram.model = new go.GraphLinksModel(
[ // node data
{ key: "Lane1", isGroup: true, color: "lightblue" },
{ key: "Lane2", isGroup: true, color: "lightgreen" },
{ key: "Lane3", isGroup: true, color: "lightyellow" },
{ key: "Lane4", isGroup: true, color: "orange" },
{ key: "oneA", group: "Lane1" },
{ key: "oneB", group: "Lane1" },
{ key: "oneC", group: "Lane1" },
{ key: "oneD", group: "Lane1" },
{ key: "twoA", group: "Lane2" },
{ key: "twoB", group: "Lane2" },
{ key: "twoC", group: "Lane2" },
{ key: "twoD", group: "Lane2" },
{ key: "twoE", group: "Lane2" },
{ key: "twoF", group: "Lane2" },
{ key: "twoG", group: "Lane2" },
{ key: "fourA", group: "Lane4" },
{ key: "fourB", group: "Lane4" },
{ key: "fourC", group: "Lane4" },
{ key: "fourD", group: "Lane4" },
],
[ // link data
{ from: "oneA", to: "oneB" },
{ from: "oneA", to: "oneC" },
{ from: "oneB", to: "oneD" },
{ from: "oneC", to: "oneD" },
{ from: "twoA", to: "twoB" },
{ from: "twoA", to: "twoC" },
{ from: "twoA", to: "twoF" },
{ from: "twoB", to: "twoD" },
{ from: "twoC", to: "twoD" },
{ from: "twoD", to: "twoG" },
{ from: "twoE", to: "twoG" },
{ from: "twoF", to: "twoG" },
{ from: "fourA", to: "fourB" },
{ from: "fourB", to: "fourC" },
{ from: "fourC", to: "fourD" }
]);
To allow each node their own fill color you change the line
{ fill: "white", portId: "", cursor: "pointer", fromLinkable: true, toLinkable: true }),
to
{ fill: "lightblue", portId: "", cursor: "pointer", fromLinkable: true, toLinkable: true },
new go.Binding("fill", "color")),
After making those changes you can then specify what fill colors you want in the node data. Note that I changed the original fill value above to lighblue. Now lightblue will be the default color if you do not specify a color for a node (fourD will be lightblue):
myDiagram.model = new go.GraphLinksModel(
[ // node data
{ key: "Lane1", isGroup: true, color: "lightblue" },
{ key: "Lane2", isGroup: true, color: "lightgreen" },
{ key: "Lane3", isGroup: true, color: "lightyellow" },
{ key: "Lane4", isGroup: true, color: "orange" },
{ key: "oneA", group: "Lane1", color: "green" },
{ key: "oneB", group: "Lane1", color: "red" },
{ key: "oneC", group: "Lane1", color: "yellow" },
{ key: "oneD", group: "Lane1", color: "purple" },
{ key: "twoA", group: "Lane2", color: "orange" },
{ key: "twoB", group: "Lane2", color: "green" },
{ key: "twoC", group: "Lane2", color: "red" },
{ key: "twoD", group: "Lane2", color: "yellow" },
{ key: "twoE", group: "Lane2", color: "purple" },
{ key: "twoF", group: "Lane2", color: "orange" },
{ key: "twoG", group: "Lane2", color: "green" },
{ key: "fourA", group: "Lane4", color: "red" },
{ key: "fourB", group: "Lane4", color: "yellow" },
{ key: "fourC", group: "Lane4", color: "purple" },
{ key: "fourD", group: "Lane4" },
],
[ // link data
{ from: "oneA", to: "oneB" },
{ from: "oneA", to: "oneC" },
{ from: "oneB", to: "oneD" },
{ from: "oneC", to: "oneD" },
{ from: "twoA", to: "twoB" },
{ from: "twoA", to: "twoC" },
{ from: "twoA", to: "twoF" },
{ from: "twoB", to: "twoD" },
{ from: "twoC", to: "twoD" },
{ from: "twoD", to: "twoG" },
{ from: "twoE", to: "twoG" },
{ from: "twoF", to: "twoG" },
{ from: "fourA", to: "fourB" },
{ from: "fourB", to: "fourC" },
{ from: "fourC", to: "fourD" }
]);