From 77e1356f4ebc5ad5a0dea03da71bc65ab3c9b39e Mon Sep 17 00:00:00 2001 From: wmi Date: Wed, 29 Jun 2016 15:08:55 -0700 Subject: [PATCH 01/10] * The changes on tables related js are dealing with locally created tables and have them shown up in the basic table panel * Add XYPlot column select popup --- src/firefly/js/tables/TableConnector.js | 7 +- src/firefly/js/tables/TableUtil.js | 2 +- src/firefly/js/tables/ui/TableRenderer.js | 7 +- .../js/visualize/ColValuesStatistics.js | 3 +- src/firefly/js/visualize/XYPlotColView.jsx | 124 +++++++++++++++++ src/firefly/js/visualize/XYPlotOptions.jsx | 125 +++++++++++++----- 6 files changed, 230 insertions(+), 38 deletions(-) create mode 100644 src/firefly/js/visualize/XYPlotColView.jsx diff --git a/src/firefly/js/tables/TableConnector.js b/src/firefly/js/tables/TableConnector.js index b2dd881900..3b7584b05d 100644 --- a/src/firefly/js/tables/TableConnector.js +++ b/src/firefly/js/tables/TableConnector.js @@ -87,7 +87,12 @@ export class TableConnector { const {hlRowIdx, startIdx} = TblUtil.getTblInfoById(this.tbl_id); if (rowIdx !== hlRowIdx) { const highlightedRow = startIdx + rowIdx; - TblCntlr.dispatchTableHighlight(this.tbl_id, highlightedRow); + if (this.origTableModel) { + const tableModel = {tbl_id: this.tbl_id, highlightedRow}; + flux.process({type: TblCntlr.TABLE_UPDATE, payload: tableModel}); + } else { + TblCntlr.dispatchTableHighlight(this.tbl_id, highlightedRow); + } } } diff --git a/src/firefly/js/tables/TableUtil.js b/src/firefly/js/tables/TableUtil.js index 7f3616f07c..5a37855bcb 100644 --- a/src/firefly/js/tables/TableUtil.js +++ b/src/firefly/js/tables/TableUtil.js @@ -441,7 +441,7 @@ export function getTblInfo(tableModel, aPageSize) { const currentPage = highlightedRow >= 0 ? Math.floor(highlightedRow / pageSize)+1 : 1; const hlRowIdx = highlightedRow >= 0 ? highlightedRow % pageSize : 0; const startIdx = (currentPage-1) * pageSize; - const endIdx = Math.min(startIdx+pageSize, totalRows) || startIdx ; + const endIdx = Math.min(startIdx+pageSize, totalRows) || get(tableModel,'tableData.data.length', startIdx) ; var totalPages = Math.ceil((totalRows || 0)/pageSize); return { tableModel, tbl_id, title, totalRows, request, startIdx, endIdx, hlRowIdx, currentPage, pageSize,totalPages, highlightedRow, selectInfo, error}; } diff --git a/src/firefly/js/tables/ui/TableRenderer.js b/src/firefly/js/tables/ui/TableRenderer.js index 0fbdd94059..4d6434602f 100644 --- a/src/firefly/js/tables/ui/TableRenderer.js +++ b/src/firefly/js/tables/ui/TableRenderer.js @@ -177,12 +177,11 @@ export class TextCell extends React.Component { // } // render() { - const lineHeight = this.props.height - 6 + 'px'; // 6 is the top/bottom padding. - const style = Object.assign({lineHeight}, this.props.style || {}); var val = getValue(this.props); - val = (isString(val) && val.search(html_regex) >= 0) ?
: val; + const lineHeight = this.props.height - 6 + 'px'; // 6 is the top/bottom padding. + val = (val.search && val.search(html_regex) >= 0) ?
: val; return ( -
{val}
+
{val}
); } } diff --git a/src/firefly/js/visualize/ColValuesStatistics.js b/src/firefly/js/visualize/ColValuesStatistics.js index ca66a61814..4b8f6e7401 100644 --- a/src/firefly/js/visualize/ColValuesStatistics.js +++ b/src/firefly/js/visualize/ColValuesStatistics.js @@ -1,10 +1,11 @@ export default class ColValuesStatistics{ - constructor(name, descr, unit, min, max, numpoints) { + constructor(name, descr, unit, min, max, numpoints,type) { this.name = name; this.descr = descr; this.unit = unit; this.min = Number(min); this.max = Number(max); this.numpoints = Number(numpoints); + this.type = type; } }; \ No newline at end of file diff --git a/src/firefly/js/visualize/XYPlotColView.jsx b/src/firefly/js/visualize/XYPlotColView.jsx new file mode 100644 index 0000000000..1d444e1b1f --- /dev/null +++ b/src/firefly/js/visualize/XYPlotColView.jsx @@ -0,0 +1,124 @@ +/* + */ +import React from 'react'; +import DialogRootContainer from '../ui/DialogRootContainer.jsx'; +import {PopupPanel} from '../ui/PopupPanel.jsx'; + + +import {BasicTable} from '../tables/ui/BasicTable.jsx'; +import {getTblById} from '../tables/TableUtil.js'; +import {dispatchShowDialog} from '../core/ComponentCntlr.js'; +import {setOptions} from './XYPlotOptions.jsx'; +import CompleteButton from '../ui/CompleteButton.jsx'; +import HelpIcon from '../ui/HelpIcon.jsx'; +import {getTblInfo} from '../tables/TableUtil.js'; +const popupIdRoot = 'XYplotColOps'; + +const popupPanelResizableStyle = { + width: 450, + minWidth: 450, + height: 450, + minHeight: 300, + resize: 'both', + overflow: 'hidden', + position: 'relative' +}; + + +//define the table style only in the table div +const tableStyle = {boxSizing: 'border-box', paddingLeft:5,paddingRight:5, width: '100%', height: 'calc(100% - 70px)', overflow: 'hidden', flexGrow: 1, display: 'flex', resize:'none'}; + +//define the complete button +const closeButtonStyle = {'textAlign': 'center', display: 'inline-block', height:40, marginTop:10, width: '90%'}; +//define the helpButton +const helpIdStyle = {'textAlign': 'center', display: 'inline-block', height:40, marginRight: 20}; + + +export function showXYPlotColPopup(tableModel,xyPlotParams,fieldKey,groupKey) { + + var popupId = popupIdRoot; + var popTitle = ''; + var plotCol = ''; + var buttonText =''; + if (fieldKey === 'x.columnOrExpr') { + popTitle = 'Select X Col : '; + plotCol ='x'; + buttonText = 'Set X'; + } else if (fieldKey ==='y.columnOrExpr') { + popTitle = 'Select Y Col : '; + plotCol ='y'; + buttonText = 'Set Y'; + } + + var popup = ( + {popupForm(tableModel,xyPlotParams,plotCol,buttonText,groupKey,popupId)} + + + ); + + DialogRootContainer.defineDialog(popupId, popup); + dispatchShowDialog(popupId); +} + +function popupForm(tableModel, xyPlotParams, plotCol,buttonText,groupKey,popupId) { + const tblId = tableModel.tbl_id; + return ( +
+ { renderTable(tableModel,popupId)} + { renderCloseAndHelpButtons(tblId,xyPlotParams,plotCol,buttonText,groupKey,popupId)} +
+ ); + +} + +/** + * display the data into a tabular format + * @param + */ +function renderTable(tableModel,popupId) { + + return ( +
+ +
+ ); + +} + +function renderCloseAndHelpButtons(tblId,xyPlotParams,plotCol,buttonText,groupKey,popupId) { + + return( +
+
+ < CompleteButton + text={buttonText} + onSuccess={()=>setXYColumns(tblId,plotCol,xyPlotParams,groupKey)} + dialogId={popupId} + /> +
+
+ +
+
+); +} + +function setXYColumns(tblId,plotCol,xyPlotParams,groupKey) { + const tableModel = getTblById(tblId); + var hlRow = getTblInfo(tableModel,1).highlightedRow; + if (hlRow) { + var seltopt = tableModel.tableData.data[hlRow]; + } else { + seltopt = tableModel.tableData.data[0]; + } + if (plotCol === 'x') { + xyPlotParams.x = {columnOrExpr: seltopt[0], lable: seltopt[0], unit: seltopt[1]}; + } else if (plotCol === 'y') { + xyPlotParams.y = {columnOrExpr: seltopt[0], lable: seltopt[0], unit: seltopt[1]}; + } + + setOptions(groupKey,xyPlotParams); +} \ No newline at end of file diff --git a/src/firefly/js/visualize/XYPlotOptions.jsx b/src/firefly/js/visualize/XYPlotOptions.jsx index a9686130de..55bc455391 100644 --- a/src/firefly/js/visualize/XYPlotOptions.jsx +++ b/src/firefly/js/visualize/XYPlotOptions.jsx @@ -1,7 +1,7 @@ /* * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt */ -import React, {PropTypes} from 'react'; +import React, {PropTypes, Component} from 'react'; import {get, isUndefined, omitBy, defer} from 'lodash'; @@ -9,6 +9,7 @@ import ColValuesStatistics from './ColValuesStatistics.js'; import CompleteButton from '../ui/CompleteButton.jsx'; import {FieldGroup} from '../ui/FieldGroup.jsx'; import {dispatchMultiValueChange} from '../fieldGroup/FieldGroupCntlr.js'; +import FieldGroupUtils from '../fieldGroup/FieldGroupUtils.js'; import Validate from '../util/Validate.js'; import {Expression} from '../util/expr/Expression.js'; import {ValidationField} from '../ui/ValidationField.jsx'; @@ -17,10 +18,14 @@ import {RadioGroupInputField} from '../ui/RadioGroupInputField.jsx'; import {SuggestBoxInputField} from '../ui/SuggestBoxInputField.jsx'; import {FieldGroupCollapsible} from '../ui/panel/CollapsiblePanel.jsx'; import {plotParamsShape} from './XYPlot.jsx'; +import TablePanel from '../tables/ui/TablePanel.jsx'; +import {showXYPlotColPopup} from './XYPlotColView.jsx'; const DECI_ENABLE_SIZE = 5000; const helpStyle = {fontStyle: 'italic', color: '#808080', paddingBottom: 10}; +import {TextButton} from '../ui/TextButton.jsx'; +import {showInfoPopup} from '../ui/PopupUtil.jsx'; /* * Split content into prior content and the last alphanumeric token in the text @@ -192,6 +197,9 @@ var XYPlotOptions = React.createClass({ render() { const { colValStats, groupKey, xyPlotParams, onOptionsSelected}= this.props; const colNames = colValStats.map((colVal) => {return colVal.name;}); + const colUnit = colValStats.map((colVal) => {return colVal.unit;}); + const colDescr = colValStats.map((colVal) => {return colVal.descr;}); + // the suggestions are indexes in the colValStats array - it makes it easier to render then with labels const allSuggestions = colValStats.map((colVal,idx)=>{return idx;}); @@ -225,6 +233,15 @@ var XYPlotOptions = React.createClass({ return retval; }; + // make a local table for plot column selection panel + var columns = [{name: 'Name'},{name: 'Unit'},{name: 'Type'},{name: 'Description'}]; + var data = []; + for (var i = 0; i < colValStats.length; i++) { + data[i] = [colValStats[i].name, colValStats[i].unit, colValStats[i].numpoints, colValStats[i].descr]; + } + const request = {pageSize:10000}; + var tableModel = {totalRows: data.length, request, tbl_id:'selectCol', tableData: {columns, data }, highlightedRow: '5'}; + return (

@@ -233,21 +250,44 @@ var XYPlotOptions = React.createClass({ For X and Y, enter a column or an expression
ex. log(col); 100*col1/col2; col1-col2
- + + + + + + + + +
+
+ +
+
+
+ showXYPlotColPopup(tableModel,xyPlotParams,'x.columnOrExpr',groupKey)} + onSuccess={this.resultsSuccess} + onFail={this.resultsFail} + /> +
+
+ @@ -291,21 +331,44 @@ var XYPlotOptions = React.createClass({
- + + + + + + + + +
+
+ +
+
+
+ showXYPlotColPopup(tableModel,xyPlotParams,'y.columnOrExpr',groupKey)} + onSuccess={this.resultsSuccess} + onFail={this.resultsFail} + /> +
+
+ From fbf16d415021d4bec452db4c19f3f8f6fc86f59e Mon Sep 17 00:00:00 2001 From: wmi Date: Thu, 7 Jul 2016 09:41:23 -0700 Subject: [PATCH 02/10] Add TextButton --- src/firefly/js/ui/TextButton.css | 20 ++++++++++++ src/firefly/js/ui/TextButton.jsx | 56 ++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 src/firefly/js/ui/TextButton.css create mode 100644 src/firefly/js/ui/TextButton.jsx diff --git a/src/firefly/js/ui/TextButton.css b/src/firefly/js/ui/TextButton.css new file mode 100644 index 0000000000..e9bb92dc7f --- /dev/null +++ b/src/firefly/js/ui/TextButton.css @@ -0,0 +1,20 @@ + +.ff-MenuItem-linkButton { + padding: 5px; + -moz-border-radius: 0 0 5px 5px; + -webkit-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; + background-color: rgba(245,245,245,.97); + -webkit-box-shadow: 0px 5px 10px rgba(0,0,0,0.3); + -moz-box-shadow: 0px 5px 10px rgba(0,0,0,0.3); + box-shadow: 0px 5px 10px rgba(0,0,0,0.3); +} + +.ff-MenuItem-linkButton .menuItemText { + font-size: 10pt; + line-height: 14pt; +} + +.ff-MenuItem-linkButton .menuItemText:HOVER { + background-color: rgba(255,255,255,.97); +} diff --git a/src/firefly/js/ui/TextButton.jsx b/src/firefly/js/ui/TextButton.jsx new file mode 100644 index 0000000000..5a763b0753 --- /dev/null +++ b/src/firefly/js/ui/TextButton.jsx @@ -0,0 +1,56 @@ +/* + * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt + */ + + +import React, {Component, PropTypes} from 'react'; +import './TextButton.css'; + +const labelStyle= { + display: 'inline-block', + lineHeight: '30px', + fontSize: '10pt', + color: 'black', + verticalAlign:'baseline' +}; + +const messageStyle={ + fontSize: '10pt', + lineHeight: '14pt' +}; + +/** + * + * @param text + * @param tip + * @param onClick + * @param style + * @return react object + */ +export function TextButton({text, tip='$text',style={}, onClick}) { + var s= Object.assign({cursor:'pointer', verticalAlign:'bottom'},style); + return ( +
+ +
+ {text} +
+ +
+ ); +} + + +//CloseButton.contextTypes= { +//}; + + +TextButton.propTypes= { + text : PropTypes.string, + style : PropTypes.object, + tip : PropTypes.string, + onClick : PropTypes.func +}; + + + From 4043caaa92a5c5f04ac7d6a02aea0c6ff8847aad Mon Sep 17 00:00:00 2001 From: tatianag Date: Thu, 7 Jul 2016 12:55:33 -0700 Subject: [PATCH 03/10] add description and type to table statistics --- src/firefly/js/visualize/TableStatsCntlr.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/firefly/js/visualize/TableStatsCntlr.js b/src/firefly/js/visualize/TableStatsCntlr.js index 059f6d88da..9d2f35ab17 100644 --- a/src/firefly/js/visualize/TableStatsCntlr.js +++ b/src/firefly/js/visualize/TableStatsCntlr.js @@ -1,6 +1,6 @@ import {flux} from '../Firefly.js'; -import {has, omit} from 'lodash'; +import {get, has, omit} from 'lodash'; import {updateSet, updateMerge} from '../util/WebUtil.js'; import ColValuesStatistics from './ColValuesStatistics.js'; @@ -129,15 +129,23 @@ function fetchTblStats(dispatch, activeTableServerRequest) { const sreq = Object.assign({}, omit(activeTableServerRequest, ['tbl_id', 'META_INFO']), {'startIdx': 0, 'pageSize': 1000000}); - const req = TableUtil.makeTblRequest('StatisticsProcessor', null, - { searchRequest: JSON.stringify(sreq) }, - 'tblstats-'+tbl_id); + const req = TableUtil.makeTblRequest('StatisticsProcessor', `Statistics for ${tbl_id}`, + { searchRequest: JSON.stringify(sreq) }, + {'startIdx': 0, 'pageSize': 1000}); TableUtil.doFetchTable(req).then( (tableModel) => { if (tableModel.tableData && tableModel.tableData.data) { + const columns = get(TableUtil.getTblById(tbl_id), 'tableData.columns', []); const colStats = tableModel.tableData.data.reduce((colstats, arow) => { - colstats.push(new ColValuesStatistics(...arow)); + const r = new ColValuesStatistics(...arow); + const col = columns.find((c)=>{return c.name=== r.name;}); + if (col) { + r.unit = col.units && col.units !== 'null' ? col.units : ''; + r.descr = col.desc ? col.desc: ''; + r.type = col.type ? col.type : ''; + } + colstats.push(r); return colstats; }, []); dispatch(updateTblStats( From d1eae3f2c164acde0fa9f3a44aafb09dd8674faa Mon Sep 17 00:00:00 2001 From: wmi Date: Thu, 7 Jul 2016 16:27:16 -0700 Subject: [PATCH 04/10] changes made with Tatiana's comments --- .../{XYPlotColView.jsx => ColSelectView.jsx} | 72 +++++++++++-------- src/firefly/js/visualize/TableStatsCntlr.js | 18 +++-- src/firefly/js/visualize/XYPlotOptions.jsx | 33 +++------ 3 files changed, 66 insertions(+), 57 deletions(-) rename src/firefly/js/visualize/{XYPlotColView.jsx => ColSelectView.jsx} (54%) diff --git a/src/firefly/js/visualize/XYPlotColView.jsx b/src/firefly/js/visualize/ColSelectView.jsx similarity index 54% rename from src/firefly/js/visualize/XYPlotColView.jsx rename to src/firefly/js/visualize/ColSelectView.jsx index 1d444e1b1f..91d20912a0 100644 --- a/src/firefly/js/visualize/XYPlotColView.jsx +++ b/src/firefly/js/visualize/ColSelectView.jsx @@ -12,10 +12,10 @@ import {setOptions} from './XYPlotOptions.jsx'; import CompleteButton from '../ui/CompleteButton.jsx'; import HelpIcon from '../ui/HelpIcon.jsx'; import {getTblInfo} from '../tables/TableUtil.js'; -const popupIdRoot = 'XYplotColOps'; +const popupId = 'XYColSelect'; const popupPanelResizableStyle = { - width: 450, + width: 600, minWidth: 450, height: 450, minHeight: 300, @@ -34,24 +34,34 @@ const closeButtonStyle = {'textAlign': 'center', display: 'inline-block', height const helpIdStyle = {'textAlign': 'center', display: 'inline-block', height:40, marginRight: 20}; -export function showXYPlotColPopup(tableModel,xyPlotParams,fieldKey,groupKey) { - - var popupId = popupIdRoot; - var popTitle = ''; - var plotCol = ''; - var buttonText =''; - if (fieldKey === 'x.columnOrExpr') { - popTitle = 'Select X Col : '; - plotCol ='x'; - buttonText = 'Set X'; - } else if (fieldKey ==='y.columnOrExpr') { - popTitle = 'Select Y Col : '; - plotCol ='y'; - buttonText = 'Set Y'; +export function showColSelectPopup(colValStats,xyPlotParams,popupTitle,buttonText,groupKey) { + + const colNames = colValStats.map((colVal) => {return colVal.name;}); + const colUnit = colValStats.map((colVal) => {return colVal.unit;}); + const colDescr = colValStats.map((colVal) => {return colVal.descr;}); + + // make a local table for plot column selection panel + var columns = [ + {name: 'Name',visibility: 'show', prefWidth: 12, fixed: true}, + {name: 'Unit',visibility: 'show', prefWidth: 8}, + {name: 'Type',visibility: 'show', prefWidth: 8}, + {name: 'Description',visibility: 'show', prefWidth: 60} + ]; + var data = []; + for (var i = 0; i < colValStats.length; i++) { + data[i] = [ + colValStats[i].name, + colValStats[i].unit, + colValStats[i].type, + colValStats[i].descr + ]; } + const request = {pageSize:10000}; + var tableModel = {totalRows: data.length, request, tbl_id:'selectCol', tableData: {columns, data }, highlightedRow: '0'}; - var popup = ( - {popupForm(tableModel,xyPlotParams,plotCol,buttonText,groupKey,popupId)} + + var popup = ( + {popupForm(tableModel,xyPlotParams,buttonText,groupKey,popupId)} ); @@ -60,12 +70,12 @@ export function showXYPlotColPopup(tableModel,xyPlotParams,fieldKey,groupKey) { dispatchShowDialog(popupId); } -function popupForm(tableModel, xyPlotParams, plotCol,buttonText,groupKey,popupId) { +function popupForm(tableModel, xyPlotParams,buttonText,groupKey,popupId) { const tblId = tableModel.tbl_id; return (
{ renderTable(tableModel,popupId)} - { renderCloseAndHelpButtons(tblId,xyPlotParams,plotCol,buttonText,groupKey,popupId)} + { renderCloseAndHelpButtons(tblId,xyPlotParams,buttonText,groupKey,popupId)}
); @@ -73,7 +83,9 @@ function popupForm(tableModel, xyPlotParams, plotCol,buttonText,groupKey,popupId /** * display the data into a tabular format - * @param + * @param tableModel + * @param popupId + * @return table section */ function renderTable(tableModel,popupId) { @@ -88,25 +100,27 @@ function renderTable(tableModel,popupId) { } -function renderCloseAndHelpButtons(tblId,xyPlotParams,plotCol,buttonText,groupKey,popupId) { +function renderCloseAndHelpButtons(tblId,xyPlotParams,buttonText,groupKey,popupId) { return(
< CompleteButton text={buttonText} - onSuccess={()=>setXYColumns(tblId,plotCol,xyPlotParams,groupKey)} + onSuccess={()=>setXYColumns(tblId,buttonText,xyPlotParams,groupKey)} dialogId={popupId} />
-
- -
+ {/* comment out the help button for now +
+ +
+ */}
); } -function setXYColumns(tblId,plotCol,xyPlotParams,groupKey) { +function setXYColumns(tblId,buttonText,xyPlotParams,groupKey) { const tableModel = getTblById(tblId); var hlRow = getTblInfo(tableModel,1).highlightedRow; if (hlRow) { @@ -114,9 +128,9 @@ function setXYColumns(tblId,plotCol,xyPlotParams,groupKey) { } else { seltopt = tableModel.tableData.data[0]; } - if (plotCol === 'x') { + if (buttonText === 'Set X') { xyPlotParams.x = {columnOrExpr: seltopt[0], lable: seltopt[0], unit: seltopt[1]}; - } else if (plotCol === 'y') { + } else if (buttonText === 'Set Y') { xyPlotParams.y = {columnOrExpr: seltopt[0], lable: seltopt[0], unit: seltopt[1]}; } diff --git a/src/firefly/js/visualize/TableStatsCntlr.js b/src/firefly/js/visualize/TableStatsCntlr.js index 059f6d88da..9d2f35ab17 100644 --- a/src/firefly/js/visualize/TableStatsCntlr.js +++ b/src/firefly/js/visualize/TableStatsCntlr.js @@ -1,6 +1,6 @@ import {flux} from '../Firefly.js'; -import {has, omit} from 'lodash'; +import {get, has, omit} from 'lodash'; import {updateSet, updateMerge} from '../util/WebUtil.js'; import ColValuesStatistics from './ColValuesStatistics.js'; @@ -129,15 +129,23 @@ function fetchTblStats(dispatch, activeTableServerRequest) { const sreq = Object.assign({}, omit(activeTableServerRequest, ['tbl_id', 'META_INFO']), {'startIdx': 0, 'pageSize': 1000000}); - const req = TableUtil.makeTblRequest('StatisticsProcessor', null, - { searchRequest: JSON.stringify(sreq) }, - 'tblstats-'+tbl_id); + const req = TableUtil.makeTblRequest('StatisticsProcessor', `Statistics for ${tbl_id}`, + { searchRequest: JSON.stringify(sreq) }, + {'startIdx': 0, 'pageSize': 1000}); TableUtil.doFetchTable(req).then( (tableModel) => { if (tableModel.tableData && tableModel.tableData.data) { + const columns = get(TableUtil.getTblById(tbl_id), 'tableData.columns', []); const colStats = tableModel.tableData.data.reduce((colstats, arow) => { - colstats.push(new ColValuesStatistics(...arow)); + const r = new ColValuesStatistics(...arow); + const col = columns.find((c)=>{return c.name=== r.name;}); + if (col) { + r.unit = col.units && col.units !== 'null' ? col.units : ''; + r.descr = col.desc ? col.desc: ''; + r.type = col.type ? col.type : ''; + } + colstats.push(r); return colstats; }, []); dispatch(updateTblStats( diff --git a/src/firefly/js/visualize/XYPlotOptions.jsx b/src/firefly/js/visualize/XYPlotOptions.jsx index 55bc455391..c5fd757ef9 100644 --- a/src/firefly/js/visualize/XYPlotOptions.jsx +++ b/src/firefly/js/visualize/XYPlotOptions.jsx @@ -1,7 +1,7 @@ /* * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt */ -import React, {PropTypes, Component} from 'react'; +import React, {PropTypes} from 'react'; import {get, isUndefined, omitBy, defer} from 'lodash'; @@ -9,7 +9,6 @@ import ColValuesStatistics from './ColValuesStatistics.js'; import CompleteButton from '../ui/CompleteButton.jsx'; import {FieldGroup} from '../ui/FieldGroup.jsx'; import {dispatchMultiValueChange} from '../fieldGroup/FieldGroupCntlr.js'; -import FieldGroupUtils from '../fieldGroup/FieldGroupUtils.js'; import Validate from '../util/Validate.js'; import {Expression} from '../util/expr/Expression.js'; import {ValidationField} from '../ui/ValidationField.jsx'; @@ -18,14 +17,13 @@ import {RadioGroupInputField} from '../ui/RadioGroupInputField.jsx'; import {SuggestBoxInputField} from '../ui/SuggestBoxInputField.jsx'; import {FieldGroupCollapsible} from '../ui/panel/CollapsiblePanel.jsx'; import {plotParamsShape} from './XYPlot.jsx'; -import TablePanel from '../tables/ui/TablePanel.jsx'; -import {showXYPlotColPopup} from './XYPlotColView.jsx'; +import {showColSelectPopup} from './ColSelectView.jsx'; +import {updateSet} from '../util/WebUtil.js'; const DECI_ENABLE_SIZE = 5000; const helpStyle = {fontStyle: 'italic', color: '#808080', paddingBottom: 10}; import {TextButton} from '../ui/TextButton.jsx'; -import {showInfoPopup} from '../ui/PopupUtil.jsx'; /* * Split content into prior content and the last alphanumeric token in the text @@ -121,6 +119,7 @@ export function setOptions(groupKey, xyPlotParams) { dispatchMultiValueChange(groupKey, flds); } + var XYPlotOptions = React.createClass({ @@ -197,9 +196,6 @@ var XYPlotOptions = React.createClass({ render() { const { colValStats, groupKey, xyPlotParams, onOptionsSelected}= this.props; const colNames = colValStats.map((colVal) => {return colVal.name;}); - const colUnit = colValStats.map((colVal) => {return colVal.unit;}); - const colDescr = colValStats.map((colVal) => {return colVal.descr;}); - // the suggestions are indexes in the colValStats array - it makes it easier to render then with labels const allSuggestions = colValStats.map((colVal,idx)=>{return idx;}); @@ -233,15 +229,6 @@ var XYPlotOptions = React.createClass({ return retval; }; - // make a local table for plot column selection panel - var columns = [{name: 'Name'},{name: 'Unit'},{name: 'Type'},{name: 'Description'}]; - var data = []; - for (var i = 0; i < colValStats.length; i++) { - data[i] = [colValStats[i].name, colValStats[i].unit, colValStats[i].numpoints, colValStats[i].descr]; - } - const request = {pageSize:10000}; - var tableModel = {totalRows: data.length, request, tbl_id:'selectCol', tableData: {columns, data }, highlightedRow: '5'}; - return (

@@ -276,9 +263,9 @@ var XYPlotOptions = React.createClass({
showXYPlotColPopup(tableModel,xyPlotParams,'x.columnOrExpr',groupKey)} + text='Col' + tip='Select X colum' + onClick={() => showColSelectPopup(colValStats, xyPlotParams,'Choose X','Set X',groupKey)} onSuccess={this.resultsSuccess} onFail={this.resultsFail} /> @@ -357,9 +344,9 @@ var XYPlotOptions = React.createClass({
showXYPlotColPopup(tableModel,xyPlotParams,'y.columnOrExpr',groupKey)} + text='Col' + tip='Select Y column' + onClick={() => showColSelectPopup(colValStats,xyPlotParams,'Choose Y','Set Y',groupKey)} onSuccess={this.resultsSuccess} onFail={this.resultsFail} /> From 629339827b77fd5359c37b9dedef28a260f48c09 Mon Sep 17 00:00:00 2001 From: wmi Date: Fri, 8 Jul 2016 14:34:56 -0700 Subject: [PATCH 05/10] few modifications and bug fixes after consult with Tatiana --- src/firefly/js/visualize/ColSelectView.jsx | 48 +++++++++++++--------- src/firefly/js/visualize/XYPlotOptions.jsx | 25 ++++++++++- 2 files changed, 51 insertions(+), 22 deletions(-) diff --git a/src/firefly/js/visualize/ColSelectView.jsx b/src/firefly/js/visualize/ColSelectView.jsx index 91d20912a0..b4b38b68fb 100644 --- a/src/firefly/js/visualize/ColSelectView.jsx +++ b/src/firefly/js/visualize/ColSelectView.jsx @@ -3,7 +3,7 @@ import React from 'react'; import DialogRootContainer from '../ui/DialogRootContainer.jsx'; import {PopupPanel} from '../ui/PopupPanel.jsx'; - +import {dispatchTableRemove} from '../tables/TablesCntlr'; import {BasicTable} from '../tables/ui/BasicTable.jsx'; import {getTblById} from '../tables/TableUtil.js'; @@ -13,6 +13,7 @@ import CompleteButton from '../ui/CompleteButton.jsx'; import HelpIcon from '../ui/HelpIcon.jsx'; import {getTblInfo} from '../tables/TableUtil.js'; const popupId = 'XYColSelect'; +const TBL_ID ='selectCol'; const popupPanelResizableStyle = { width: 600, @@ -34,12 +35,18 @@ const closeButtonStyle = {'textAlign': 'center', display: 'inline-block', height const helpIdStyle = {'textAlign': 'center', display: 'inline-block', height:40, marginRight: 20}; -export function showColSelectPopup(colValStats,xyPlotParams,popupTitle,buttonText,groupKey) { +export function showColSelectPopup(colValStats,onColSelected,popupTitle,buttonText,currentVal) { + + if (getTblById(TBL_ID)) { +        dispatchTableRemove(TBL_ID); +    } const colNames = colValStats.map((colVal) => {return colVal.name;}); const colUnit = colValStats.map((colVal) => {return colVal.unit;}); const colDescr = colValStats.map((colVal) => {return colVal.descr;}); + var hlRowNum = getHlRow(currentVal,colNames); + // make a local table for plot column selection panel var columns = [ {name: 'Name',visibility: 'show', prefWidth: 12, fixed: true}, @@ -57,11 +64,11 @@ export function showColSelectPopup(colValStats,xyPlotParams,popupTitle,buttonTex ]; } const request = {pageSize:10000}; - var tableModel = {totalRows: data.length, request, tbl_id:'selectCol', tableData: {columns, data }, highlightedRow: '0'}; + var tableModel = {totalRows: data.length, request, tbl_id:TBL_ID, tableData: {columns, data }, highlightedRow: hlRowNum}; var popup = ( - {popupForm(tableModel,xyPlotParams,buttonText,groupKey,popupId)} + {popupForm(tableModel,onColSelected,buttonText,popupId)} ); @@ -70,12 +77,12 @@ export function showColSelectPopup(colValStats,xyPlotParams,popupTitle,buttonTex dispatchShowDialog(popupId); } -function popupForm(tableModel, xyPlotParams,buttonText,groupKey,popupId) { +function popupForm(tableModel, onColSelected,buttonText,popupId) { const tblId = tableModel.tbl_id; return (
{ renderTable(tableModel,popupId)} - { renderCloseAndHelpButtons(tblId,xyPlotParams,buttonText,groupKey,popupId)} + { renderCloseAndHelpButtons(tblId,onColSelected,buttonText,popupId)}
); @@ -100,14 +107,14 @@ function renderTable(tableModel,popupId) { } -function renderCloseAndHelpButtons(tblId,xyPlotParams,buttonText,groupKey,popupId) { +function renderCloseAndHelpButtons(tblId,onColSelected,buttonText,popupId) { return(
< CompleteButton text={buttonText} - onSuccess={()=>setXYColumns(tblId,buttonText,xyPlotParams,groupKey)} + onSuccess={()=>setXYColumns(tblId,onColSelected)} dialogId={popupId} />
@@ -120,19 +127,20 @@ function renderCloseAndHelpButtons(tblId,xyPlotParams,buttonText,groupKey,popupI ); } -function setXYColumns(tblId,buttonText,xyPlotParams,groupKey) { +function setXYColumns(tblId,onColSelected) { const tableModel = getTblById(tblId); - var hlRow = getTblInfo(tableModel,1).highlightedRow; - if (hlRow) { - var seltopt = tableModel.tableData.data[hlRow]; - } else { - seltopt = tableModel.tableData.data[0]; - } - if (buttonText === 'Set X') { - xyPlotParams.x = {columnOrExpr: seltopt[0], lable: seltopt[0], unit: seltopt[1]}; - } else if (buttonText === 'Set Y') { - xyPlotParams.y = {columnOrExpr: seltopt[0], lable: seltopt[0], unit: seltopt[1]}; + var hlRow = tableModel.highlightedRow || 0; + const selectedColName = tableModel.tableData.data[hlRow][0]; +    onColSelected(selectedColName); + +} + +function getHlRow(currentVal,colNames) { + var hLRow = 0; + for(var i = 0; i < colNames.length; i++) { + if (colNames[i] === currentVal) { + return hLRow = i; + } } - setOptions(groupKey,xyPlotParams); } \ No newline at end of file diff --git a/src/firefly/js/visualize/XYPlotOptions.jsx b/src/firefly/js/visualize/XYPlotOptions.jsx index c5fd757ef9..d3a6e70c5c 100644 --- a/src/firefly/js/visualize/XYPlotOptions.jsx +++ b/src/firefly/js/visualize/XYPlotOptions.jsx @@ -229,6 +229,27 @@ var XYPlotOptions = React.createClass({ return retval; }; + var x = Object.assign({}, xyPlotParams.x); +        var y = Object.assign({}, xyPlotParams.y); + const onXColSelected = (colName) => { +            x = {columnOrExpr: colName}; + const flds = [ +                {fieldKey: 'x.columnOrExpr', value: colName}, +                {fieldKey: 'x.label', value: ''}, +                {fieldKey: 'x.unit', value: ''} +            ]; +            dispatchMultiValueChange(groupKey, flds); +        }; +        const onYColSelected = (colName) => { + y = {columnOrExpr: colName}; +            const flds = [ +                {fieldKey: 'y.columnOrExpr', value: colName}, +                {fieldKey: 'y.label', value: ''}, +                {fieldKey: 'y.unit', value: ''} +            ]; +            dispatchMultiValueChange(groupKey, flds); +        }; +                                          return (

@@ -265,7 +286,7 @@ var XYPlotOptions = React.createClass({ showColSelectPopup(colValStats, xyPlotParams,'Choose X','Set X',groupKey)} + onClick={() => showColSelectPopup(colValStats, onXColSelected,'Choose X','Set X',x.columnOrExpr)} onSuccess={this.resultsSuccess} onFail={this.resultsFail} /> @@ -346,7 +367,7 @@ var XYPlotOptions = React.createClass({ showColSelectPopup(colValStats,xyPlotParams,'Choose Y','Set Y',groupKey)} + onClick={() => showColSelectPopup(colValStats,onYColSelected,'Choose Y','Set Y',y.columnOrExpr)} onSuccess={this.resultsSuccess} onFail={this.resultsFail} /> From b664b71f01abd3361ba807f2c5ff64dd7598ebac Mon Sep 17 00:00:00 2001 From: tatianag Date: Fri, 8 Jul 2016 14:57:09 -0700 Subject: [PATCH 06/10] updating validators on mount - in charts dropdown the same form is reused by different tables. --- src/firefly/js/visualize/XYPlotOptions.jsx | 65 ++++++++++++---------- 1 file changed, 37 insertions(+), 28 deletions(-) diff --git a/src/firefly/js/visualize/XYPlotOptions.jsx b/src/firefly/js/visualize/XYPlotOptions.jsx index d3a6e70c5c..1ec0672808 100644 --- a/src/firefly/js/visualize/XYPlotOptions.jsx +++ b/src/firefly/js/visualize/XYPlotOptions.jsx @@ -18,7 +18,6 @@ import {SuggestBoxInputField} from '../ui/SuggestBoxInputField.jsx'; import {FieldGroupCollapsible} from '../ui/panel/CollapsiblePanel.jsx'; import {plotParamsShape} from './XYPlot.jsx'; import {showColSelectPopup} from './ColSelectView.jsx'; -import {updateSet} from '../util/WebUtil.js'; const DECI_ENABLE_SIZE = 5000; @@ -119,6 +118,22 @@ export function setOptions(groupKey, xyPlotParams) { dispatchMultiValueChange(groupKey, flds); } +export function getColValidator(colValStats) { + const colNames = colValStats.map((colVal) => {return colVal.name;}); + return (val) => { + let retval = {valid: true, message: ''}; + if (!val) { + return {valid: false, message: 'Can not be empty. Please provide value or expression'}; + } else if (colNames.indexOf(val) < 0) { + const expr = new Expression(val, colNames); + if (!expr.isValid()) { + retval = {valid: false, message: `${expr.getError().error}. Unable to parse ${val}.`}; + } + } + return retval; + }; +} + var XYPlotOptions = React.createClass({ @@ -130,6 +145,18 @@ var XYPlotOptions = React.createClass({ xyPlotParams: plotParamsShape }, + componentDidMount() { + // make sure column validator matches current columns + const {colValStats, groupKey} = this.props; + if (colValStats) { + const colValidator = getColValidator(colValStats); + const flds = [ + {fieldKey: 'x.columnOrExpr', validator: colValidator}, + {fieldKey: 'y.columnOrExpr', validator: colValidator} + ]; + dispatchMultiValueChange(groupKey, flds); + } + }, shouldComponentUpdate(np) { return this.props.groupKey !== np.groupKey || this.props.colValStats !== np.colValStats || @@ -195,7 +222,6 @@ var XYPlotOptions = React.createClass({ render() { const { colValStats, groupKey, xyPlotParams, onOptionsSelected}= this.props; - const colNames = colValStats.map((colVal) => {return colVal.name;}); // the suggestions are indexes in the colValStats array - it makes it easier to render then with labels const allSuggestions = colValStats.map((colVal,idx)=>{return idx;}); @@ -216,23 +242,10 @@ var XYPlotOptions = React.createClass({ return priorContent+colValStats[idx].name; }; - const colValidator = (val) => { - let retval = {valid: true, message: ''}; - if (!val) { - return {valid: false, message: 'Can not be empty. Please provide value or expression'}; - } else if (colNames.indexOf(val)<0) { - const expr = new Expression(val,colNames); - if (!expr.isValid()) { - retval = {valid: false, message: `${expr.getError().error}. Unable to parse ${val}.`}; - } - } - return retval; - }; - - var x = Object.assign({}, xyPlotParams.x); -        var y = Object.assign({}, xyPlotParams.y); + var x = get(xyPlotParams, 'x.columnOrExpr'); +        var y = get(xyPlotParams, 'y.columnOrExpr'); const onXColSelected = (colName) => { -            x = {columnOrExpr: colName}; +            x = colName; const flds = [                 {fieldKey: 'x.columnOrExpr', value: colName},                 {fieldKey: 'x.label', value: ''}, @@ -241,7 +254,7 @@ var XYPlotOptions = React.createClass({             dispatchMultiValueChange(groupKey, flds);         };         const onYColSelected = (colName) => { - y = {columnOrExpr: colName}; + y = colName;             const flds = [                 {fieldKey: 'y.columnOrExpr', value: colName},                 {fieldKey: 'y.label', value: ''}, @@ -261,7 +274,6 @@ var XYPlotOptions = React.createClass({ -
showColSelectPopup(colValStats, onXColSelected,'Choose X','Set X',x.columnOrExpr)} + tip='Select X column' + onClick={() => showColSelectPopup(colValStats, onXColSelected,'Choose X','Set X',x)} onSuccess={this.resultsSuccess} onFail={this.resultsFail} /> @@ -342,7 +353,6 @@ var XYPlotOptions = React.createClass({ -
showColSelectPopup(colValStats,onYColSelected,'Choose Y','Set Y',y.columnOrExpr)} + onClick={() => showColSelectPopup(colValStats,onYColSelected,'Choose Y','Set Y',y)} onSuccess={this.resultsSuccess} onFail={this.resultsFail} /> From ad1a94752c228a762558657e2f13567a1c7d53f3 Mon Sep 17 00:00:00 2001 From: wmi Date: Fri, 8 Jul 2016 15:33:24 -0700 Subject: [PATCH 07/10] more code clean up --- src/firefly/js/ui/TextButton.jsx | 10 +++------- src/firefly/js/visualize/ColSelectView.jsx | 13 +++---------- 2 files changed, 6 insertions(+), 17 deletions(-) diff --git a/src/firefly/js/ui/TextButton.jsx b/src/firefly/js/ui/TextButton.jsx index 5a763b0753..c12781261c 100644 --- a/src/firefly/js/ui/TextButton.jsx +++ b/src/firefly/js/ui/TextButton.jsx @@ -3,22 +3,18 @@ */ -import React, {Component, PropTypes} from 'react'; +import React, {PropTypes} from 'react'; import './TextButton.css'; const labelStyle= { display: 'inline-block', lineHeight: '30px', fontSize: '10pt', - color: 'black', + fontStyle: 'italic', + color: 'blue', verticalAlign:'baseline' }; -const messageStyle={ - fontSize: '10pt', - lineHeight: '14pt' -}; - /** * * @param text diff --git a/src/firefly/js/visualize/ColSelectView.jsx b/src/firefly/js/visualize/ColSelectView.jsx index b4b38b68fb..996b308804 100644 --- a/src/firefly/js/visualize/ColSelectView.jsx +++ b/src/firefly/js/visualize/ColSelectView.jsx @@ -8,10 +8,8 @@ import {dispatchTableRemove} from '../tables/TablesCntlr'; import {BasicTable} from '../tables/ui/BasicTable.jsx'; import {getTblById} from '../tables/TableUtil.js'; import {dispatchShowDialog} from '../core/ComponentCntlr.js'; -import {setOptions} from './XYPlotOptions.jsx'; import CompleteButton from '../ui/CompleteButton.jsx'; import HelpIcon from '../ui/HelpIcon.jsx'; -import {getTblInfo} from '../tables/TableUtil.js'; const popupId = 'XYColSelect'; const TBL_ID ='selectCol'; @@ -42,14 +40,11 @@ export function showColSelectPopup(colValStats,onColSelected,popupTitle,buttonTe     } const colNames = colValStats.map((colVal) => {return colVal.name;}); - const colUnit = colValStats.map((colVal) => {return colVal.unit;}); - const colDescr = colValStats.map((colVal) => {return colVal.descr;}); - - var hlRowNum = getHlRow(currentVal,colNames); + var hlRowNum = getHlRow(currentVal,colNames) || 0; // make a local table for plot column selection panel var columns = [ - {name: 'Name',visibility: 'show', prefWidth: 12, fixed: true}, + {name: 'Name',visibility: 'show', prefWidth: 12}, {name: 'Unit',visibility: 'show', prefWidth: 8}, {name: 'Type',visibility: 'show', prefWidth: 8}, {name: 'Description',visibility: 'show', prefWidth: 60} @@ -136,11 +131,9 @@ function setXYColumns(tblId,onColSelected) { } function getHlRow(currentVal,colNames) { - var hLRow = 0; for(var i = 0; i < colNames.length; i++) { if (colNames[i] === currentVal) { - return hLRow = i; + return i; } } - } \ No newline at end of file From 099196cc0be0b31c6b358e4777d99d0f714d0b7c Mon Sep 17 00:00:00 2001 From: wmi Date: Fri, 8 Jul 2016 15:47:26 -0700 Subject: [PATCH 08/10] clean up again --- src/firefly/js/ui/TextButton.jsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/firefly/js/ui/TextButton.jsx b/src/firefly/js/ui/TextButton.jsx index c12781261c..3983d1f3a4 100644 --- a/src/firefly/js/ui/TextButton.jsx +++ b/src/firefly/js/ui/TextButton.jsx @@ -4,7 +4,6 @@ import React, {PropTypes} from 'react'; -import './TextButton.css'; const labelStyle= { display: 'inline-block', From 323a48c17447fbbcc07d06488d3f0df6e3a5fbc8 Mon Sep 17 00:00:00 2001 From: wmi Date: Wed, 29 Jun 2016 15:08:55 -0700 Subject: [PATCH 09/10] * The changes on tables related js are dealing with locally created tables and have them shown up in the basic table panel * Add XYPlot column select popup add description and type to table statistics few modifications and bug fixes updating validators on mount - in charts dropdown the same form is reused by different tables. code clean up --- src/firefly/js/tables/TableConnector.js | 7 +- src/firefly/js/tables/TableUtil.js | 2 +- src/firefly/js/tables/ui/TableRenderer.js | 7 +- src/firefly/js/ui/TextButton.css | 20 +++ src/firefly/js/ui/TextButton.jsx | 51 ++++++ src/firefly/js/visualize/ColSelectView.jsx | 139 +++++++++++++++ .../js/visualize/ColValuesStatistics.js | 3 +- src/firefly/js/visualize/TableStatsCntlr.js | 18 +- src/firefly/js/visualize/XYPlotOptions.jsx | 168 +++++++++++++----- 9 files changed, 359 insertions(+), 56 deletions(-) create mode 100644 src/firefly/js/ui/TextButton.css create mode 100644 src/firefly/js/ui/TextButton.jsx create mode 100644 src/firefly/js/visualize/ColSelectView.jsx diff --git a/src/firefly/js/tables/TableConnector.js b/src/firefly/js/tables/TableConnector.js index b2dd881900..3b7584b05d 100644 --- a/src/firefly/js/tables/TableConnector.js +++ b/src/firefly/js/tables/TableConnector.js @@ -87,7 +87,12 @@ export class TableConnector { const {hlRowIdx, startIdx} = TblUtil.getTblInfoById(this.tbl_id); if (rowIdx !== hlRowIdx) { const highlightedRow = startIdx + rowIdx; - TblCntlr.dispatchTableHighlight(this.tbl_id, highlightedRow); + if (this.origTableModel) { + const tableModel = {tbl_id: this.tbl_id, highlightedRow}; + flux.process({type: TblCntlr.TABLE_UPDATE, payload: tableModel}); + } else { + TblCntlr.dispatchTableHighlight(this.tbl_id, highlightedRow); + } } } diff --git a/src/firefly/js/tables/TableUtil.js b/src/firefly/js/tables/TableUtil.js index 7f3616f07c..5a37855bcb 100644 --- a/src/firefly/js/tables/TableUtil.js +++ b/src/firefly/js/tables/TableUtil.js @@ -441,7 +441,7 @@ export function getTblInfo(tableModel, aPageSize) { const currentPage = highlightedRow >= 0 ? Math.floor(highlightedRow / pageSize)+1 : 1; const hlRowIdx = highlightedRow >= 0 ? highlightedRow % pageSize : 0; const startIdx = (currentPage-1) * pageSize; - const endIdx = Math.min(startIdx+pageSize, totalRows) || startIdx ; + const endIdx = Math.min(startIdx+pageSize, totalRows) || get(tableModel,'tableData.data.length', startIdx) ; var totalPages = Math.ceil((totalRows || 0)/pageSize); return { tableModel, tbl_id, title, totalRows, request, startIdx, endIdx, hlRowIdx, currentPage, pageSize,totalPages, highlightedRow, selectInfo, error}; } diff --git a/src/firefly/js/tables/ui/TableRenderer.js b/src/firefly/js/tables/ui/TableRenderer.js index 0fbdd94059..4d6434602f 100644 --- a/src/firefly/js/tables/ui/TableRenderer.js +++ b/src/firefly/js/tables/ui/TableRenderer.js @@ -177,12 +177,11 @@ export class TextCell extends React.Component { // } // render() { - const lineHeight = this.props.height - 6 + 'px'; // 6 is the top/bottom padding. - const style = Object.assign({lineHeight}, this.props.style || {}); var val = getValue(this.props); - val = (isString(val) && val.search(html_regex) >= 0) ?
: val; + const lineHeight = this.props.height - 6 + 'px'; // 6 is the top/bottom padding. + val = (val.search && val.search(html_regex) >= 0) ?
: val; return ( -
{val}
+
{val}
); } } diff --git a/src/firefly/js/ui/TextButton.css b/src/firefly/js/ui/TextButton.css new file mode 100644 index 0000000000..e9bb92dc7f --- /dev/null +++ b/src/firefly/js/ui/TextButton.css @@ -0,0 +1,20 @@ + +.ff-MenuItem-linkButton { + padding: 5px; + -moz-border-radius: 0 0 5px 5px; + -webkit-border-radius: 0 0 5px 5px; + border-radius: 0 0 5px 5px; + background-color: rgba(245,245,245,.97); + -webkit-box-shadow: 0px 5px 10px rgba(0,0,0,0.3); + -moz-box-shadow: 0px 5px 10px rgba(0,0,0,0.3); + box-shadow: 0px 5px 10px rgba(0,0,0,0.3); +} + +.ff-MenuItem-linkButton .menuItemText { + font-size: 10pt; + line-height: 14pt; +} + +.ff-MenuItem-linkButton .menuItemText:HOVER { + background-color: rgba(255,255,255,.97); +} diff --git a/src/firefly/js/ui/TextButton.jsx b/src/firefly/js/ui/TextButton.jsx new file mode 100644 index 0000000000..3983d1f3a4 --- /dev/null +++ b/src/firefly/js/ui/TextButton.jsx @@ -0,0 +1,51 @@ +/* + * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt + */ + + +import React, {PropTypes} from 'react'; + +const labelStyle= { + display: 'inline-block', + lineHeight: '30px', + fontSize: '10pt', + fontStyle: 'italic', + color: 'blue', + verticalAlign:'baseline' +}; + +/** + * + * @param text + * @param tip + * @param onClick + * @param style + * @return react object + */ +export function TextButton({text, tip='$text',style={}, onClick}) { + var s= Object.assign({cursor:'pointer', verticalAlign:'bottom'},style); + return ( +
+ +
+ {text} +
+ +
+ ); +} + + +//CloseButton.contextTypes= { +//}; + + +TextButton.propTypes= { + text : PropTypes.string, + style : PropTypes.object, + tip : PropTypes.string, + onClick : PropTypes.func +}; + + + diff --git a/src/firefly/js/visualize/ColSelectView.jsx b/src/firefly/js/visualize/ColSelectView.jsx new file mode 100644 index 0000000000..996b308804 --- /dev/null +++ b/src/firefly/js/visualize/ColSelectView.jsx @@ -0,0 +1,139 @@ +/* + */ +import React from 'react'; +import DialogRootContainer from '../ui/DialogRootContainer.jsx'; +import {PopupPanel} from '../ui/PopupPanel.jsx'; +import {dispatchTableRemove} from '../tables/TablesCntlr'; + +import {BasicTable} from '../tables/ui/BasicTable.jsx'; +import {getTblById} from '../tables/TableUtil.js'; +import {dispatchShowDialog} from '../core/ComponentCntlr.js'; +import CompleteButton from '../ui/CompleteButton.jsx'; +import HelpIcon from '../ui/HelpIcon.jsx'; +const popupId = 'XYColSelect'; +const TBL_ID ='selectCol'; + +const popupPanelResizableStyle = { + width: 600, + minWidth: 450, + height: 450, + minHeight: 300, + resize: 'both', + overflow: 'hidden', + position: 'relative' +}; + + +//define the table style only in the table div +const tableStyle = {boxSizing: 'border-box', paddingLeft:5,paddingRight:5, width: '100%', height: 'calc(100% - 70px)', overflow: 'hidden', flexGrow: 1, display: 'flex', resize:'none'}; + +//define the complete button +const closeButtonStyle = {'textAlign': 'center', display: 'inline-block', height:40, marginTop:10, width: '90%'}; +//define the helpButton +const helpIdStyle = {'textAlign': 'center', display: 'inline-block', height:40, marginRight: 20}; + + +export function showColSelectPopup(colValStats,onColSelected,popupTitle,buttonText,currentVal) { + + if (getTblById(TBL_ID)) { +        dispatchTableRemove(TBL_ID); +    } + + const colNames = colValStats.map((colVal) => {return colVal.name;}); + var hlRowNum = getHlRow(currentVal,colNames) || 0; + + // make a local table for plot column selection panel + var columns = [ + {name: 'Name',visibility: 'show', prefWidth: 12}, + {name: 'Unit',visibility: 'show', prefWidth: 8}, + {name: 'Type',visibility: 'show', prefWidth: 8}, + {name: 'Description',visibility: 'show', prefWidth: 60} + ]; + var data = []; + for (var i = 0; i < colValStats.length; i++) { + data[i] = [ + colValStats[i].name, + colValStats[i].unit, + colValStats[i].type, + colValStats[i].descr + ]; + } + const request = {pageSize:10000}; + var tableModel = {totalRows: data.length, request, tbl_id:TBL_ID, tableData: {columns, data }, highlightedRow: hlRowNum}; + + + var popup = ( + {popupForm(tableModel,onColSelected,buttonText,popupId)} + + + ); + + DialogRootContainer.defineDialog(popupId, popup); + dispatchShowDialog(popupId); +} + +function popupForm(tableModel, onColSelected,buttonText,popupId) { + const tblId = tableModel.tbl_id; + return ( +
+ { renderTable(tableModel,popupId)} + { renderCloseAndHelpButtons(tblId,onColSelected,buttonText,popupId)} +
+ ); + +} + +/** + * display the data into a tabular format + * @param tableModel + * @param popupId + * @return table section + */ +function renderTable(tableModel,popupId) { + + return ( +
+ +
+ ); + +} + +function renderCloseAndHelpButtons(tblId,onColSelected,buttonText,popupId) { + + return( +
+
+ < CompleteButton + text={buttonText} + onSuccess={()=>setXYColumns(tblId,onColSelected)} + dialogId={popupId} + /> +
+ {/* comment out the help button for now +
+ +
+ */} +
+); +} + +function setXYColumns(tblId,onColSelected) { + const tableModel = getTblById(tblId); + var hlRow = tableModel.highlightedRow || 0; + const selectedColName = tableModel.tableData.data[hlRow][0]; +    onColSelected(selectedColName); + +} + +function getHlRow(currentVal,colNames) { + for(var i = 0; i < colNames.length; i++) { + if (colNames[i] === currentVal) { + return i; + } + } +} \ No newline at end of file diff --git a/src/firefly/js/visualize/ColValuesStatistics.js b/src/firefly/js/visualize/ColValuesStatistics.js index ca66a61814..4b8f6e7401 100644 --- a/src/firefly/js/visualize/ColValuesStatistics.js +++ b/src/firefly/js/visualize/ColValuesStatistics.js @@ -1,10 +1,11 @@ export default class ColValuesStatistics{ - constructor(name, descr, unit, min, max, numpoints) { + constructor(name, descr, unit, min, max, numpoints,type) { this.name = name; this.descr = descr; this.unit = unit; this.min = Number(min); this.max = Number(max); this.numpoints = Number(numpoints); + this.type = type; } }; \ No newline at end of file diff --git a/src/firefly/js/visualize/TableStatsCntlr.js b/src/firefly/js/visualize/TableStatsCntlr.js index 059f6d88da..9d2f35ab17 100644 --- a/src/firefly/js/visualize/TableStatsCntlr.js +++ b/src/firefly/js/visualize/TableStatsCntlr.js @@ -1,6 +1,6 @@ import {flux} from '../Firefly.js'; -import {has, omit} from 'lodash'; +import {get, has, omit} from 'lodash'; import {updateSet, updateMerge} from '../util/WebUtil.js'; import ColValuesStatistics from './ColValuesStatistics.js'; @@ -129,15 +129,23 @@ function fetchTblStats(dispatch, activeTableServerRequest) { const sreq = Object.assign({}, omit(activeTableServerRequest, ['tbl_id', 'META_INFO']), {'startIdx': 0, 'pageSize': 1000000}); - const req = TableUtil.makeTblRequest('StatisticsProcessor', null, - { searchRequest: JSON.stringify(sreq) }, - 'tblstats-'+tbl_id); + const req = TableUtil.makeTblRequest('StatisticsProcessor', `Statistics for ${tbl_id}`, + { searchRequest: JSON.stringify(sreq) }, + {'startIdx': 0, 'pageSize': 1000}); TableUtil.doFetchTable(req).then( (tableModel) => { if (tableModel.tableData && tableModel.tableData.data) { + const columns = get(TableUtil.getTblById(tbl_id), 'tableData.columns', []); const colStats = tableModel.tableData.data.reduce((colstats, arow) => { - colstats.push(new ColValuesStatistics(...arow)); + const r = new ColValuesStatistics(...arow); + const col = columns.find((c)=>{return c.name=== r.name;}); + if (col) { + r.unit = col.units && col.units !== 'null' ? col.units : ''; + r.descr = col.desc ? col.desc: ''; + r.type = col.type ? col.type : ''; + } + colstats.push(r); return colstats; }, []); dispatch(updateTblStats( diff --git a/src/firefly/js/visualize/XYPlotOptions.jsx b/src/firefly/js/visualize/XYPlotOptions.jsx index a9686130de..1ec0672808 100644 --- a/src/firefly/js/visualize/XYPlotOptions.jsx +++ b/src/firefly/js/visualize/XYPlotOptions.jsx @@ -17,10 +17,12 @@ import {RadioGroupInputField} from '../ui/RadioGroupInputField.jsx'; import {SuggestBoxInputField} from '../ui/SuggestBoxInputField.jsx'; import {FieldGroupCollapsible} from '../ui/panel/CollapsiblePanel.jsx'; import {plotParamsShape} from './XYPlot.jsx'; +import {showColSelectPopup} from './ColSelectView.jsx'; const DECI_ENABLE_SIZE = 5000; const helpStyle = {fontStyle: 'italic', color: '#808080', paddingBottom: 10}; +import {TextButton} from '../ui/TextButton.jsx'; /* * Split content into prior content and the last alphanumeric token in the text @@ -116,6 +118,23 @@ export function setOptions(groupKey, xyPlotParams) { dispatchMultiValueChange(groupKey, flds); } +export function getColValidator(colValStats) { + const colNames = colValStats.map((colVal) => {return colVal.name;}); + return (val) => { + let retval = {valid: true, message: ''}; + if (!val) { + return {valid: false, message: 'Can not be empty. Please provide value or expression'}; + } else if (colNames.indexOf(val) < 0) { + const expr = new Expression(val, colNames); + if (!expr.isValid()) { + retval = {valid: false, message: `${expr.getError().error}. Unable to parse ${val}.`}; + } + } + return retval; + }; +} + + var XYPlotOptions = React.createClass({ @@ -126,6 +145,18 @@ var XYPlotOptions = React.createClass({ xyPlotParams: plotParamsShape }, + componentDidMount() { + // make sure column validator matches current columns + const {colValStats, groupKey} = this.props; + if (colValStats) { + const colValidator = getColValidator(colValStats); + const flds = [ + {fieldKey: 'x.columnOrExpr', validator: colValidator}, + {fieldKey: 'y.columnOrExpr', validator: colValidator} + ]; + dispatchMultiValueChange(groupKey, flds); + } + }, shouldComponentUpdate(np) { return this.props.groupKey !== np.groupKey || this.props.colValStats !== np.colValStats || @@ -191,7 +222,6 @@ var XYPlotOptions = React.createClass({ render() { const { colValStats, groupKey, xyPlotParams, onOptionsSelected}= this.props; - const colNames = colValStats.map((colVal) => {return colVal.name;}); // the suggestions are indexes in the colValStats array - it makes it easier to render then with labels const allSuggestions = colValStats.map((colVal,idx)=>{return idx;}); @@ -212,19 +242,27 @@ var XYPlotOptions = React.createClass({ return priorContent+colValStats[idx].name; }; - const colValidator = (val) => { - let retval = {valid: true, message: ''}; - if (!val) { - return {valid: false, message: 'Can not be empty. Please provide value or expression'}; - } else if (colNames.indexOf(val)<0) { - const expr = new Expression(val,colNames); - if (!expr.isValid()) { - retval = {valid: false, message: `${expr.getError().error}. Unable to parse ${val}.`}; - } - } - return retval; - }; - + var x = get(xyPlotParams, 'x.columnOrExpr'); +        var y = get(xyPlotParams, 'y.columnOrExpr'); + const onXColSelected = (colName) => { +            x = colName; + const flds = [ +                {fieldKey: 'x.columnOrExpr', value: colName}, +                {fieldKey: 'x.label', value: ''}, +                {fieldKey: 'x.unit', value: ''} +            ]; +            dispatchMultiValueChange(groupKey, flds); +        }; +        const onYColSelected = (colName) => { + y = colName; +            const flds = [ +                {fieldKey: 'y.columnOrExpr', value: colName}, +                {fieldKey: 'y.label', value: ''}, +                {fieldKey: 'y.unit', value: ''} +            ]; +            dispatchMultiValueChange(groupKey, flds); +        }; +                                          return (

@@ -233,21 +271,42 @@ var XYPlotOptions = React.createClass({ For X and Y, enter a column or an expression
ex. log(col); 100*col1/col2; col1-col2
- + + + + + + + +
+
+ +
+
+
+ showColSelectPopup(colValStats, onXColSelected,'Choose X','Set X',x)} + onSuccess={this.resultsSuccess} + onFail={this.resultsFail} + /> +
+
+ @@ -291,21 +350,42 @@ var XYPlotOptions = React.createClass({
- + + + + + + + +
+
+ +
+
+
+ showColSelectPopup(colValStats,onYColSelected,'Choose Y','Set Y',y)} + onSuccess={this.resultsSuccess} + onFail={this.resultsFail} + /> +
+
+ From 893a25c8a223a7ef8a644bf92d32efa2d6ecbd4f Mon Sep 17 00:00:00 2001 From: wmi Date: Fri, 8 Jul 2016 16:13:50 -0700 Subject: [PATCH 10/10] remove TextButton.css --- src/firefly/js/ui/TextButton.css | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/firefly/js/ui/TextButton.css diff --git a/src/firefly/js/ui/TextButton.css b/src/firefly/js/ui/TextButton.css deleted file mode 100644 index e9bb92dc7f..0000000000 --- a/src/firefly/js/ui/TextButton.css +++ /dev/null @@ -1,20 +0,0 @@ - -.ff-MenuItem-linkButton { - padding: 5px; - -moz-border-radius: 0 0 5px 5px; - -webkit-border-radius: 0 0 5px 5px; - border-radius: 0 0 5px 5px; - background-color: rgba(245,245,245,.97); - -webkit-box-shadow: 0px 5px 10px rgba(0,0,0,0.3); - -moz-box-shadow: 0px 5px 10px rgba(0,0,0,0.3); - box-shadow: 0px 5px 10px rgba(0,0,0,0.3); -} - -.ff-MenuItem-linkButton .menuItemText { - font-size: 10pt; - line-height: 14pt; -} - -.ff-MenuItem-linkButton .menuItemText:HOVER { - background-color: rgba(255,255,255,.97); -}