Skip to content

Commit

Permalink
dash: seperate out selection updates from result updates, for perform…
Browse files Browse the repository at this point in the history
…ance reasons
  • Loading branch information
naterush committed Oct 5, 2023
1 parent ba6cd87 commit e48a8aa
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 40 deletions.
50 changes: 27 additions & 23 deletions mitosheet/dash_usage.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,39 @@
from unittest.mock import patch
from dash import Dash, dcc, html, Input, Output, callback, State
from dash import Dash, callback, Input, Output, html, dcc
from mitosheet.mito_dash.v1 import Spreadsheet, mito_callback
import pandas as pd

app = Dash(__name__)

app.layout = html.Div([
html.H6("Change the value in the text box to see callbacks in action!"),
html.Div([
"Input: ",
dcc.Input(id='my-input', value='initial value', type='text')
]),
Spreadsheet(id='my-spreadsheet'),
html.Br(),
html.Div(id='my-output'),
df = pd.DataFrame({'A': [1, 2, 3]})

app.layout = html.Div([
html.H1("Stock Analysis", style={'color': 'white'}),
Spreadsheet(df, id='sheet'),
html.Div(id='output-code'),
html.Div(id='output-selection'),
])





@mito_callback(
Output(component_id='my-output', component_property='children'),
Input(component_id='my-spreadsheet', component_property='return_value'),
prevent_initial_call=True
Output('output-code', 'children'),
Input('sheet', 'spreadsheet_result'),
)
def update_output_div(result):
print("HERE!")
result = result.selection()
return f'Output: {result}'
def update_code(spreadsheet_result):
print("NEW SPREADSHEET RESULT")
return html.Div([
html.Code(spreadsheet_result.code(), style={'color': 'white'})
])


@mito_callback(
Output('output-selection', 'children'),
Input('sheet', 'spreadsheet_selection'),
)
def update_selection(new_selection):
print("NEW SPREADSHEET SELECTION")
return html.Div([
html.Code(str(new_selection), style={'color': 'white'})
])


if __name__ == '__main__':
app.run(debug=True)
app.run_server(debug=True)
9 changes: 7 additions & 2 deletions mitosheet/mitosheet/mito_dash/v1/mito_callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ def mito_callback(*args, **kwargs):
def function_wrapper(original_function):
# TODO: do we need an @wraps
def new_function(*_args, **_kwargs):
print("CALLING CALLBACK")
new_args = list(_args)

# TODO: do we need to handle kwargs? Probably. But we will do that in the future...
Expand All @@ -58,7 +57,13 @@ def new_function(*_args, **_kwargs):
# TODO: use a more dash exception?
raise Exception(f"Could not find spreadsheet with id {id}")

new_args[index] = spreadsheet.get_result()
if 'spreadsheet_result' in arg:
# If the user is getting the result, give them the result
new_args[index] = spreadsheet.get_result()
else:
# If they are just getting the selection, just get the current selection
new_args[index] = spreadsheet.get_result().selection()


return original_function(*new_args, **_kwargs)

Expand Down
8 changes: 3 additions & 5 deletions mitosheet/mitosheet/mito_dash/v1/spreadsheet.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,12 +126,12 @@ def handle_message(msg):
@callback(
Output(self.mito_id, 'all_json', allow_duplicate=True),
Output(self.mito_id, 'spreadsheet_selection', allow_duplicate=True),
Input(self.mito_id, 'selection'), prevent_initial_call=True
Input(self.mito_id, 'index_and_selections'), prevent_initial_call=True
)
def handle_selection_change(selection):
def handle_selection_change(index_and_selections):
self.num_messages += 1

self.index_and_selections = selection
self.index_and_selections = index_and_selections

self.spreadsheet_selection = WRONG_CALLBACK_ERROR_MESSAGE.format(prop_name='spreadsheet_selection', num_messages=self.num_messages, id=self.mito_id)
return self.get_all_json(), self.spreadsheet_selection
Expand Down Expand Up @@ -236,7 +236,6 @@ def process_single_message(self):
self.processing_messages = False

self.spreadsheet_result = WRONG_CALLBACK_ERROR_MESSAGE.format(prop_name='spreadsheet_result', num_messages=self.num_messages, id=self.mito_id)
print("NEW RESULT", self.spreadsheet_result)


def get_all_json(self) -> str:
Expand All @@ -247,7 +246,6 @@ def get_all_json(self) -> str:
})

def get_result(self):
print(self.mito_backend.steps_manager)
return SpreadsheetResult(
dfs=self.mito_backend.steps_manager.dfs,
code=self.mito_backend.steps_manager.code(),
Expand Down
23 changes: 13 additions & 10 deletions mitosheet/src/dash/MitoDashWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import { getAnalysisDataFromString, getSheetDataArrayFromString, getUserProfileF

export const DELAY_BETWEEN_SET_DASH_PROPS = 25;

// TODO: Update
type PropNameForSetProps = 'message' | 'index_and_selections';

interface State {
responses: MitoResponse[],
analysisName: string,
messageQueue: Record<string, any>[],
messageQueue: [PropNameForSetProps, Record<string, any>][],
isSendingMessages: boolean,
}

Expand Down Expand Up @@ -101,16 +103,16 @@ export default class MitoDashWrapper extends Component<Props, State> {
processQueue = () => {
if (this.state.messageQueue.length > 0) {
// Send one message
const message = this.state.messageQueue[0];
const [messageType, message] = this.state.messageQueue[0];
this.props.setProps({
'message': message
[messageType]: message
})

// Remove the processed message from the queue - making sure
// to avoid merge conflicts by finding by value
this.setState((prevState) => {
const messageQueue = [...prevState.messageQueue];
const index = messageQueue.findIndex((m) => m === message);
const index = messageQueue.findIndex((m) => m[1] === message);
messageQueue.splice(index, 1);

return {
Expand All @@ -127,7 +129,7 @@ export default class MitoDashWrapper extends Component<Props, State> {
}
};

handleMitoEvent = (message: Record<string, unknown>) => {
handleMitoEvent = (propName: PropNameForSetProps, message: Record<string, unknown>) => {
// TODO: I think we have to check the origin here, but I'm not sure
// how to do that.

Expand All @@ -139,7 +141,7 @@ export default class MitoDashWrapper extends Component<Props, State> {

// Add the message to the queue
this.setState((prevState) => ({
messageQueue: [...prevState.messageQueue, message],
messageQueue: [...prevState.messageQueue, [propName, message]],
}));

// Do some work to make sure we avoid race conditions. Namely, we only want to
Expand All @@ -159,7 +161,7 @@ export default class MitoDashWrapper extends Component<Props, State> {


public async send(msg: Record<string, unknown>): Promise<SendFunctionReturnType<any>> {
this.handleMitoEvent(msg);
this.handleMitoEvent('message', msg);
const response = await this.getResponseData(msg['id'] as string);
return response;
}
Expand Down Expand Up @@ -194,8 +196,6 @@ export default class MitoDashWrapper extends Component<Props, State> {
this.setState({responses: responses});
}

console.log('analsyisData', analysisData.theme)

return (
<Mito
key={key as string}
Expand All @@ -205,7 +205,10 @@ export default class MitoDashWrapper extends Component<Props, State> {
userProfile={userProfile}
theme={analysisData.theme ?? undefined}
onSelectionChange={(selectedDataframeIndex, selections) => {
// TODO: handle this properly!
this.handleMitoEvent('index_and_selections', {
selectedDataframeIndex,
selections
});
}}
/>
)
Expand Down

0 comments on commit e48a8aa

Please sign in to comment.