Skip to content

Commit 79dcad2

Browse files
committed
DM-6726 Default chart and other optimizations
1 parent eafcba2 commit 79dcad2

16 files changed

+672
-197
lines changed

src/firefly/html/demo/ffapi-highlevel-test.html

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@
196196
firefly.showTable('tables-2', tblReq2, {removable: false, showUnits: true, showFilters: true});
197197
//----------------- CHART DEMO ------------------------//
198198
//--- using QUERY_ID: 'upload' does not work getActiveTableId('upload') returns undefined ---//
199-
firefly.addXYPlot('xyPlot1', {tbl_id: tblReq2.tbl_id, xCol: 'ra1+ra2', yCol: 'dec1+dec2'});
200-
firefly.addXYPlot('xyPlot2', {tbl_id: tblReq2.tbl_id, xCol: 'dtanneal', yCol: 'febgain'});
199+
firefly.addXYPlot('xyPlot1', {tbl_id: tblReq2.tbl_id, xCol: 'w1mpro+w4mpro', yCol: 'w2mpro'});
200+
firefly.addXYPlot('xyPlot2', {tbl_id: tblReq2.tbl_id, xCol: 'ra', yCol: 'dec'});
201201

202202
//-----< old table api ------//
203203
var tblParams = {

src/firefly/java/edu/caltech/ipac/firefly/server/util/QueryUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ public static DataGroup doDecimation(DataGroup dg, DecimateInfo decimateInfo) {
650650
if (!doDecimation) {
651651
DataObject retrow = new DataObject(retval);
652652
retrow.setDataElement(columns[0], convertData(xColClass,xval));
653-
retrow.setDataElement(columns[1], convertData(xColClass,yval));
653+
retrow.setDataElement(columns[1], convertData(yColClass,yval));
654654
retrow.setDataElement(columns[2], rIdx); // natural index
655655
retval.add(retrow);
656656
} else if (checkDeciLimits) {

src/firefly/js/FFEntryPoint.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ if (app) {
4646
{label:'Catalogs CLASSIC', action:'IrsaCatalogDropDown'},
4747
{label:'Test Searches', action:'TestSearches'},
4848
{label:'Images', action:'ImageSelectDropDownCmd'},
49+
{label:'Charts', action:'ChartSelectDropDownCmd'},
4950
{label:'Help', action:HELP_LOAD, type:'COMMAND'},
5051
{label:'Example Js Dialog', action:'exampleDialog', type:'COMMAND'}
5152
]

src/firefly/js/api/ApiHighlevelBuild.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,14 +407,14 @@ function showXYPlot(llApi, targetDiv, params={}) {
407407
const new_tblId = getActiveTableId(tblGroup);
408408
if (new_tblId !== tblId) {
409409
tblId = new_tblId;
410-
dispatchSetupTblTracking(tblId);
411410
loadPlotDataForTbl(tblId, chartId, xyPlotParams);
411+
dispatchSetupTblTracking(tblId);
412412
}
413413
});
414414
}
415415
if (tblId) {
416-
dispatchSetupTblTracking(tblId);
417416
loadPlotDataForTbl(tblId, chartId, xyPlotParams);
417+
dispatchSetupTblTracking(tblId);
418418
}
419419

420420

@@ -424,7 +424,8 @@ function showXYPlot(llApi, targetDiv, params={}) {
424424
tblId,
425425
chartId,
426426
closeable: false,
427-
expandedMode: false
427+
expandedMode: false,
428+
deletable: false
428429
}
429430
);
430431
}

src/firefly/js/api/ApiUtilChart.jsx

Lines changed: 1 addition & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
/*
22
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
33
*/
4-
import {take} from 'redux-saga/effects';
5-
6-
import {dispatchAddSaga} from '../core/MasterSaga.js';
7-
import * as TablesCntlr from '../tables/TablesCntlr.js';
8-
import * as TableUtil from '../tables/TableUtil.js';
94

105
import * as XYPlotCntlr from '../visualize/XYPlotCntlr.js';
116
//import * as HistogramCntlr from '../visualize/HistogramCntlr.js';
@@ -14,22 +9,5 @@ import * as XYPlotCntlr from '../visualize/XYPlotCntlr.js';
149
export {uniqueChartId} from '../visualize/ChartUtil.js';
1510

1611
export function loadPlotDataForTbl(tblId, chartId, xyPlotParams) {
17-
dispatchAddSaga(getChart, {tblId, chartId, xyPlotParams});
12+
XYPlotCntlr.dispatchLoadPlotData(chartId, xyPlotParams, tblId);
1813
}
19-
20-
export function* getChart({tblId, chartId, xyPlotParams}) {
21-
22-
if (TableUtil.isFullyLoaded(tblId)) {
23-
XYPlotCntlr.dispatchLoadPlotData(chartId, xyPlotParams, TableUtil.getTblById(tblId)['request']);
24-
return;
25-
}
26-
27-
while (true) {
28-
const action = yield take([TablesCntlr.TABLE_NEW_LOADED]);
29-
const {tbl_id, request} = action.payload;
30-
if (tbl_id === tblId) {
31-
XYPlotCntlr.dispatchLoadPlotData(chartId, xyPlotParams, request);
32-
return;
33-
}
34-
}
35-
}
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
/*
2+
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
3+
*/
4+
5+
import React, { Component, PropTypes} from 'react';
6+
import sCompare from 'react-addons-shallow-compare';
7+
import {get} from 'lodash';
8+
// import {deepDiff} from '../util/WebUtil.js';
9+
10+
import {flux} from '../Firefly.js';
11+
import * as TblUtil from '../tables/TableUtil.js';
12+
import * as TableStatsCntlr from '../visualize/TableStatsCntlr.js';
13+
import * as XYPlotCntlr from '../visualize/XYPlotCntlr.js';
14+
import * as HistogramCntlr from '../visualize/HistogramCntlr.js';
15+
import XYPlotOptions from '../visualize/XYPlotOptions.jsx';
16+
import {resultsSuccess as onXYPlotOptsSelected} from '../visualize/XYPlotOptions.jsx';
17+
import HistogramOptions from '../visualize/HistogramOptions.jsx';
18+
import {resultsSuccess as onHistogramOptsSelected} from '../visualize/HistogramOptions.jsx';
19+
//import {uniqueChartId} from '../visualize/ChartUtil.js';
20+
21+
import FormPanel from './FormPanel.jsx';
22+
import {dispatchHideDropDown} from '../core/LayoutCntlr.js';
23+
24+
import LOADING from 'html/images/gxt/loading.gif';
25+
26+
const dropdownName = 'ChartSelectDropDownCmd';
27+
28+
const SCATTER = 'scatter';
29+
const HISTOGRAM = 'histogram';
30+
const PREF_CHART_TYPE = 'pref.chartType';
31+
32+
function getFormName(chartType) {
33+
return chartType+'ChartOpts';
34+
}
35+
36+
/**
37+
*
38+
* @param props
39+
* @return {XML}
40+
* @constructor
41+
*/
42+
class ChartSelect extends Component {
43+
constructor(props) {
44+
super(props);
45+
46+
this.state = {
47+
chartType: localStorage.getItem(PREF_CHART_TYPE) || SCATTER
48+
};
49+
50+
this.onChartTypeChange = this.onChartTypeChange.bind(this);
51+
}
52+
53+
onChartTypeChange(ev) {
54+
// the value of the group is the value of the selected option
55+
var val = ev.target.value;
56+
var checked = ev.target.checked;
57+
58+
if (checked) {
59+
if (val !== this.state.chartType) {
60+
localStorage.setItem(PREF_CHART_TYPE, val);
61+
this.setState({chartType : val});
62+
}
63+
}
64+
}
65+
66+
renderChartSelection() {
67+
const {chartType} = this.state;
68+
const fieldKey = 'chartType';
69+
return (
70+
<div style={{display:'block', whiteSpace: 'nowrap'}}>
71+
<input type='radio'
72+
name={fieldKey}
73+
value={SCATTER}
74+
defaultChecked={chartType===SCATTER}
75+
onChange={this.onChartTypeChange}
76+
/> Scatter Plot&nbsp;&nbsp;
77+
<input type='radio'
78+
name={fieldKey}
79+
value={HISTOGRAM}
80+
defaultChecked={chartType===HISTOGRAM}
81+
onChange={this.onChartTypeChange}
82+
/> Histogram&nbsp;&nbsp;
83+
</div>
84+
);
85+
}
86+
87+
render() {
88+
const {tblId, tblStatsData} = this.props;
89+
const {chartType} = this.state;
90+
const formName = getFormName(chartType);
91+
92+
const resultSuccess = (flds) => {
93+
//const chartId = uniqueChartId(chartType);
94+
const chartId = tblId; // before chart container is available we support one chart per table
95+
switch (chartType) {
96+
case SCATTER:
97+
onXYPlotOptsSelected((xyPlotParams) => {
98+
XYPlotCntlr.dispatchLoadPlotData(chartId, xyPlotParams, tblId);
99+
}, flds);
100+
break;
101+
case HISTOGRAM:
102+
onHistogramOptsSelected((histogramParams) => {
103+
HistogramCntlr.dispatchLoadColData(chartId, histogramParams, tblId);
104+
}, flds);
105+
break;
106+
}
107+
hideSearchPanel();
108+
};
109+
110+
return (
111+
<div style={{padding:10, overflow:'auto', maxWidth:350, maxheight:500}}>
112+
<FormPanel
113+
groupKey={formName}
114+
onSubmit={resultSuccess}
115+
onCancel={hideSearchPanel}>
116+
{this.renderChartSelection()}
117+
<OptionsWrapper {...{tblStatsData, chartType}}/>
118+
</FormPanel>
119+
120+
</div>);
121+
}
122+
}
123+
124+
ChartSelect.propTypes = {
125+
tblId: PropTypes.string,
126+
tblStatsData : PropTypes.object
127+
};
128+
129+
130+
function hideSearchPanel() {
131+
dispatchHideDropDown();
132+
}
133+
134+
export class OptionsWrapper extends React.Component {
135+
constructor(props) {
136+
super(props);
137+
}
138+
139+
shouldComponentUpdate(np, ns) {
140+
return sCompare(this, np, ns);
141+
}
142+
143+
// componentDidUpdate(prevProps, prevState) {
144+
// deepDiff({props: prevProps, state: prevState},
145+
// {props: this.props, state: this.state},
146+
// this.constructor.name);
147+
// }
148+
149+
render() {
150+
const {tblStatsData, chartType} = this.props;
151+
152+
if (get(tblStatsData,'isColStatsReady')) {
153+
const formName = getFormName(chartType);
154+
if (chartType === SCATTER) {
155+
return (
156+
<XYPlotOptions key={formName} groupKey={formName}
157+
colValStats={tblStatsData.colStats}/>
158+
);
159+
} else {
160+
return (
161+
<HistogramOptions key={formName} groupKey = {formName}
162+
colValStats={tblStatsData.colStats}/>
163+
);
164+
}
165+
} else {
166+
return (<img style={{verticalAlign:'top', height: 16, padding: 10, float: 'left'}}
167+
title='Loading Options...'
168+
src={LOADING}
169+
/>);
170+
}
171+
}
172+
}
173+
174+
OptionsWrapper.propTypes = {
175+
tblStatsData : PropTypes.object,
176+
chartType: PropTypes.string
177+
};
178+
179+
180+
181+
182+
export class ChartSelectDropdown extends Component {
183+
184+
constructor(props) {
185+
super(props);
186+
this.state = this.getNextState();
187+
}
188+
189+
shouldComponentUpdate(np, ns) {
190+
return sCompare(this, np, ns);
191+
}
192+
193+
// componentDidUpdate(prevProps, prevState) {
194+
// deepDiff({props: prevProps, state: prevState},
195+
// {props: this.props, state: this.state},
196+
// this.constructor.name);
197+
// }
198+
199+
componentDidMount() {
200+
this.removeListener = flux.addListener(() => this.storeUpdate());
201+
this.iAmMounted= true;
202+
}
203+
204+
componentWillUnmount() {
205+
this.iAmMounted= false;
206+
this.removeListener && this.removeListener();
207+
}
208+
209+
getNextState() {
210+
const tblId = TblUtil.getActiveTableId(this.props.tblGroup);
211+
const tblStatsData = tblId && flux.getState()[TableStatsCntlr.TBLSTATS_DATA_KEY][tblId];
212+
return {tblId, tblStatsData};
213+
}
214+
215+
storeUpdate() {
216+
if (this.iAmMounted) {
217+
const {tblId, tblStatsData} = this.getNextState();
218+
if (tblId !== this.state.tblId || tblStatsData !== this.state.tblStatsData) {
219+
this.setState(this.getNextState());
220+
}
221+
}
222+
}
223+
224+
render() {
225+
const {tblId, tblStatsData} = this.state;
226+
return tblId ? (
227+
<ChartSelect {...{tblId, tblStatsData}} {...this.props}/>
228+
) : (
229+
<div style={{padding:20, fontSize:'150%'}}>Charts are not available: no active table.</div>
230+
);
231+
}
232+
}
233+
234+
ChartSelectDropdown.propTypes = {
235+
tblGroup: PropTypes.string, // if not present, default table group is used
236+
name: PropTypes.oneOf([dropdownName])
237+
};
238+
239+
240+
ChartSelectDropdown.defaultProps = {
241+
name: dropdownName
242+
};

0 commit comments

Comments
 (0)