Skip to content

Commit

Permalink
Bugfixes & Updates
Browse files Browse the repository at this point in the history
* #243: column menu descriptions
* #247: code export compilation error fixes
* #242: type conversion column menu option & auto-column names on "Build Column"
* #235: nan formatting
  • Loading branch information
aschonfeld committed Aug 20, 2020
1 parent 317465a commit 8368b09
Show file tree
Hide file tree
Showing 38 changed files with 932 additions and 436 deletions.
4 changes: 2 additions & 2 deletions dtale/charts/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def build_agg_data(df, x, y, inputs, agg, z=None, group_col=None, animate_by=Non
return agg_df, code

idx_cols = make_list(animate_by) + make_list(group_col) + [x]
agg_cols = y
agg_cols = make_list(y)
if z_exists:
idx_cols += make_list(y)
agg_cols = make_list(z)
Expand All @@ -374,7 +374,7 @@ def build_agg_data(df, x, y, inputs, agg, z=None, group_col=None, animate_by=Non
code = code.format(
cols="', '".join(idx_cols),
subidx_cols="', '".join(subidx_cols),
agg_cols="', '".join(agg_cols),
agg_cols="', '".join(make_list(agg_cols)),
agg=func,
)
code = [code]
Expand Down
44 changes: 22 additions & 22 deletions dtale/dash_application/charts.py
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ def scatter_code_builder(
z_code = "" if z is None else " z=chart_data['{z}'],".format(z=z)
code.append(
(
"\nimport plotly.graph_objects as go\n\n"
"\nimport plotly.graph_objs as go\n\n"
"chart = {scatter_func}(\n"
"\tx=chart_data['x'], y=chart_data['{y}'],{z} , mode='markers', opacity=0.7, name='{series_key}',\n"
"\tmarker={marker}\n"
Expand All @@ -681,10 +681,10 @@ def scatter_code_builder(
data = "chart, trendline"

layout_cfg = build_layout(
dict_merge(title, build_scatter_layout(axes_builder([y_val])[0], z),)
dict_merge(title, build_scatter_layout(axes_builder([y_val])[0], z))
)
code.append(
"figure = go.Figure(data=[{data}], layout={layout})".format(
"figure = go.Figure(data=[{data}], layout=go.{layout})".format(
data=data, layout=pp.pformat(layout_cfg)
)
)
Expand Down Expand Up @@ -747,7 +747,7 @@ def surface_builder(data, x, y, z, axes_builder, wrapper, agg=None, modal=False)
pp = pprint.PrettyPrinter(indent=4)
code.append(
(
"\nimport plotly.graph_objects as go\n\n"
"\nimport plotly.graph_objs as go\n\n"
"chart = go.Surface(\n"
"\tx=chart_data.columns, y=chart_data.index.values, z=chart_data.values, opacity=0.8, \n"
"\t colorscale='YlGnBu', colorbar={colorbar}\n"
Expand All @@ -756,7 +756,7 @@ def surface_builder(data, x, y, z, axes_builder, wrapper, agg=None, modal=False)
)
layout_cfg = build_layout(dict_merge(build_title(x, y[0], z=z, agg=agg), layout))
code.append(
"figure = go.Figure(data=[chart], layout={layout})".format(
"figure = go.Figure(data=[chart], layout=go.{layout})".format(
layout=pp.pformat(layout_cfg)
)
)
Expand Down Expand Up @@ -1102,7 +1102,7 @@ def bar_code_builder(
)

pp = pprint.PrettyPrinter(indent=4)
code.append(("\nimport plotly.graph_objects as go\n\n" "charts = []"))
code.append(("\nimport plotly.graph_objs as go\n\n" "charts = []"))
for i, y2 in enumerate(y, 1):
name = name_builder(y2, series_key)
chart_cfg = ["x={}".format(x_data), "y=chart_data['{}']".format(y2)]
Expand All @@ -1121,7 +1121,7 @@ def bar_code_builder(

layout_cfg = build_layout(dict_merge(title, axes, dict(barmode=barmode or "group")))
code.append(
"figure = go.Figure(data=charts, layout={layout})".format(
"figure = go.Figure(data=charts, layout=go.{layout})".format(
layout=pp.pformat(layout_cfg)
)
)
Expand Down Expand Up @@ -1284,7 +1284,7 @@ def line_code_builder(data, x, y, axes_builder, **inputs):
if len(data["data"]) > 1:
code.append(GROUP_WARNING.format(series_key=series_key))

code.append("\nimport plotly.graph_objects as go\n\n" "charts = []")
code.append("\nimport plotly.graph_objs as go\n\n" "charts = []")
pp = pprint.PrettyPrinter(indent=4)
code.append("line_cfg = {}".format(pp.pformat(build_line_cfg(series))))
for i, y2 in enumerate(y, 1):
Expand Down Expand Up @@ -1354,9 +1354,9 @@ def build_pie_code():
pp = pprint.PrettyPrinter(indent=4)
code.append(
(
"\nimport plotly.graph_objects as go\n\n"
"\nimport plotly.graph_objs as go\n\n"
"chart = go.Pie(labels=chart_data['x'], y=chart_data['{y}']{name})\n"
"figure = go.Figure(data=[chart], layout={layout})"
"figure = go.Figure(data=[chart], layout=go.{layout})"
).format(y=y[0], name=name, layout=pp.pformat(layout_cfg))
)
return code
Expand Down Expand Up @@ -1631,14 +1631,14 @@ def _build_heatmap_axis(col, data, title):
pp = pprint.PrettyPrinter(indent=4)
code.append(
(
"\nimport plotly.graph_objects as go\n\n"
"\nimport plotly.graph_objs as go\n\n"
"hm_kwargs = {hm_kwargs_str}\n"
"chart = {chart}"
).format(chart=heatmap_func_str, hm_kwargs_str=pp.pformat(hm_kwargs))
)

code.append(
"figure = go.Figure(data=[chart], layout={layout})".format(
"figure = go.Figure(data=[chart], layout=go.{layout})".format(
layout=pp.pformat(layout_cfg)
)
)
Expand Down Expand Up @@ -1785,10 +1785,10 @@ def candlestick_builder(data_id, export=False, **inputs):
)

pp = pprint.PrettyPrinter(indent=4)
code.append("\nimport plotly.graph_objects as go\n\n")
code.append("\nimport plotly.graph_objs as go\n\n")
code.append(candlestick_str)
code.append(
"figure = go.Figure(data=[chart], layout={layout})".format(
"figure = go.Figure(data=[chart], layout=go.{layout})".format(
layout=pp.pformat(layout_cfg)
)
)
Expand Down Expand Up @@ -1945,11 +1945,11 @@ def build_scattergeo(inputs, raw_data, layout):

code.append(
(
"\nimport plotly.graph_objects as go\n\n"
"\nimport plotly.graph_objs as go\n\n"
"chart = go.Scattergeo(\n"
"{code_kwargs}\n"
")\n"
"figure = go.Figure(data=[chart], layout={layout})"
"figure = go.Figure(data=[chart], layout=go.{layout})"
).format(
code_kwargs=",\n".join(map(lambda ck: "\t{}".format(ck), code_kwargs)),
layout=pp.pformat(layout),
Expand Down Expand Up @@ -2053,11 +2053,11 @@ def build_mapbox(inputs, raw_data, layout):

code.append(
(
"\nimport plotly.graph_objects as go\n\n"
"\nimport plotly.graph_objs as go\n\n"
"chart = go.Scattergeo(\n"
"{code_kwargs}\n"
")\n"
"figure = go.Figure(data=[chart], layout={layout})"
"figure = go.Figure(data=[chart], layout=go.{layout})"
).format(
code_kwargs=",\n".join(map(lambda ck: "\t{}".format(ck), code_kwargs)),
layout=pp.pformat(layout),
Expand Down Expand Up @@ -2122,7 +2122,7 @@ def build_choropleth(inputs, raw_data, layout):

data = data.dropna(subset=dupe_cols)
code.append(
"chart_data = chart_data.dropna(subset=['{}']".format(",".join(dupe_cols))
"chart_data = chart_data.dropna(subset=['{}'])".format(",".join(dupe_cols))
)
check_exceptions(data[dupe_cols], False, unlimited_data=True, **kwargs)

Expand Down Expand Up @@ -2165,7 +2165,7 @@ def build_choropleth(inputs, raw_data, layout):
pp = pprint.PrettyPrinter(indent=4)
code_kwargs = [
"locations=chart_data['{}']".format(props.loc),
"locationsmode='{}'".format(props.loc_mode),
"locationmode='{}'".format(props.loc_mode),
"z=chart_data['{}']".format(props.map_val),
"colorscale={}".format(pp.pformat(colorscale)),
"colorbar_title='{}'".format(props.map_val),
Expand All @@ -2177,11 +2177,11 @@ def build_choropleth(inputs, raw_data, layout):

code.append(
(
"\nimport plotly.graph_objects as go\n\n"
"\nimport plotly.graph_objs as go\n\n"
"chart = go.Choropleth(\n"
"{code_kwargs}\n"
")\n"
"figure = go.Figure(data=[chart], layout={layout})"
"figure = go.Figure(data=[chart], layout=go.{layout})"
).format(
code_kwargs=",\n".join(map(lambda ck: "\t{}".format(ck), code_kwargs)),
layout=pp.pformat(layout),
Expand Down
23 changes: 23 additions & 0 deletions dtale/static/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -4560,6 +4560,10 @@ div.upload-modal > div.modal-lg {
width: 400px;
}

div.type-conversion-modal > div.modal-lg {
width: 500px;
}

div.reshape-modal > div.modal-lg {
min-width: 800px;
}
Expand Down Expand Up @@ -4591,6 +4595,9 @@ div.xarray-indexes-modal > div.modal-lg{
div.code-modal > div.modal-lg {
max-width: 700px;
}
div.type-conversion-modal > div.modal-lg {
max-width: 500px;
}
}

.tooltip {
Expand Down Expand Up @@ -8713,6 +8720,22 @@ caption {
width: 100%;
}

.column-toggle__dropdown ul.col-menu-descriptors {
list-style: disc;
padding-left: 1.5em;
font-weight: normal;
}

.column-toggle__dropdown ul.col-menu-descriptors li {
border-bottom: 0;
display: list-item;
}

.column-toggle__dropdown ul.col-menu-descriptors li span {
padding-left: 0.25em;
font-weight: bold;
}

.column-toggle__dropdown li span {
padding: .3em;
}
Expand Down
6 changes: 4 additions & 2 deletions dtale/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ def json_string(x, nan_display="", **kwargs):
:return: string value
:rtype: str
"""
if pd.isnull(x):
return nan_display
if x or x in ["", False, 0]:
try:
return str(x)
Expand Down Expand Up @@ -806,9 +808,9 @@ def build_code_export(data_id, imports="import pandas as pd\n\n", query=None):
).format(query=final_query, data_id=data_id)
)
else:
final_history.append("df = df.query('{}')\n".format(final_query))
final_history.append('df = df.query("{}")\n'.format(final_query))
elif "query" in settings:
final_history.append("df = df.query('{}')\n".format(settings["query"]))
final_history.append('df = df.query("{}")\n'.format(settings["query"]))
if "sort" in settings:
cols, dirs = [], []
for col, dir in settings["sort"]:
Expand Down
9 changes: 7 additions & 2 deletions dtale/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -1048,6 +1048,9 @@ def update_formats(data_id):
:return: JSON
"""
update_all_dtype = get_bool_arg(request, "all")
nan_display = get_str_arg(request, "nanDisplay")
if nan_display is None:
nan_display = "nan"
col = get_str_arg(request, "col")
col_format = get_json_arg(request, "format")
curr_settings = global_state.get_settings(data_id) or {}
Expand All @@ -1060,7 +1063,9 @@ def update_formats(data_id):
if c["dtype"] == col_dtype
}
updated_formats = dict_merge(curr_settings.get("formats") or {}, updated_formats)
updated_settings = dict_merge(curr_settings, dict(formats=updated_formats))
updated_settings = dict_merge(
curr_settings, dict(formats=updated_formats, nanDisplay=nan_display)
)
global_state.set_settings(data_id, updated_settings)
return jsonify(dict(success=True))

Expand Down Expand Up @@ -1865,8 +1870,8 @@ def get_data(data_id):
return jsonify({})

col_types = global_state.get_dtypes(data_id)
f = grid_formatter(col_types, nan_display="nan")
curr_settings = global_state.get_settings(data_id) or {}
f = grid_formatter(col_types, nan_display=curr_settings.get("nanDisplay", "nan"))
if curr_settings.get("sort") != params.get("sort"):
data = sort_df_for_grid(data, params)
global_state.set_data(data_id, data)
Expand Down
14 changes: 7 additions & 7 deletions static/__tests__/dtale/create/bins-test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,13 +85,13 @@ describe("DataViewer tests", () => {
});

it("DataViewer: build bins cut column", async () => {
result
.find(CreateColumn)
.find("div.form-group")
.first()
.find("input")
.first()
.simulate("change", { target: { value: "cut_col" } });
// result
// .find(CreateColumn)
// .find("div.form-group")
// .first()
// .find("input")
// .first()
// .simulate("change", { target: { value: "cut_col" } });
result.find(CreateColumn).find("div.form-group").at(1).find("button").at(1).simulate("click");
result.update();
expect(result.find(CreateBins).length).toBe(1);
Expand Down
Loading

0 comments on commit 8368b09

Please sign in to comment.