Skip to content

Commit

Permalink
Bug fixes
Browse files Browse the repository at this point in the history
 - #28 "Instances" menu option will now be displayed by default
 - #29 add hints to how users can navigate the correlations popup
 - add "unicode" as a string classification for column width calculation
  • Loading branch information
Andrew Schonfeld committed Nov 12, 2019
1 parent 8f21de6 commit 6a6d0f4
Show file tree
Hide file tree
Showing 11 changed files with 69 additions and 47 deletions.
4 changes: 2 additions & 2 deletions static/__tests__/dtale/DataViewer-base-test.jsx
Expand Up @@ -90,7 +90,7 @@ describe("DataViewer tests", () => {
.find(DataViewerMenu)
.find("ul li span.font-weight-bold")
.map(s => s.text()),
["Describe", "Filter", "Correlations", "Coverage", "Resize", "About", "Shutdown"],
["Describe", "Filter", "Correlations", "Coverage", "Resize", "About", "Instances 1", "Shutdown"],
"Should render default menu options"
);

Expand Down Expand Up @@ -119,7 +119,7 @@ describe("DataViewer tests", () => {
.map(s => s.text()),
_.concat(
["Describe", "Move To Front", "Lock", "Sort Ascending", "Sort Descending", "Clear Sort", "Filter", "Formats"],
["Histogram", "Correlations", "Coverage", "Resize", "About", "Shutdown"]
["Histogram", "Correlations", "Coverage", "Resize", "About", "Instances 1", "Shutdown"]
),
"Should render menu options associated with selected column"
);
Expand Down
2 changes: 1 addition & 1 deletion static/__tests__/dtale/DataViewerInfo-test.jsx
Expand Up @@ -2,7 +2,7 @@ import { mount } from "enzyme";
import React from "react";

import { RemovableError } from "../../RemovableError";
import DataViewerInfo from "../../dtale/DataViewerInfo";
import { DataViewerInfo } from "../../dtale/DataViewerInfo";
import * as t from "../jest-assertions";
import { buildInnerHTML } from "../test-utils";

Expand Down
4 changes: 2 additions & 2 deletions static/__tests__/dtale/DataViewerMenu-test.jsx
Expand Up @@ -43,7 +43,7 @@ describe("DataViewerMenu tests", () => {
result
.find("ul li span.toggler-action")
.last()
.text() === "About",
.text() === "Instances 1",
"should hide shutdown"
);
done();
Expand All @@ -64,7 +64,7 @@ describe("DataViewerMenu tests", () => {
result
.find("ul li span.toggler-action")
.last()
.text() === "Instances",
.text() === "Instances 2",
"should show instances"
);
done();
Expand Down
36 changes: 20 additions & 16 deletions static/dtale/DataViewer.jsx
Expand Up @@ -11,7 +11,7 @@ import MultiGrid from "react-virtualized/dist/commonjs/MultiGrid";
import { buildURLParams, buildURLString } from "../actions/url-utils";
import { fetchJsonPromise, logException } from "../fetcher";
import { Popup } from "../popups/Popup";
import DataViewerInfo from "./DataViewerInfo";
import { DataViewerInfo, hasNoInfo } from "./DataViewerInfo";
import { DataViewerMenu } from "./DataViewerMenu";
import Filter from "./Filter";
import { Formatting } from "./Formatting";
Expand Down Expand Up @@ -238,8 +238,7 @@ class ReactDataViewer extends React.Component {
logException(e, callstack);
});
};
return [
<DataViewerInfo key={0} {...this.state} propagateState={this.propagateState} />,
return (
<div key={1} style={{ height: "100%", width: "100%" }}>
<InfiniteLoader
isRowLoaded={({ index }) => _.has(this.state, ["data", index])}
Expand All @@ -249,17 +248,22 @@ class ReactDataViewer extends React.Component {
this._onRowsRendered = onRowsRendered;
return (
<AutoSizer className="main-grid" onResize={() => this._grid.recomputeGridSize()}>
{({ width, height }) => (
<MultiGrid
{...this.state}
cellRenderer={this._cellRenderer}
height={height - 3}
width={width - 3}
columnWidth={({ index }) => gu.getColWidth(index, this.state)}
onSectionRendered={this._onSectionRendered}
ref={mg => (this._grid = mg)}
/>
)}
{({ width, height }) => {
const gridHeight = height - (hasNoInfo(this.state) ? 3 : 23);
return [
<DataViewerInfo key={0} width={width} {...this.state} propagateState={this.propagateState} />,
<MultiGrid
{...this.state}
key={1}
cellRenderer={this._cellRenderer}
height={gridHeight}
width={width - 3}
columnWidth={({ index }) => gu.getColWidth(index, this.state)}
onSectionRendered={this._onSectionRendered}
ref={mg => (this._grid = mg)}
/>,
];
}}
</AutoSizer>
);
}}
Expand All @@ -269,8 +273,8 @@ class ReactDataViewer extends React.Component {
<Filter {...{ visible: filterOpen, propagateState: this.propagateState, query }} />
<Formatting {...{ visible: formattingOpen, save: saveFormatting, propagateState: this.propagateState }} />
<MeasureText />
</div>,
];
</div>
);
}
}
ReactDataViewer.displayName = "ReactDataViewer";
Expand Down
11 changes: 8 additions & 3 deletions static/dtale/DataViewerInfo.jsx
Expand Up @@ -5,12 +5,16 @@ import React from "react";
import ConditionalRender from "../ConditionalRender";
import { RemovableError } from "../RemovableError";

function hasNoInfo({ selectedCols, sortInfo, query }) {
return _.isEmpty(selectedCols) && _.isEmpty(sortInfo) && _.isEmpty(query);
}

class DataViewerInfo extends React.Component {
render() {
const { error, propagateState } = this.props;
if (error) {
return (
<div className="row">
<div style={{ width: this.props.width || "100%" }} className="row">
<div className="col-md-12">
<RemovableError {...this.props} onRemove={() => propagateState({ error: null, traceback: null })} />
</div>
Expand All @@ -24,7 +28,7 @@ class DataViewerInfo extends React.Component {
return null;
}
return (
<div className="row text-center">
<div style={{ width: this.props.width || "100%" }} className="row text-center">
<div className="col-md-4">
<ConditionalRender display={!hideSelected}>
<div className="font-weight-bold d-inline-block">Selected:</div>
Expand Down Expand Up @@ -71,6 +75,7 @@ DataViewerInfo.propTypes = {
query: PropTypes.string,
propagateState: PropTypes.func,
error: PropTypes.string,
width: PropTypes.number,
};

export default DataViewerInfo;
export { DataViewerInfo, hasNoInfo };
21 changes: 11 additions & 10 deletions static/dtale/DataViewerMenu.jsx
Expand Up @@ -209,16 +209,17 @@ class ReactDataViewerMenu extends React.Component {
</button>
</span>
</li>
<ConditionalRender display={processCt > 1}>
<li>
<span className="toggler-action">
<button className="btn btn-plain" onClick={() => this.props.openChart({ type: "instances" })}>
<i className="ico-apps" />
<span className="font-weight-bold">Instances</span>
</button>
</span>
</li>
</ConditionalRender>
<li>
<span className="toggler-action">
<button className="btn btn-plain" onClick={() => this.props.openChart({ type: "instances" })}>
<i className="ico-apps" />
<span className="font-weight-bold">
{"Instances "}
<span className="badge badge-secondary">{processCt}</span>
</span>
</button>
</span>
</li>
<ConditionalRender display={hideShutdown == false}>
<li>
<span className="toggler-action">
Expand Down
2 changes: 1 addition & 1 deletion static/dtale/gridUtils.jsx
Expand Up @@ -10,7 +10,7 @@ const DEFAULT_COL_WIDTH = 70;
numeral.nullFormat("");

function isStringCol(dtype) {
return _.some(["string", "object"], s => dtype.startsWith(s));
return _.some(["string", "object", "unicode"], s => dtype.startsWith(s));
}

function isIntCol(dtype) {
Expand Down
11 changes: 7 additions & 4 deletions static/popups/Correlations.jsx
Expand Up @@ -169,6 +169,7 @@ class ReactCorrelations extends React.Component {
<div key="body" className="modal-body scatter-body">
<BouncerWrapper showBouncer={_.isEmpty(correlations)}>
<b>Pearson Correlation Matrix</b>
<small className="pl-3">(Click on any cell to view the details of that correlation)</small>
<AutoSizer className="correlations-grid" disableHeight>
{({ width }) => (
<MultiGrid
Expand All @@ -190,9 +191,12 @@ class ReactCorrelations extends React.Component {
</BouncerWrapper>
<ConditionalRender display={!_.isEmpty(selectedCols) && hasDate}>
<div className="row d-inline">
<b className="float-left pt-5">
{`Timeseries of Pearson Correlation for ${selectedCols[0]} vs. ${selectedCols[1]}`}
</b>
<div className="float-left pt-5">
<b>{`Timeseries of Pearson Correlation for ${selectedCols[0]} vs. ${selectedCols[1]}`}</b>
<small className="pl-3">
(Click on any point in the chart to view the scatter plot of that correlation)
</small>
</div>
<ConditionalRender display={_.size(dates) > 1}>
<div className="form-group row small-gutters float-right pt-5 pr-3">
<label className="col-form-label text-right">Date Column</label>
Expand All @@ -210,7 +214,6 @@ class ReactCorrelations extends React.Component {
ref={r => (this._ts_chart = r)}
url={tsUrl}
visible={true}
units="month"
configHandler={config => {
config.options.scales.yAxes = [
{
Expand Down
13 changes: 10 additions & 3 deletions static/popups/TimeseriesChartBody.jsx
Expand Up @@ -95,7 +95,11 @@ class TimeseriesChartBody extends React.Component {
chartUtils.fitToContainer(ctx);
let i = 0;
const yAxises = [];
let points = 0;
let datasets = _.map(chartData, (tsData, key) => {
if (tsData.data.length > points) {
points = tsData.data.length;
}
const dataset = this.props.datasetHandler(key, tsData.data, i++);
if (dataset.yAxisID && !_.find(yAxises, { id: dataset.yAxisID })) {
const axisCfg = { id: dataset.yAxisID };
Expand All @@ -107,14 +111,18 @@ class TimeseriesChartBody extends React.Component {
return dataset;
});
datasets = this.props.datasetSorter(datasets);
let units = this.props.units;
if (!units) {
units = points > 150 ? "month" : "day";
}
const scales = {
xAxes: [
{
type: "time",
time: {
unit: this.props.units,
unit: units,
displayFormats: {
[this.props.units]: "YYYYMMDD",
[units]: "YYYYMMDD",
},
min: _.get(datasets, "0.data.0.x"),
max: _.get(datasets, [0, "data", _.get(datasets, "0.data", []).length - 1, "x"]),
Expand Down Expand Up @@ -237,7 +245,6 @@ TimeseriesChartBody.propTypes = {
useMinMax: PropTypes.bool,
};
TimeseriesChartBody.defaultProps = {
units: "day",
height: 400,
chartOptions: {},
datasetHandler: defaultDatasetHandler,
Expand Down
11 changes: 6 additions & 5 deletions static/popups/correlations/CorrelationScatterStats.jsx
Expand Up @@ -15,11 +15,11 @@ class CorrelationScatterStats extends React.Component {
let i = 0;
const pearsonInfo = [<dt key={i++}>Pearson</dt>, <dd key={i++}>{corrUtils.percent(pearson)}</dd>];
const spearmanInfo = [<dt key={i++}>Spearman</dt>, <dd key={i++}>{corrUtils.percent(spearman)}</dd>];
return (
<div className="pt-5">
return [
<div key={0} className="pt-5">
<dl className="property-pair inline">
<dt>
<b>{`${col0} vs. ${col1}${this.props.date ? ` for ${this.props.date}` : ""}`}</b>
<b style={{ color: "black" }}>{`${col0} vs. ${col1}${this.props.date ? ` for ${this.props.date}` : ""}`}</b>
</dt>
</dl>
<dl className="property-pair inline">{pearsonInfo}</dl>
Expand All @@ -36,8 +36,9 @@ class CorrelationScatterStats extends React.Component {
<dt>{`Only in ${col1}`}</dt>
<dd>{stats.only_in_s1}</dd>
</dl>
</div>
);
</div>,
<small key={1}>(Click on any point in the scatter to filter the grid down to that record)</small>,
];
}
}
CorrelationScatterStats.displayName = "CorrelationScatterStats";
Expand Down
1 change: 1 addition & 0 deletions static/popups/correlations/correlationsUtils.jsx
Expand Up @@ -51,6 +51,7 @@ function createScatter(ctx, chartData, xProp, yProp, label, onClick) {
},
],
},
legend: { display: false },
pan: { enabled: true, mode: "x" },
zoom: { enabled: true, mode: "x" },
maintainAspectRatio: false,
Expand Down

0 comments on commit 6a6d0f4

Please sign in to comment.