Dash Components for Visualization.
Project description
Visdcc
Dash Core Components for Visualization.
- Installing
- Basic Usage
- Advanced Usage
- Learning more about dash ...
Installing :
pip install visdcc
pip install dash==3.0.0
Basic Usage :
from dash import Dash, html, dcc
from dash.dependencies import Input, Output, State
import visdcc
app = Dash(__name__)
app.layout = html.Div(...)
@app.callback(...)
def myfun(...):
...
return ...
if __name__ == '__main__':
app.run()
See detail example code
1. visdcc.Network :
See documents of vis.js : https://visjs.github.io/vis-network/docs/network/
CSS : https://cdnjs.cloudflare.com/ajax/libs/vis/4.20.1/vis.min.css
Plot basic network :
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}}
Get selected nodes and edges :
app.layout = html.Div([
visdcc.Network(id = 'net',
selection = {'nodes':[], 'edges':[]},
options = dict(height= '600px', width= '100%')),
html.Div(id = 'nodes'),
html.Div(id = 'edges')
])
@app.callback(
Output('nodes', 'children'),
[Input('net', 'selection')])
def myfun(x):
s = 'Selected nodes : '
if len(x['nodes']) > 0 : s += str(x['nodes'][0])
return s
@app.callback(
Output('edges', 'children'),
[Input('net', 'selection')])
def myfun(x):
s = 'Selected edges : '
if len(x['edges']) > 0 : s = [s] + [html.Div(i) for i in x['edges']]
return s
Animate or move the camera :
app.layout = html.Div([
visdcc.Network(id = 'net',
options = dict(height= '600px', width= '100%')),
dcc.Input(id = 'label',
placeholder = 'Enter a scale ...',
type = 'text',
value = '' ),
dcc.Input(id = 'labelx',
placeholder = 'Enter x position ...',
type = 'text',
value = '' ),
dcc.Input(id = 'labely',
placeholder = 'Enter y position ...',
type = 'text',
value = '' ),
dcc.Input(id = 'node',
placeholder = 'Enter node id ...',
type = 'text',
value = '' )
])
@app.callback(
Output('net', 'moveTo'),
[Input('label', 'value'),
Input('labelx', 'value'),
Input('labely', 'value')])
def myfun(z, x, y):
if z == '': z = 1
if x == '': x = 1
if y == '': y = 1
return {'position': {'x': int(x), 'y': int(y)}, 'scale': int(z)}
@app.callback(
Output('net', 'fit'),
[Input('node', 'value')])
def myfun(x):
if x == '': return {'Is_used': False}
else: return {'nodes': [x], 'animation': True}
Animate or move the camera by javascript :
from dash import html, dcc, callback_context as ctx
from dash_extensions.enrich import DashProxy as Dash, MultiplexerTransform, Input, Output, State
from flask import Flask, request, send_file
import visdcc
server = Flask(__name__)
app = Dash(server=server, prevent_initial_callbacks=True, transforms=[MultiplexerTransform()])
app.layout = html.Div([
visdcc.Network(id = 'net',
options = dict(height= '600px', width= '100%')),
dcc.Input(id = 'label',
placeholder = 'Enter a scale ...',
type = 'text',
value = '' ),
dcc.Input(id = 'labelx',
placeholder = 'Enter x position ...',
type = 'text',
value = '' ),
dcc.Input(id = 'labely',
placeholder = 'Enter y position ...',
type = 'text',
value = '' ),
dcc.Input(id = 'node',
placeholder = 'Enter node id ...',
type = 'text',
value = '' )
])
@app.callback(
Output('net', 'run'),
[Input('label', 'value'),
Input('labelx', 'value'),
Input('labely', 'value')])
def myfun(z, x, y):
if z == '': z = '1'
if x == '': x = '1'
if y == '': y = '1'
javascript = "this.net.moveTo({{'position': {{'x': {}, 'y': {}}}, 'scale': {}}})".format(x,y,z)
print(javascript)
return javascript
@app.callback(
Output('net', 'run'),
[Input('node', 'value')])
def myfun(x):
if x == '': return ""
else:
javascript = "this.net.fit({{'nodes':[{}], 'animation': true}})".format(x)
print(javascript)
return javascript
2. visdcc.DataTable :
See documents of antd.js : https://ant.design/components/table/
- Using regular expression to filter the string.
- Using boolean expression like
x > 20 & x < 70to filter the number.
CSS :
- https://unpkg.com/antd@3.1.1/dist/antd.css
- https://rawgit.com/jimmybow/CSS/master/visdcc/DataTable/Filter.css
Plot basic table and get selected cell :
external_stylesheets = ['https://unpkg.com/antd@3.1.1/dist/antd.css',
'https://rawgit.com/jimmybow/CSS/master/visdcc/DataTable/Filter.css']
Data_Sample = {
'dataSource':[ {'key': 1, 'name': 'Jacky', 'age': 20},
{'key': 2, 'name': 'Mei' , 'age': 18},
{'key': 3, 'name': 'Jay', 'age': 72},
{'key': 4, 'name': 'Sandy' , 'age': 14},
{'key': 5, 'name': 'Jerry', 'age': 56},
{'key': 6, 'name': 'May' , 'age': 22},
{'key': 7, 'name': 'Jimmy', 'age': 34},
{'key': 8, 'name': 'Jeff' , 'age': 28},
{'key': 9, 'name': 'Bob', 'age': 15} ],
'columns':[{'title': 'Names',
'dataIndex': 'name',
'key': 'name',
'Is_sort': True,
'Is_click': True,
'width': 120,
'fixed': True },
{'title': 'Ages',
'dataIndex': 'age',
'key': 'age',
'Is_sort': True,
'Is_click': True } ]
}
app = Dash(__name__, external_stylesheets = external_stylesheets)
app.layout = html.Div([
visdcc.DataTable(id = 'table' ,
box_type = 'radio',
data = Data_Sample,
scroll = {'x':600,'y':400},
pagination = {'pageSize': 5},
style = {'width':'25%'}
),
html.Div(id = 'text1'),
html.Div(id = 'text2'),
html.Div(id = 'text3'),
html.Div(id = 'text4'),
html.Div(id = 'text5')
])
@app.callback(
Output('text1', 'children'),
[Input('table', 'box_selected_keys')])
def myfun(x):
if x == None : return('')
else : return("Selected row key is " + ', '.join([str(i) for i in x]) )
@app.callback(
Output('text2', 'children'),
[Input('table', 'selectedcell')])
def myfun(x):
if x == None : return('')
else : return('Clicked cell is on row : {} col : {}'.format(x['row'], x['col']) )
@app.callback(
Output('text3', 'children'),
[Input('table', 'row_filtered')])
def myfun(x):
if x == None : return('')
else : return("row_filtered are " + str(x) )
@app.callback(
Output('text4', 'children'),
[Input('table', 'col_filtered')])
def myfun(x):
if x == None : return('')
else : return("col_filtered are " + str(x) )
@app.callback(
Output('text5', 'children'),
[Input('table', 'searchText')])
def myfun(x):
if x == None : return('')
else : return("searchText are " + str(x) )
3. visdcc.Run_js :
Run your javascript !
Open url on new window :
app.layout = html.Div([
html.Button('open url', id = 'button'),
visdcc.Run_js(id = 'javascript')
])
@app.callback(
Output('javascript', 'run'),
[Input('button', 'n_clicks')])
def myfun(x):
if x:
return "window.open('https://yahoo.com/')"
return ""
Apply jQuery Datatables :
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('apply datatable', id = 'button'),
visdcc.Run_js(id = 'javascript'),
html.Br(),
html.Div(
generate_html_table_from_df(df, id = 'datatable'),
style = {'width': '40%'}
),
html.H1(id = 'output_div')
])
@app.callback(
Output('javascript', 'run'),
[Input('button', 'n_clicks')])
def myfun(x):
if x:
return "$('#datatable').DataTable()"
return ""
@app.callback(
Output('output_div', 'children'),
[Input('datatable_{}_{}'.format(i, j), 'n_clicks') for i in range(len(df)) for j in range(len(df.columns))])
def myfun(*args):
ctx = dash.callback_context
if not ctx.triggered or ctx.triggered[0]['value'] is None: return ""
input_id = ctx.triggered[0]['prop_id'].split('.')[0]
row = input_id.split('_')[1]
col = input_id.split('_')[2]
return "you click on row {} col {}".format(row, col)
Add event and callback :
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 mousemove 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 '''
var target = $('#datatable')[0]
target.addEventListener('mousemove', function(evt) {
setProps({
'event': {'x':evt.x, 'y':evt.y }
})
console.log(evt)
})
console.log(this)
'''
@app.callback(
Output('output_div', 'children'),
[Input('javascript', 'event')])
def myfun(x):
return str(x)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file visdcc-0.0.63.tar.gz.
File metadata
- Download URL: visdcc-0.0.63.tar.gz
- Upload date:
- Size: 1.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3c11b24f3a63060b90fa40b260aa7296329ae46f7239cff20daa1b4f753f3400
|
|
| MD5 |
2dd19db8232585032d5a0ac0cf839bac
|
|
| BLAKE2b-256 |
2d712f9ecfafb138e4dd776c6ee95020d3125262dc46a58525a83a7b9337a591
|
File details
Details for the file visdcc-0.0.63-py3-none-any.whl.
File metadata
- Download URL: visdcc-0.0.63-py3-none-any.whl
- Upload date:
- Size: 1.8 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f4ac6f53ba1269a80c190f54395755af73a3cd537159d845f3be00d4501f4037
|
|
| MD5 |
a69a2c392f32a20ac0f88a755ebd5f39
|
|
| BLAKE2b-256 |
05afcf2d4d57c55a14480ea83f1f609183b5ad877b322b1fbb8d8afc32a14355
|