EdgeClick on reactflow's subflow doesn't trigger - javascript

I have my nodes like this
const nodes = [
{
id: 'A',
type: 'group',
data: { label: null },
position: { x: 0, y: 0 },
style: {
width: 170,
height: 140,
},
},
{
id: 'B',
type: 'input',
data: { label: 'child node 1' },
position: { x: 10, y: 10 },
parentNode: 'A',
extent: 'parent',
},
{
id: 'C',
data: { label: 'child node 2' },
position: { x: 10, y: 90 },
parentNode: 'A',
extent: 'parent',
},
];
export default nodes;
..and have connection between them
export default [{ id: 'b-c', source: 'B', target: 'C' }];
A is a parent node and B,C are its child nodes. But when clicking on edges with in a subflow group, the onEdgeClick does not trigger. But the same prop works when the edge is not inside a group ( subflow ) !
Highly appreciate any help on which direction to look for a solution!

Related

Append canvas elements to a group

I want to group elements and when these elements are dragged over the rectangle(group) element, they move with each other
How to implement such a feature? Is there a way to know whether an element is on top of that element and append it to it as a child or any other solution
const elements = [
{ // this is the rectangle which I want to append elements to it
id: '1',
type: 'group',
data: {
label: 'node 1',
},
position: { x: 250, y: 0 },
},
{
id: '2',
type: 'ec2',
data: {
label: 'node 2',
},
position: { x: 100, y: 100 },
},
{
id: '3',
type: 's3',
data: {
label: 'node 3',
},
position: { x: 80, y: 120 },
}
];
Getting positions of elements
P.S: I am using React.js & react-flow-library (If that could help)

Is it possible to load tooltip with external data with React-Native-HighCharts?

Good Morning,
Is it possible to read an external variable containing a list within the settings of a HighCharts chart for React-Native?
I'm using the component: "react-native-highcharts".
My code:
import ChartView from 'react-native-highcharts';
render() {
this.state.dadosApi = [10, 10, 1, 3, 4, 6, 5, 7, 18, 19, 2, 13];
var exData = ['2h 30m','1h 30m','4h 30m','5h 30m','6h 30m','4h 30m','1h 30m','7h 30m','15h 30m','2h 13m','12h 30m','00h 30m'];
var Highcharts='Highcharts';
var conf={
chart: {
type: 'line',
animation: Highcharts.svg,
marginRight: 10,
tooltipArr: exData,
},
yAxis: {
title: {
useHTML: true,
text: null,
},
},
navigation: {
buttonOptions: {
enabled: false
}
},
colors:
['#DA6AFF']
,
title: {
text: null
},
xAxis: {
categories: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D'],
},
credits: {
enabled: false
},
series: [{
type: 'line',
name: 'Linha 1',
data: this.state.dadosApi,
marker: {
enabled: false,
},
tooltip: {
pointFormatter: function() {
var toolTip = this.series.chart.options.chart.tooltipArr;
return toolTip[this.x];
}
}
}
tooltip:
{
headerFormat: '',
}
};
const options = {
global: {
useUTC: false
},
lang: {
decimalPoint: ',',
thousandsSep: '.'
}
};
}
return (
<ChartView style={{height:300}} config={conf} options={options}></ChartView>
);
The variable "exData" is coming as "undefined". So I can not load in the "tooltip" the value of the hours of each point in the graph.
Is there any way to do this?
I need to load Tooltip values from another list. I load the line with the values from list1. But when I click on the line I want to open a tooltip containing not the value of "line1" but the corresponding value in "list2".
Example: If I click on the "4" position, the value of the line is "6", but I want to show in the tooltip the text of "list2" that is equal to "Test 4".
But the setting says that the value of list2 is empty. How should I proceed to create tooltip this way?
javascript
const tooltips = ['Teste 1','Teste 2','Teste 3','Teste 4','Teste 5','Teste 6','Teste 7','Teste 8','Teste 9','Teste 10','Teste 11','Teste 12'];
var conf = {
chart: {
type: 'spline',
},
title: {
text: 'Live random data'
},
tooltip: {
formatter: function () {
return this.y > 0 ? this.series.name : tooltips[0];
}
},
navigation: {
buttonOptions: {
enabled: false
}
},
colors:
['#DA6AFF']
,
title: {
text: null
},
xAxis: {
categories: ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D']
},
credits: {
enabled: false
},
series: [{
name: 'Random data',
data: this.state.dataAcionamentos,
marker: {
enabled: false,
},
}]
};
const options = {
global: {
useUTC: false
},
lang: {
decimalPoint: ',',
thousandsSep: '.'
}
//showLoading: true,
};
I got it!
My solution just for contribution.
First I create my 2 arrays for the two Series:
for (i in myObj) {
var Label1 = 'Teste 1';
valueP = myObj[i].value;
dataList1.push({
name: Label1,
y: ValueP
});
valueAux1 = myObj[i].value;
valueAux2 = myObj[i].unit;
dataList2.push({
name: valueAux2,
y: valueAux1
});
}
The results:
dataList1 =
[
{ name: 'Teste 1', y: 61.41 },
{ name: 'Teste 1', y: 51.35 },
{ name: 'Teste 1', y: 41.00 },
{ name: 'Teste 1', y: 31.29 },
{ name: 'Teste 1', y: 21.23 },
{ name: 'Teste 1', y: 11.16 },
{ name: 'Teste 1', y: 16.19 },
{ name: 'Teste 1', y: 26.87 },
{ name: 'Teste 1', y: 36.65 },
{ name: 'Teste 1', y: 31.44 },
]
dataList2 =
[
{ name: '1h', y: 61.41 },
{ name: '2h 30m', y: 41.35 },
{ name: '2h 30m', y: 51.00 },
{ name: '22h 30m', y: 36.29 },
{ name: '4h 30m', y: 31.23 },
{ name: '12h 30m', y: 21.16 },
{ name: '4h 30m', y: 18.19 },
{ name: '6h 30m', y: 46.87 },
{ name: '7h 30m', y: 37.65 },
{ name: '9h 30m', y: 30.44 },
]
So I load the graph configuration:
var conf = {
chart: {
type: 'column',
},
title: {
text: null
},
navigation: {
buttonOptions: {
enabled: false
}
},
colors:
['#DA6AFF', 'rgb(76, 43, 228)']
,
title: {
text: null
},
yAxis: {
title: {
useHTML: true,
text: null
}
},
xAxis: {
categories: [1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
},
credits: {
enabled: false
},
series: [{
type: 'column',
name: 'Bar Chart',
data: dataList1,
marker: {
enabled: false,
},
tooltip: {
pointFormat: '<b>{this.series.data.y}</b>'
},
},{
type: 'line',
name: 'Line 1',
data: dataList2,
marker: {
enabled: false,
},
tooltip: {
pointFormat: '<b>{this.series.data.name}</b>'
},
}]
};
const options = {
global: {
useUTC: false
},
lang: {
decimalPoint: ',',
thousandsSep: '.'
}
};
In this way the bar chart loads the value {this.series.data.y} in the tooltip and in the line graph loads the value {this.series.data.name}.
For example:
Clicking on position "4" of the bar, loads the value of "31.29" on Tooltip.
Clicking on position "4" of the line, loads the value of "22h 30m" on Tooltip.
Please take a look at the example provided here.
In your case, you defined the config as follows:
var conf = {
chart: {
tooltipArr: exData,
},
series: [{
tooltip: {
pointFormatter: function() {
var toolTip = this.series.chart.options.chart.tooltipArr;
return toolTip[this.x];
}
}
}]
}
In your example, you take the tooltip data from:
var toolTip = this.series.chart.options.chart.tooltipArr;
what might quickly result in one of the accessors being undefined. If you want to customise your tooltip based on the values you receive, I would go with the formatter function. You can check, what is the x and y value, using this.x or this.y.
If you know, what do you want to display in tooltips, I would simply declare a const outside conf object and access in inside tooltip formatter function, as the author of the package does.
const tooltips = ['Tooltip1', 'Tooltip2'];
var conf = {
chart: {
type: 'spline',
},
title: {
text: 'Live random data'
},
tooltip: {
formatter: function () {
return this.y > 0 ? this.series.name : tooltips[0];
}
},
series: [{
name: 'Random data'
}]
}

Can hidden values be passed between a highcharts drilldown?

I want to pass a hidden value between a HighCharts drill down. When a user clicks on an item (Item 1), they them have 3 selections. On clicking any of these selections, I would like to have a hidden id passed from Item 1 in order to use this ID to perform an action using another PHP script. Is this possible?
$(function() {
// Create the chart
Highcharts.chart('container', {
chart: {
type: 'bar'
},
title: {
text: 'Overall Status'
},
xAxis: {
type: 'category',
labels: {
style: {
fontSize: '15px'
}
}
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
style: {
fontSize: '20px'
}
},
cursor: 'pointer',
point: {
events: {
click: function() {
if (this.options && this.options.url) {
location.href = this.options.url;
}
}
}
}
}
},
series: [{
name: 'Status',
colorByPoint: true,
data: [{
name: 'Item 1',
y: 80,
drilldown: 'item1'
}, {
name: 'Item 2',
y: 33,
drilldown: 'item2'
}]
}],
drilldown: {
series: [{
id: 'item1',
data: [{
name: 'Condition 1',
url: 'http://myurl?id=item 1',
y: 7
}, {
name: 'Condition 2',
url: 'http://myurl?id=item 1',
y: 2,
}, {
name: 'Condition 3',
url: 'http://myurl?id=item 1',
y: 1,
}]
}, {
id: 'item2',
data: [{
name: 'Condition 1',
url: 'http://myurl?id=item 2',
y: 3
}, {
name: 'Condition 2',
url: 'http://myurl?id=item 2',
y: 2,
}, {
name: 'Condition 3',
url: 'http://myurl?id=item 2',
y: 9,
}]
}]
}
});
});
Have a jsfiddle here https://jsfiddle.net/mark2017/bd1v6tew/2/
You can do it dynamically on a drilldown event.
Define a hidden property for a point.
series: [{
name: 'Status',
colorByPoint: true,
data: [{
name: 'Item 1',
y: 80,
drilldown: 'item1',
hiddenValue: 'hidden 1',
}, {
name: 'Item 2',
y: 33,
drilldown: 'item2',
hiddenValue: 'hidden 2'
}]
}],
Save a parent hiddent property to the new series on the drilldown event:
chart: {
type: 'bar',
events: {
drilldown: function (e) {
e.seriesOptions.hiddenValue = e.point.options.hiddenValue;
}
}
},
Read it on the point click event:
click: function() {
var seriesOptions = this.series && this.series.options;
var hiddenValue = seriesOptions && seriesOptions.hiddenValue;
console.log(hiddenValue);
example: https://jsfiddle.net/enjk7w1r/

Cytoscape.js - Circle layout

I'm trying to make this http://gcuculi.com/cda/imagens/grafico.png with Cytoscape.js. I'm using the circle layout, but it isn't working. I will add more items dynamically. The first node always be closer than the second and so on for the others.
Here is the code:
$(function(){
var cy = cytoscape({
container: document.getElementById('grafico-constelacao'),
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(name)',
'text-valign' : 'center',
'color' : 'white',
})
.selector('edge')
.css({
'width': 2,
'line-color': '#000'
})
.selector('#p')
.css({
'background-color': '#fff',
'width': '60px',
'height': '60px',
'border-width': '2px',
'border-style': 'solid',
'border-color ': '#888',
}),
elements: {
nodes: [
{
data: {id: 'p', weight: 1 },
group: 'nodes',
position: {
x: 500,
y: 150
},
classes: 'principal',
selected: false,
selectable: false,
locked: true,
grabbable: false
},
{ data: { id: 'atr1', name : 'A'} },
{ data: { id: 'atr2', name : 'B' } },
{ data: { id: 'atr3', name : 'C' } },
{ data: { id: 'atr4', name : 'D' } },
{ data: { id: 'atr5', name : 'E' } }
],
edges: [
{ data: { id: 'p-atr1', weight: 1, source: 'p', target: 'atr1' } },
{ data: { id: 'p-atr2', weight: 10, source: 'p', target: 'atr2' } },
{ data: { id: 'p-atr3', weight: 50, source: 'p', target: 'atr3' } },
{ data: { id: 'p-atr4', weight: 100, source: 'p', target: 'atr4' } },
{ data: { id: 'p-atr5', weight: 250, source: 'p', target: 'atr5' } }
]
},
layout: {
name: 'circle',
fit: true,
padding: 30,
boundingBox: undefined,
avoidOverlap: true,
radius: undefined,
startAngle: 10 * Math.PI,
counterclockwise: true,
sort: undefined,
animate: false,
animationDuration: 500,
ready: undefined,
stop: undefined
},
// interaction options:
zoomingEnabled: false,
userZoomingEnabled: false,
panningEnabled: false,
userPanningEnabled: false,
boxSelectionEnabled: false,
selectionType: 'single',
touchTapThreshold: 8,
desktopTapThreshold: 4,
autolock: false,
autoungrabify: false,
autounselectify: false,
});
});
There is a way to control the size of the edges forcing a value?
Run the circle layout on the outside nodes only, specifying your radius as desired and the bounding box centred around the centre node. Run whatever layout you like on the other nodes after init, so you have initial positions to base the secondary layouts on.
http://js.cytoscape.org/#collection/layout

How to highlight the path between two nodes in CYTOSCAPE JS

i can create a graph using cytoscape js library . i am following the this tutorial and i implement like this.
CODE:
$(function(){ // on dom ready
$('#cy').cytoscape({
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)'
})
.selector('edge')
.css({
'target-arrow-shape': 'triangle',
'width': 4,
'line-color': '#ddd',
'target-arrow-color': '#ddd'
})
.selector('.highlighted')
.css({
'background-color': '#61bffc',
'line-color': '#61bffc',
'target-arrow-color': '#61bffc',
'transition-property': 'background-color, line-color, target-arrow-color',
'transition-duration': '0.5s'
}),
elements: {
nodes: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{ data: { id: 'c' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } },
{ data: { id: 'f' } },
{ data: { id: 'g' } }
],
edges: [
{ data: { id: 'ab', weight: 1, source: 'a', target: 'b' } },
{ data: { id: 'ac', weight: 2, source: 'a', target: 'c' } },
{ data: { id: 'bd', weight: 3, source: 'b', target: 'd' } },
{ data: { id: 'be', weight: 4, source: 'b', target: 'e' } },
{ data: { id: 'cf', weight: 5, source: 'c', target: 'f' } },
{ data: { id: 'cg', weight: 6, source: 'c', target: 'g' } }
]
},
layout: {
name: 'breadthfirst',
directed: true,
roots: '#a',
padding: 5
},
ready: function(){
window.cy = this;
var bfs = cy.elements().bfs('#a', function(){}, true);
var i = 0;
var highlightNextEle = function(){
bfs.path[i].addClass('highlighted');
if( i < bfs.path.length ){
i++;
setTimeout(highlightNextEle, 1000);
}
};
// kick off first highlight
highlightNextEle();
}
});
}); // on dom ready
on my implementation i need to highlight the path between the nodes d and g.
How to find the path between the nodes and highlight them?
Using dijkstra algorithm method we can find the path between the nodes.
var dijkstra = cy.elements().dijkstra('#e',function(){
return this.data('weight');
},false);
var bfs = dijkstra.pathTo( cy.$('#i') );
Complete CODE :
$(function(){ // on dom ready
$('#cy').cytoscape({
style: cytoscape.stylesheet()
.selector('node')
.css({
'content': 'data(id)'
})
.selector('edge')
.css({
'target-arrow-shape': 'triangle',
'width': 4,
'line-color': '#ddd',
'target-arrow-color': '#ddd'
})
.selector('.highlighted')
.css({
'background-color': '#61bffc',
'line-color': '#61bffc',
'target-arrow-color': '#61bffc',
'transition-property': 'background-color, line-color, target-arrow-color',
'transition-duration': '0.5s'
}),
elements: {
nodes: [
{ data: { id: 'a' } },
{ data: { id: 'b' } },
{ data: { id: 'c' } },
{ data: { id: 'd' } },
{ data: { id: 'e' } },
{ data: { id: 'f' } },
{ data: { id: 'g' } },
{ data: { id: 'h' } },
{ data: { id: 'i' } }
],
edges: [
{ data: { id: 'ab', weight: 1, source: 'a', target: 'b' } },
{ data: { id: 'ac', weight: 2, source: 'a', target: 'c' } },
{ data: { id: 'bd', weight: 3, source: 'b', target: 'd' } },
{ data: { id: 'be', weight: 4, source: 'b', target: 'e' } },
{ data: { id: 'cf', weight: 5, source: 'c', target: 'f' } },
{ data: { id: 'cg', weight: 6, source: 'c', target: 'g' } },
{ data: { id: 'ah', weight: 7, source: 'a', target: 'h' } },
{ data: { id: 'hi', weight: 8, source: 'h', target: 'i' } }
]
},
layout: {
name: 'breadthfirst',
directed: true,
roots: '#a',
padding: 5
},
ready: function(){
window.cy = this;
var dijkstra = cy.elements().dijkstra('#e',function(){
return this.data('weight');
},false);
var bfs = dijkstra.pathTo( cy.$('#i') );
var x=0;
var highlightNextEle = function(){
var el=bfs[x];
el.addClass('highlighted');
if(x<bfs.length){
x++;
setTimeout(highlightNextEle, 500);
}
};
highlightNextEle();
}
});
}); // on dom ready
I you want to highlight all the possible paths
event.target- is the starting node
event.target.successors().animate({
style: { lineColor: 'red' }
});
Assuming you have picked two nodes and stored them in source_node and target_node, and you want to label everything in between with class 'path_element':
p = cy.elements().aStar({root: source_node, goal: target_node, directed: true}).path;
if (p) {
p.filter(function(i,x) { return x != source_node && x != target_node; })
.addClass('path_element');
p.edgesWith(p)
.addClass('path_element');
}

Categories