@app.callback(
Output("offcanvas-placement", "is_open"),
Input("open-offcanvas-placement", "n_clicks"),
[State("offcanvas-placement", "is_open")],
)
def toggle_offcanvas(n1, is_open):
if n1:
return not is_open
return is_open
@app.callback(
Output("offcanvas-placement", "placement"),
Input("offcanvas-placement-selector", "value"),
)
def toggle_placement(placement):
return placement
@app.callback(
Output('unique-value-dropdown', 'options'),
[Input('column-filter-dropdown', 'value')],
[Input('url', 'pathname')]
)
def update_dropdown_options(column, pathname):
params = dict(x.split('=') for x in pathname[1:].split('&'))
def get_dataframe(_params):
obj = client.get_object(
Bucket='bentolabs-test-propflo-dashboard',
Key=f'data-mart/{_params["!entity"]}/{_params["project"]}/leads.csv'
)
dataframe = pd.read_csv(obj['Body'], low_memory=False)
return dataframe
df = get_dataframe(params)
if column:
unique_values = df[column].unique()
options = [{'label': str(val), 'value': str(val)} for val in unique_values]
return options
else:
return []
@app.callback(
Output('pinned-dropdown', 'options'),
[Input('url', 'pathname')]
)
def update_pinned_dropdown_options(pathname):
params = dict(x.split('=') for x in pathname[1:].split('&'))
def get_saved_boards(_params):
prefix = f'data-mart/{_params["!entity"]}/{_params["project"]}/'
response = client.list_objects_v2(Bucket='bentolabs-test-propflo-dashboard', Prefix=prefix)
boards = []
if 'Contents' in response:
for item in response['Contents']:
if item['Key'].endswith('.json'):
board_name = item['Key'].replace(prefix, '').replace('.json', '')
boards.append(board_name)
return boards
boards = get_saved_boards(params)
options = [{'label': board_name, 'value': board_name} for board_name in boards]
return options
@app.callback(
Output('graph-container', 'children'),
[Input('add-graph-button', 'n_clicks')],
Input('get-board-button', 'n_clicks'),
[Input('url', 'pathname')],
[State('graph-container', 'children'),
State('unique-value-dropdown', 'value'),
State('column-filter-dropdown', 'value')],
[State('pinned-dropdown', 'value')]
)
def add_graphs(n_clicks, pinned_button, pathname, children, selected_values, column, pinned_board):
try:
params = dict(x.split('=') for x in pathname[1:].split('&'))
graphs = children or []
if pinned_board != None:
if pinned_button > 0:
obj = client.get_object(
Bucket='bentolabs-test-propflo-dashboard',
Key=f'data-mart/{params["!entity"]}/{params["project"]}/{pinned_board}.json'
)
required_data = obj['Body'].read().decode('utf-8')
json_data = json.loads(required_data)
print(json_data)
new_graph_index = len(json_data['x_columns'])
for i in range(new_graph_index):
print(new_graph_index)
graph_card = dbc.Card([
dbc.CardBody([
dbc.Row([
dbc.Col([
html.Label('Graph Type:', className='mb-1'),
dcc.Dropdown(
id={'type': 'type-dropdown', 'index': new_graph_index},
options=[{'label': t, 'value': t} for t in ['line', 'bar', 'pie']],
value='line', # No pre-selected value
className='mb-3 form-select'
),
html.Label('Select x-axis column:', className='mb-1'),
dcc.Dropdown(
id={'type': 'x-axis-dropdown', 'index': new_graph_index},
options=dropdown_options,
value=None, # No pre-selected value
className='mb-3 form-select'
),
html.Label('Select y-axis column:', className='mb-1'),
dcc.Dropdown(
id={'type': 'y-axis-dropdown', 'index': new_graph_index},
options=dropdown_options,
value=None, # No pre-selected value
className='mb-3 form-select'
),
html.Label('Aggregations:', className='mb-1'),
dcc.Dropdown(
id={'type': 'aggregations-dropdown', 'index': new_graph_index},
options=[{'label': t, 'value': t} for t in ["None", "Sum"]],
value=None,
className='mb-3 form-select'
),
dbc.Button(
'Generate Graph',
id='generate-button',
color='info',
className='btn btn-primary',
n_clicks=0,
style={"backgroundColor": "black",
"color": "white",
"border": "2px solid black"}
),
], width=2),
dbc.Col([
dcc.Graph(id={'type': 'graph', 'index': new_graph_index}, config={'displaylogo': False})
], width=10)
])
])
], className='mb-3 p-3 bg-light rounded')
graphs.append(graph_card)
return graphs
elif n_clicks > len(graphs):
new_graph_index = len(graphs)
graph_card = dbc.Card([
dbc.CardBody([
dbc.Row([
dbc.Col([
html.Label('Graph Type:', className='mb-1'),
dcc.Dropdown(
id={'type': 'type-dropdown', 'index': new_graph_index},
options=[{'label': t, 'value': t} for t in ['line', 'bar', 'pie']],
value='line', # No pre-selected value
className='mb-3 form-select'
),
html.Label('Select x-axis column:', className='mb-1'),
dcc.Dropdown(
id={'type': 'x-axis-dropdown', 'index': new_graph_index},
options=dropdown_options,
value=None, # No pre-selected value
className='mb-3 form-select'
),
html.Label('Select y-axis column:', className='mb-1'),
dcc.Dropdown(
id={'type': 'y-axis-dropdown', 'index': new_graph_index},
options=dropdown_options,
value=None, # No pre-selected value
className='mb-3 form-select'
),
html.Label('Aggregations:', className='mb-1'),
dcc.Dropdown(
id={'type': 'aggregations-dropdown', 'index': new_graph_index},
options=[{'label': t, 'value': t} for t in ["None", "Sum"]],
value=None,
className='mb-3 form-select'
),
dbc.Button(
'Generate Graph',
id='generate-button',
color='info',
className='btn btn-primary',
n_clicks=0,
style={"backgroundColor": "black",
"color": "white",
"border": "2px solid black"}
),
], width=2),
dbc.Col([
dcc.Graph(id={'type': 'graph', 'index': new_graph_index}, config={'displaylogo': False})
], width=10)
])
])
], className='mb-3 p-3 bg-light rounded')
graphs.insert(0, graph_card)
return graphs
elif pinned_board: # Append the selected board name to the dropdown options
options = [{'label': li.children, 'value': li.children} for li in
graphs[0].children[1].children[2].children]
options.append({'label': pinned_board, 'value': pinned_board})
graphs[0].children[1].children[2].children = [
html.Li(option['label'], id={'type': 'graph-li', 'index': i}, className='mb-2') for i, option in
enumerate(options)
]
except:
pass
@app.callback(
Output({'type': 'graph', 'index': ALL}, 'figure'),
[Input('filter-button', 'n_clicks')],
[Input('generate-button', 'n_clicks')],
[Input('url', 'pathname')],
[Input('board-name-input', 'value'),
Input('save-button', 'n_clicks')],
Input('pinned-dropdown', 'value'),
Input('get-board-button', 'n_clicks'),
[State('column-filter-dropdown', 'value'),
State('unique-value-dropdown', 'value'),
State({'type': 'x-axis-dropdown', 'index': ALL}, 'value'),
State({'type': 'y-axis-dropdown', 'index': ALL}, 'value'),
State({'type': 'type-dropdown', 'index': ALL}, 'value'),
State({'type': 'aggregations-dropdown', 'index': ALL}, 'value'),
State('start-date-picker', 'date'),
State('end-date-picker', 'date')]
)
def update_graphs(n_clicks, generate, pathname, board_name, z_clicks, pinned_data, pinned_button, column, values, x_columns, y_columns, graph_types, aggregations, start_date, end_date):
try:
params = dict(x.split('=') for x in pathname[1:].split('&'))
if pinned_data is not None:
def get_dataframe(_params):
obj = client.get_object(
Bucket='bentolabs-test-propflo-dashboard',
Key=f'data-mart/{_params["!entity"]}/{_params["project"]}/leads.csv'
)
dataframe = pd.read_csv(obj['Body'], low_memory=False)
return dataframe
df = get_dataframe(params)
figures = []
if pinned_button > 0:
obj = client.get_object(
Bucket='bentolabs-test-propflo-dashboard',
Key=f'data-mart/{params["!entity"]}/{params["project"]}/{pinned_data}.json'
)
required_data = obj['Body'].read().decode('utf-8')
json_data = json.loads(required_data)
if json_data['end_date'] is None:
if json_data['column'] is None:
for i in range(len(json_data['x_columns'])):
x_column = json_data['x_columns'][i]
y_column = json_data['y_columns'][i]
graph_type = json_data['graph_types'][i]
if None in (x_column, y_column, graph_type): # Skip if any required field is not selected
continue
if json_data['aggregations'] == 'None':
if graph_type == 'bar':
fig = px.bar(df, x=x_column, y=y_column, color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
fig = px.line(df, x=x_column, y=y_column, color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
fig = px.pie(df, names=x_column, values=y_column, hole=0.4,
color_discrete_sequence=color_palette)
else:
if graph_type == 'bar':
status = df.groupby(x_column).size().reset_index(name='Sum')
fig = px.bar(df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'], color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
status = df.groupby(x_column).size().reset_index(name='Sum')
fig = px.line(df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'],
color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
status = df.groupby(x_column).size().reset_index(name='Sum')
fig = px.pie(df.groupby(x_column)[y_column].sum().reset_index(), names=x_column,
values=status['Sum'],
hole=0.4, color_discrete_sequence=color_palette)
fig.update_layout(
title=f'{y_column} vs {x_column}',
xaxis_title=x_column,
yaxis_title=y_column
)
figures.append(fig)
if json_data['end_date'] is not None:
if json_data['column'] is None:
filtered_df = df[(df['Created Date'] >= start_date) & (df['Created Date'] <= end_date)]
for i in range(len(json_data['x_columns'])):
x_column = json_data['x_columns'][i]
y_column = json_data['y_columns'][i]
graph_type = json_data['graph_types'][i]
if None in (x_column, y_column, graph_type): # Skip if any required field is not selected
continue
if json_data['aggregations'] == 'None':
if graph_type == 'bar':
fig = px.bar(filtered_df, x=x_column, y=y_column, color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
fig = px.line(filtered_df, x=x_column, y=y_column, color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
fig = px.pie(filtered_df, names=x_column, values=y_column, hole=0.4,
color_discrete_sequence=color_palette)
else:
if graph_type == 'bar':
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.bar(filtered_df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'], color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.line(filtered_df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'],
color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.pie(filtered_df.groupby(x_column)[y_column].sum().reset_index(), names=x_column,
values=status['Sum'],
hole=0.4, color_discrete_sequence=color_palette)
fig.update_layout(
title=f'{y_column} vs {x_column}',
xaxis_title=x_column,
yaxis_title=y_column
)
figures.append(fig)
if json_data['end_date'] is not None:
if json_data['column'] is not None:
filtered_df = df[(df['Created Date'] >= json_data['start_date']) & (df['Created Date'] <= json_data['end_date'])]
if json_data['column'] and json_data['values']:
filtered_df = filtered_df[filtered_df[json_data['column']].isin(json_data['values'])]
for i in range(len(json_data['x_columns'])):
print(i)
x_column = json_data['x_columns'][i]
y_column = json_data['y_columns'][i]
graph_type = json_data['graph_types'][i]
# if None in (x_column, y_column, graph_type): # Skip if any required field is not selected
# continue
if json_data['aggregations'] == 'None':
if graph_type == 'bar':
fig = px.bar(filtered_df, x=x_column, y=y_column, color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
fig = px.line(filtered_df, x=x_column, y=y_column,
color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
fig = px.pie(filtered_df, names=x_column, values=y_column, hole=0.4,
color_discrete_sequence=color_palette)
else:
if graph_type == 'bar':
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.bar(filtered_df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'], color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.line(filtered_df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'],
color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.pie(filtered_df.groupby(x_column)[y_column].sum().reset_index(),
names=x_column,
values=status['Sum'],
hole=0.4, color_discrete_sequence=color_palette)
fig.update_layout(
title=f'{y_column} vs {x_column}',
xaxis_title=x_column,
yaxis_title=y_column
)
figures.append(fig)
return figures
elif board_name is None:
if generate > 0:
def get_dataframe(_params):
obj = client.get_object(
Bucket='bentolabs-test-propflo-dashboard',
Key=f'data-mart/{_params["!entity"]}/{_params["project"]}/leads.csv'
)
dataframe = pd.read_csv(obj['Body'], low_memory=False)
return dataframe
df = get_dataframe(params)
figures = []
if n_clicks > 0:
filtered_df = df[(df['Created Date'] >= start_date) & (df['Created Date'] <= end_date)]
if column and values:
filtered_df = filtered_df[filtered_df[column].isin(values)]
figures = []
for i in range(len(x_columns)):
x_column = x_columns[i]
y_column = y_columns[i]
graph_type = graph_types[i]
if None in (x_column, y_column, graph_type): # Skip if any required field is not selected
continue
if aggregations == 'None':
if graph_type == 'bar':
fig = px.bar(filtered_df, x=x_column, y=y_column, color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
fig = px.line(filtered_df, x=x_column, y=y_column, color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
fig = px.pie(filtered_df, names=x_column, values=y_column, hole=0.4,
color_discrete_sequence=color_palette)
else:
if graph_type == 'bar':
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.bar(filtered_df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'], color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.line(filtered_df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'],
color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
status = filtered_df.groupby(x_column).size().reset_index(name='Sum')
fig = px.pie(filtered_df.groupby(x_column)[y_column].sum().reset_index(), names=x_column,
values=status['Sum'],
hole=0.4, color_discrete_sequence=color_palette)
fig.update_layout(
title=f'{y_column} vs {x_column}',
xaxis_title=x_column,
yaxis_title=y_column
)
figures.append(fig)
return figures
else:
for i in range(len(x_columns)):
x_column = x_columns[i]
y_column = y_columns[i]
graph_type = graph_types[i]
if None in (x_column, y_column, graph_type): # Skip if any required field is not selected
continue
if aggregations == 'None':
if graph_type == 'bar':
fig = px.bar(df, x=x_column, y=y_column, color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
fig = px.line(df, x=x_column, y=y_column, color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
fig = px.pie(df, names=x_column, values=y_column, hole=0.4,
color_discrete_sequence=color_palette)
else:
if graph_type == 'bar':
status = df.groupby(x_column).size().reset_index(name='Sum')
fig = px.bar(df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'], color=x_column)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
elif graph_type == 'line':
status = df.groupby(x_column).size().reset_index(name='Sum')
fig = px.line(df.groupby(x_column)[y_column].sum().reset_index(), x=x_column,
y=status['Sum'],
color_discrete_sequence=color_palette)
fig.update_traces(marker=dict(line=dict(color='#FFF', width=0.5)))
else:
status = df.groupby(x_column).size().reset_index(name='Sum')
fig = px.pie(df.groupby(x_column)[y_column].sum().reset_index(), names=x_column,
values=status['Sum'],
hole=0.4, color_discrete_sequence=color_palette)
fig.update_layout(
title=f'{y_column} vs {x_column}',
xaxis_title=x_column,
yaxis_title=y_column
)
figures.append(fig)
return figures
elif board_name is not None:
if z_clicks > 0:
Data = {
'column': column,
'values': values,
'x_columns': x_columns,
'y_columns': y_columns,
'graph_types': graph_types,
'aggregations': aggregations,
'start_date': start_date,
'end_date': end_date,
'board_name': board_name
}
with open("data.json", "w") as outfile:
json.dump(Data, outfile)
client.upload_file(
"data.json",
'bentolabs-test-propflo-dashboard',
f'data-mart/{params["!entity"]}/{params["project"]}/{board_name}.json'
)
except Exception as e:
raise e
if __name__ == '__main__':
app.run_server(debug=True)`Preformatted text`
> Blockquote
Hi, you’ll need a dcc.Graph()
for each figure you want to show.
You could however create a figure including subplots which I would not recommend.
see my full code bro I think you might understand
d
Hi @krishnateja sorry, I’m not going to go thru all the code you posted.
Please try breaking down your problem into a minimal example.
hi @krishnateja
To increase the chances of community members understanding your code and finding an answer, it’s best to follow this guideline.
Make sure your code is formatted correctly and that you provide sample code with with sample data that can be reproduced locally when we run your code on our computers.
Hello @adamschroeder thanks from your advice now can anyone refer the code and give me a solution if possible please.
dbc.Col([
dcc.Graph(id=f'graph{new_graph_index}', config={'displaylogo': False})
], width=10)
@app.callback(
[Output(f'graph{cid}', 'figure') for cid in range(2)],
I have changed my layout in this way but I’m getting id not found error