jimmybow / visdcc Goto Github PK
View Code? Open in Web Editor NEWDash Core Components for Visualization.
License: MIT License
Dash Core Components for Visualization.
License: MIT License
Hello,
Since the amount of data and the number of relationships are high, nodes move forever, so how can we close this mobility.
Is there any possibility to have something like this? when clicking on a node just that node and flowers are highlighted and the rest are fade.
I have some javascript code to record videos using the user's webcam: I'm using run_js function to run the code inside a callback.
Here is the js code:
VIDEO_HTML =
var my_div = document.createElement("DIV");
var my_p = document.createElement("P");
var my_btn = document.createElement("BUTTON");
var my_btn_txt = document.createTextNode("Press to start recording");
my_btn.appendChild(my_btn_txt);
my_div.appendChild(my_btn);
document.body.appendChild(my_div);
var base64data = 0;
var reader;
var recorder, videoStream;
var recordButton = my_btn;
var handleSuccess = function(stream) {
videoStream = stream;
var options = {
mimeType : 'video/webm;codecs=vp9'
};
recorder = new MediaRecorder(stream, options);
recorder.ondataavailable = function(e) {
var url = URL.createObjectURL(e.data);
var preview = document.createElement('video');
preview.controls = true;
preview.src = url;
document.body.appendChild(preview);
reader = new FileReader();
reader.readAsDataURL(e.data);
reader.onloadend = function() {
base64data = reader.result;
}
};
recorder.start();
};
recordButton.innerText = "Recording... press to stop";
navigator.mediaDevices.getUserMedia({video: true}).then(handleSuccess);
function toggleRecording() {
if (recorder && recorder.state == "recording") {
recorder.stop();
videoStream.getVideoTracks()[0].stop();
recordButton.innerText = "Saving the recording... Please wait!"
setProps({
'data': {'data':base64data
}
})
}
}
function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
var data = new Promise(resolve=>{
recordButton.onclick = ()=>{
toggleRecording()
sleep(2000).then(() => {
// wait 2000ms for the data to be available
resolve(base64data)
});
}
});
I want the recorded "data" from the js code to be used as input to another callback in my dash app. I've seen this https://github.com/jimmybow/visdcc/blob/master/example/Run_js/Add_event_and_callback.py, but couldn't find out a way to do that.
Hello Jimmy,
That's great work! How can we implement the tooltip functionality in visdcc? For example, moving the mouse to one node or edge, the tooltip information for the node or edge will pop up? Thank you!
In a normal dcc graph, it's possible to trigger callbacks when clicking in a graph (https://dash.plotly.com/interactive-graphing). Is this also possible in visdcc.Network?
I want to be able to click on a node and then display it's features in a little menu. If this question has been asked before I am sorry for repeating it but having difficulty finding it in the examples or closed issues.
Any help is appreciated.
I can't open the rawgit website, can you send me the filter.css file Or upload it to other places?
my email:[email protected],Thank you very much
could this be updated to:
github.com/visjs/vis-network
currently the code here is based is on a project that is no longer maintained?
Hi,
I'd like to be able to use the window resize event to trigger a dash callback.
I've got close to that with the following:
from dash import Dash, html, dcc
from dash.dependencies import Input, Output, State
from dash.exceptions import PreventUpdate
import visdcc
import pandas as pd
def generate_html_table_from_df(df, id):
Thead = html.Thead(
[html.Tr([html.Th(col) for col in df.columns])]
)
Tbody = html.Tbody(
[html.Tr(
[html.Td( df.iloc[i, j], id = '{}_{}_{}'.format(id, i, j) ) for j in range(len(df.columns))]
) for i in range(len(df))]
)
return html.Table([Thead, Tbody], id = id, className = "display")
df = pd.DataFrame({'name': ['Jacky', 'Mei', 'Jay', 'Sandy', 'Jerry', 'Jimmy', 'Jeff',
'Jacky', 'Mei', 'Jay', 'Sandy', 'Jerry', 'Jimmy', 'Jeff',
'Jacky', 'Mei', 'Jay', 'Sandy', 'Jerry', 'Jimmy', 'Jeff'],
'age': [18, 71, 14, 56, 22, 28, 15,
18, 71, 14, 56, 22, 28, 15,
18, 71, 14, 56, 22, 28, 15]}, columns = ['name', 'age'])
external_scripts = ['https://code.jquery.com/jquery-3.3.1.min.js',
'https://cdn.datatables.net/v/dt/dt-1.10.18/datatables.min.js']
external_stylesheets = ['https://cdn.datatables.net/v/dt/dt-1.10.18/datatables.min.css']
app = Dash(__name__,
external_scripts = external_scripts,
external_stylesheets = external_stylesheets
)
app.layout = html.Div([
html.Button('Add window event', id = 'button'),
visdcc.Run_js(id = 'javascript', run = "$('#datatable').DataTable()", event = 'null'),
html.Br(),
html.Div(
generate_html_table_from_df(df, id = 'datatable'),
style = {'width': '40%'}
),
html.Div(id = 'output_div')
])
@app.callback(
Output('javascript', 'run'),
[Input('button', 'n_clicks')])
def myfun(x):
if x is None: return ''
return '''
// Copied from https://community.plotly.com/t/accessing-dash-element-props-on-client-side/15798/6
function findAttribute(object, key) {
var value;
var path;
Object.keys(object).some(function(k) {
if (k === key) {
value = object[k];
path = k + '.' + path
return true;
}
if (k.indexOf('__reactInternalInstance') == -1 //_reacInternal is annoyingly recursive?
&& object[k]
&& typeof object[k] === 'object'
&& object.hasOwnProperty(k)) {
[value, path] = findAttribute(object[k], key);
if(value !== undefined) {path = k + '.' + path}
return value !== undefined;
}
});
return [value, path];
}
var target = $('#datatable')[0];
window.addEventListener('resize', function(evt) {
console.log(evt);
var dataTableSetter;
var _unused;
[dataTableSetter , _unused] = findAttribute(target, 'setProps');
console.log(dataTableSetter);
dataTableSetter({
'event': {'x': window.innerHeight, 'y': window.innerWidth},
});
})
console.log(this)
'''
@app.callback(
Output('output_div', 'children'),
[Input('javascript', 'event')])
def myfun(x):
return str(x)
if __name__ == '__main__':
app.run_server(debug=True)
I can see in the browser debugger that dataTableSetter
ends up calling the dash setProps function. However, it says there are no watched properties so doesn't pass on the event.
I'd also like to be able to do this without using a DataTable
. Is that possible?
I'm using:
I load the Network with physics and stabilization enabled.
With visdcc, Is there any possibility once the nodes are stabilized to trap the stabilized event?
When the stabilized event is fired, I want to disable the physics via network.setOptions.
For example, with vis.js
, I do this:
network = new vis.Network(container, data, options);
network.on("stabilizationIterationsDone", function () {
network.setOptions( { physics: false } );
});
Running the https://github.com/jimmybow/visdcc/blob/master/example/Run_js/Add_event_and_callback.py example with:
Results in the following warning being output to the console:
[email protected]_3_1m1649084547.14.0.js:82 Warning: Cannot update a component (`Connect(UnconnectedContainer)`) while rendering a different component (`Run_js`). To locate the bad setState() call inside `Run_js`, follow the stack trace as described in https://fb.me/setstate-in-render
in Run_js (created by CheckedComponent)
in CheckedComponent (created by BaseTreeContainer)
in ComponentErrorBoundary (created by BaseTreeContainer)
in BaseTreeContainer (created by Context.Consumer)
in Unknown (created by BaseTreeContainer)
in div (created by it)
in it (created by CheckedComponent)
in CheckedComponent (created by BaseTreeContainer)
in ComponentErrorBoundary (created by BaseTreeContainer)
in BaseTreeContainer (created by Context.Consumer)
in Unknown (created by UnconnectedContainer)
in div (created by UnconnectedGlobalErrorContainer)
in div (created by GlobalErrorOverlay)
in div (created by GlobalErrorOverlay)
in GlobalErrorOverlay (created by DebugMenu)
in div (created by DebugMenu)
in DebugMenu (created by UnconnectedGlobalErrorContainer)
in div (created by UnconnectedGlobalErrorContainer)
in UnconnectedGlobalErrorContainer (created by Connect(UnconnectedGlobalErrorContainer))
in Connect(UnconnectedGlobalErrorContainer) (created by UnconnectedContainer)
in UnconnectedContainer (created by Connect(UnconnectedContainer))
in Connect(UnconnectedContainer) (created by UnconnectedAppContainer)
in UnconnectedAppContainer (created by Connect(UnconnectedAppContainer))
in Connect(UnconnectedAppContainer) (created by AppProvider)
in Provider (created by AppProvider)
in AppProvider
Nothing appears to actually go wrong but as this comment says "it points out legitimate issues that are likely causing bugs in your code" so would be good to fix.
Hi!
I want to make the labels of all edges invisible except the user hovers over them or selects them. I found this for vis.js, which I'm trying to adapt in viddcc:
https://stackoverflow.com/questions/32690394/how-to-hide-label-in-edge-in-visjs-graph
Here is the code I'm currently working on:
DEFAULT_OPTIONS = {
'height': '600px',
'width': '100%',
'interaction':{'hover': True},
# 'edges': {'scaling': {'min': 1, 'max': 5}},
'physics':{'stabilization':{'iterations': 100}}
}
def get_options(directed, opts_args):
opts = DEFAULT_OPTIONS.copy()
opts['edges'] = { 'arrows': { 'to': directed }, 'font': { 'size': 0 }, 'chosen': { 'label': 'function (values,id,selected,hovering) {values.size = 14;}'}}
if opts_args is not None:
opts.update(opts_args)
return opts
The result is, the font is actually set to zero (the labels are invisible), but they do not get visible when hovering over the edges or selecting them.
Any suggestions?
Hi,
I really like your project. I have already one working HTML+JavaScript+vis.js solution and would like to use the same for my Dash app. However, I am running into trouble setting the options:
OPTIONS = dict(
autoResize=True,
height='600px',
width='100%',
locale='en',
nodes=dict(
shapeProperties=dict(useBorderWithImage=True),
borderWidth=0,
borderWidthSelected=5,
color=dict(
border='#FFFFFF',
background='#FFFFFF',
highlight=dict(border='#0000FF', background='#0000FF')
),
font=dict(size=12, color='#000')
),
edges=dict(
color='black',
length=200,
arrows=dict(
to=dict(enabled=True, scaleFactor=0.5)
),
font=dict(size=12, color='#000')
)
)
It works for the height
, width
, nodes.color
. But it does not work for the nodes.shapeProperties
and edges.color
properties and I really don't have any clue why.
Maybe you can give a hint. Thanks.
Hi i am using your package for a Dashboard Project. Pylance is always complaining that "Network" is unknown import symbol
. Is it possible for you to fix that?
Hi,
I was attempting to use jquery to trigger an update to a div by registering a click event via a loop of buttons.
However, although the click works fine, and the div is updated correctly, it doesn't seem to get pick up by dash's callback function
for example:
when user click the button, it'll trigger an update to the 'operation' div. I have another button called 'btn-test' which checks the value of 'operation' div, it doesn't seem to pick up the update, where am I missing here?
@dash_app.callback(
Output('test', "style"),
[
Input('btn-test','n_clicks')
],
[
State('operation', "children"),
]
)
def test(_, id):
print(id)
return {}
Hello and thank you very much for this package.
I've created a network on my Dash app using your package and I would like to give the users the opportunity to extract the network in .png or .jpeg format.
Is this possible through your package?
is it possible to trace back the path and highlight it when I select the edge or node?
If I use the callback to display the table, I need to click the button multiple times to activate the sorting and selection function. Can you help solve this problem?
app.layout=html.Div([
html.Button('output',id='output-btn'),
html.Div('output')
])
@app.callback(
Output('output', 'children'),
[Input('output-btn', 'n_clicks')])
def update_wordcloud(n_clicks):
if n_clicks is None:
raise PreventUpdate
return visdcc.DataTable(id = 'table2',
box_type = 'radio',
data = DF_SAMPLE,
scroll = {'y':200},
pagination = {'pageSize': 5},
style = {'width':'100%'})
https://community.plot.ly/t/share-visdcc-datatable-a-dash-component-for-antd-table/8227
Hi,
I was using this beautiful package to create a pipeline flow of my application.
I was wondering if there's a trick/solution to have multiple nodes inside a parent node.
______________
| Parent Node1 |
+--------------+
| | |
| |N1| |
| | |
| |N2| |
|______________|
|
______________
| Parent Node2 |
+--------------+
is there a way of making the labels for the edge to show up? I tried everything and I can't seem to get it working.
Hi,
I like and use both vis.js and the dcc. So your package is welcome to me.
However, I don't find how to add a double click event to the network (I'd like to open specific url on dblclick on a node).
Is it possible?
Thanks
Is there a way such that we can expand or collapse the nodes after a certain level depth?
IS there a way within the options argument to set the node label colors, either globally for all nodes or ideally individually for different nodes, looping through the nodes?
Thanks for your great work. Your visdcc works like a charm when it serves only one individual dash app. I have multiple dash app and I put them together with file structure as below.
File structure:
- app.py
- index.py
- apps
|-- __init__.py
|-- app1.py
|-- app2.py
app.py
import dash
app = dash.Dash()
server = app.server
app.config.supress_callback_exceptions = True
app.css.config.serve_locally = True
external_css = ["static/base.css",
"static/custom.css"]
for css in external_css:
app.css.append_css({"external_url": css})
index.py
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from app import app
from apps import app1, app2
app.layout = html.Div([
dcc.Location(id='url', refresh=False),
html.Div(id='page-content')
])
@app.callback(Output('page-content', 'children'),
[Input('url', 'pathname')])
def display_page(pathname):
if pathname == '/':
return app1.layout
elif pathname == '/apps/app2':
return app2.layout
else:
return '404'
if __name__ == '__main__':
app.run_server(debug=True)
app1
from dash.dependencies import Input, Output
import dash_html_components as html
import dash_core_components as dcc
from app import app
layout = html.Div([
html.H3('App 1'),
dcc.Dropdown(
id='app-1-dropdown',
options=[
{'label': 'App 1 - {}'.format(i), 'value': i} for i in [
'NYC', 'MTL', 'LA'
]
]
),
html.Div(id='app-1-display-value'),
dcc.Link('Go to App 2', href='/apps/app2')
],className='container')
@app.callback(
Output('app-1-display-value', 'children'),
[Input('app-1-dropdown', 'value')])
def display_value(value):
return 'You have selected "{}"'.format(value)
app2
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, Event, State
import visdcc
from app import app
layout = html.Div([
visdcc.Network(id = 'net',
options = dict(height= '600px', width= '100%')),
dcc.Input(id = 'label',
placeholder = 'Enter a label ...',
type = 'text',
value = '' ),
html.Br(),html.Br(),
dcc.RadioItems(id = 'color',
options=[{'label': 'Red' , 'value': '#ff0000'},
{'label': 'Green', 'value': '#00ff00'},
{'label': 'Blue' , 'value': '#0000ff'} ],
value='Red' )
])
@app.callback(
Output('net', 'data'),
[Input('label', 'value')])
def myfun(x):
data ={'nodes':[{'id': 1, 'label': x , 'color':'#00ffff'},
{'id': 2, 'label': 'Node 2'},
{'id': 4, 'label': 'Node 4'},
{'id': 5, 'label': 'Node 5'},
{'id': 6, 'label': 'Node 6'} ],
'edges':[{'id':'1-3', 'from': 1, 'to': 3},
{'id':'1-2', 'from': 1, 'to': 2} ]
}
return data
@app.callback(
Output('net', 'options'),
[Input('color', 'value')])
def myfun(x):
return {'nodes':{'color': x}}
So the problem I encountered is the app2 with visdcc works great as individual dash app but wont work as file structure above. It shows blank on the screen and shows no error. When I remove visdcc.Network(id = 'net', options = dict(height= '600px', width= '100%')),
, the content is showing up again. That is why I think there may be a problem related to visdcc when constructing multiple dash apps.
Hey jimmybow, thanks for porting vis.js to dash. I'm a big fan. I did have a quick question for you:
I'm not not able to get the hover information when I hover over any of the nodes. Have you been able to get the tooltips when you use it? I've looked through their docs and believe I'm doing things correctly (even though I have very little experience with js in general). If that wasn't something you were interested in capturing when you ported then I might take a swing at it and let you know how it goes.
Thanks,
Doug
Hi,
How would we go about changing the layout of the plotted graph? For example, if we wanted more space between the nodes.
Here is how my web app looks like:
and here is the code:
html.Div([visdcc.Network(id = 'net-holders',
options = dict(height= '1000px',
width= '100%',
physics={'barnesHut': {'avoidOverlap': 0.1}},
))], style={'padding-right':'10px','padding-left':'10px'}),
blah blah blah .........
@app.callback(
Output('net-holders', 'value'),
[Input('net-holders', 'selection')])
def shareholders_addition(add):
print( add)
My problem is that it wont show up the nodes and edges with corresponding names or ID when I select the nodes on the network? Do you know why?
The render() method cannot be set in the given package. I would like to see more features of Ant.design on the table front of the package which are not working properly.
hi, thanks for your visdcc, it really works for me. i still have some question to ask for help!
i use the visdcc.network to plot the graph, and i want to implement a function, when i select a node, it will just show the path the node to root, and when i click blank space, it will return to the whole graph like before.
here is my code:
app.layout = html.Div([
html.Div(id='vis_div',children=[visdcc.Network(id='vis_graph',
data=data,
options=options,
selection={'nodes': [], 'edges': []})])
])
@app.callback(
[Output('vis_div','children')],
[Input('vis_graph', 'selection')])
def myfun(selection):
try:
node = selection['nodes'][0]
new_data = get_full_path(node)
print(new_data)
return [visdcc.Network(id='vis_graph',
data=new_data,
options=options,selection={'nodes': [], 'edges': []})]
except:
return [visdcc.Network(id='vis_graph',
data=data,
options=options,selection={'nodes': [], 'edges': []})]
this code does not work,
and if I change the id of the new path data, it can work, but it can not return to the previous graph, here is my graph.
app.layout = html.Div([
html.Div(id='vis_div',children=[visdcc.Network(id='vis_graph',
data=data,
options=options,
selection={'nodes': [], 'edges': []})])
])
@app.callback(
[Output('vis_div','children')],
[Input('vis_graph', 'selection')])
def myfun(selection):
try:
node = selection['nodes'][0]
new_data = get_full_path(node)
print(new_data)
return [visdcc.Network(id='vis_graph_path',
data=new_data,
options=options,selection={'nodes': [], 'edges': []})]
except:
return [visdcc.Network(id='vis_graph',
data=data,
options=options,selection={'nodes': [], 'edges': []})]
@app.callback(
[Output('vis_div','children')],
[Input('vis_graph_path', 'selection')])
def myfun(selection):
return [visdcc.Network(id='vis_graph',
data=data,
options=options,selection={'nodes': [], 'edges': []})]
that code will raise exceptions: dash.exceptions.DuplicateCallbackOutput:
Multi output ..vis_div.children.. contains an Output
object
that was already assigned.
or can I highlight some important nodes and edges in other simple way?
hope you can solve my question, thanks for your help!
For nodes, beside 'id' and 'label', we can pass in 'title'. In VIsJS usually the title shows up as one hovers over the node or clicks on it. However, this does not seem to be the case with visdcc.
In short, how to show other node data as one hovers over a node.
I took the example in the main page and added title data:
app.layout = html.Div([
visdcc.Network(id = 'net',
options = dict(height= '600px', width= '100%')),
dcc.Input(id = 'label',
placeholder = 'Enter a label ...',
type = 'text',
value = '' ),
html.Br(),html.Br(),
dcc.RadioItems(id = 'color',
options=[{'label': 'Red' , 'value': '#ff0000'},
{'label': 'Green', 'value': '#00ff00'},
{'label': 'Blue' , 'value': '#0000ff'} ],
value='Red' )
])
@app.callback(
Output('net', 'data'),
[Input('label', 'value')])
def myfun(x):
data ={'nodes':[{'id': 1, 'label': x , 'color':'#00ffff'},
{'id': 2, 'label': 'Node 2', 'title':'I EXPECT TO SEE A TEXT HERE'},
{'id': 4, 'label': 'Node 4'},
{'id': 5, 'label': 'Node 5'},
{'id': 6, 'label': 'Node 6'} ],
'edges':[{'id':'1-3', 'from': 1, 'to': 3},
{'id':'1-2', 'from': 1, 'to': 2} ]
}
return data
@app.callback(
Output('net', 'options'),
[Input('color', 'value')])
def myfun(x):
return {'nodes':{'color': x}}
Hi,
I used below package in R and really like the features. Is the goal of this python library to get somewhere close to that package? With color-coding, grouping, shape, hover over tooltip, it could be much powerful package.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.