diff --git a/src/firefly/html/firefly.html b/src/firefly/html/firefly.html index 9192839f08..e5a46d916e 100644 --- a/src/firefly/html/firefly.html +++ b/src/firefly/html/firefly.html @@ -21,7 +21,9 @@ ] }, MenuItemKeys: {maskOverlay:true}, - imageTabs: [ 'fileUpload', 'url', '2mass', 'wise', 'sdss', 'msx', 'dss', 'iras' ] + imageTabs: [ 'fileUpload', 'url', '2mass', 'wise', 'sdss', 'msx', 'dss', 'iras' ], + irsaCatalogFilter: 'lsstFilter', + catalogSpacialOp: 'polygonWhenPlotExist' }; diff --git a/src/firefly/html/images/icons-2014/RecenterImage-selection.png b/src/firefly/html/images/icons-2014/RecenterImage-selection.png new file mode 100755 index 0000000000..88bc8b2871 Binary files /dev/null and b/src/firefly/html/images/icons-2014/RecenterImage-selection.png differ diff --git a/src/firefly/html/images/icons-2014/ZoomFitToSpace.png b/src/firefly/html/images/icons-2014/ZoomFitToSelectedSpace.png similarity index 100% rename from src/firefly/html/images/icons-2014/ZoomFitToSpace.png rename to src/firefly/html/images/icons-2014/ZoomFitToSelectedSpace.png diff --git a/src/firefly/js/fieldGroup/FieldGroupCntlr.js b/src/firefly/js/fieldGroup/FieldGroupCntlr.js index 86b5c432f3..36fff9caa7 100644 --- a/src/firefly/js/fieldGroup/FieldGroupCntlr.js +++ b/src/firefly/js/fieldGroup/FieldGroupCntlr.js @@ -346,8 +346,8 @@ const updateFieldGroupMount= function(state,action) { else { retState= initFieldGroup(state,action); retState[groupKey].mounted= true; - retState[groupKey].fields= fireFieldsReducer(retState[groupKey], action); } + retState[groupKey].fields= fireFieldsReducer(retState[groupKey], action); } else { if (isFieldGroupDefined(state,groupKey)) { diff --git a/src/firefly/js/ui/CatalogSearchMethodType.jsx b/src/firefly/js/ui/CatalogSearchMethodType.jsx index 436935b299..17810189ad 100644 --- a/src/firefly/js/ui/CatalogSearchMethodType.jsx +++ b/src/firefly/js/ui/CatalogSearchMethodType.jsx @@ -6,19 +6,24 @@ import React, {Component, PropTypes} from 'react'; import {get} from 'lodash'; import {ValidationField} from '../ui/ValidationField.jsx'; +import {VALUE_CHANGE, dispatchValueChange} from '../fieldGroup/FieldGroupCntlr.js'; import {TargetPanel} from '../ui/TargetPanel.jsx'; +import {PlotAttribute} from '../visualize/WebPlot.js'; import Validate from '../util/Validate.js'; import Enum from 'enum'; import FieldGroupUtils from '../fieldGroup/FieldGroupUtils.js'; +import {clone} from '../util/WebUtil.js'; +import {RadioGroupInputField} from './RadioGroupInputField.jsx'; import {ListBoxInputField} from './ListBoxInputField.jsx'; import {SizeInputFields} from './SizeInputField.jsx'; import {InputAreaFieldConnected} from './InputAreaField.jsx'; import {FileUpload} from '../ui/FileUpload.jsx'; +import {FieldGroup} from './FieldGroup.jsx'; import CsysConverter from '../visualize/CsysConverter.js'; -import {primePlot} from '../visualize/PlotViewUtil.js'; -import { makeImagePt} from '../visualize/Point.js'; +import {primePlot, getActivePlotView} from '../visualize/PlotViewUtil.js'; +import { makeImagePt, makeWorldPt, makeScreenPt} from '../visualize/Point.js'; import {visRoot} from '../visualize/ImagePlotCntlr.js'; import './CatalogSearchMethodType.css'; @@ -47,16 +52,33 @@ export class CatalogSearchMethodType extends Component { }); } + componentWillReceiveProps(nextProps) { + // const fields= FieldGroupUtils.getGroupFields(this.nextProps.groupKey); + const {coneMax, boxMax, groupKey}= nextProps; + if (coneMax && boxMax && groupKey) { + const fields= FieldGroupUtils.getGroupFields(this.props.groupKey); + if (this.iAmMounted) this.setState({fields}); + const searchType = get(fields, 'spatial.value', SpatialMethod.Cone.value); + const max= searchType===SpatialMethod.Box.value ? boxMax : coneMax; + + if (fields.conesize.max!==max) { + dispatchValueChange({fieldKey:'conesize', groupKey, max, min:1/3600}); + } + } + } + render() { const {fields}= this.state; + const {groupKey, polygonDefWhenPlot}= this.props; + + const polyIsDef= polygonDefWhenPlot && primePlot(visRoot()); - let searchType = get(fields, 'spatial.value', SpatialMethod.Cone.value); - const max = get(fields, 'conesize.max', 10); - const {groupKey} = this.props; + const searchType = get(fields, 'spatial.value', SpatialMethod.Cone.value); return ( -
+ {renderTargetPanel(groupKey, searchType)}
@@ -66,15 +88,15 @@ export class CatalogSearchMethodType extends Component { tooltip: 'Enter a search method', label : 'Method Search:', labelWidth: 80, - value:SpatialMethod.Cone.value + value: polyIsDef ? SpatialMethod.Polygon.value : SpatialMethod.Cone.value }} options={ spatialOptions() } wrapperStyle={{marginRight:'15px', padding:'10px 0 5px 0'}} multiple={false} /> - {sizeArea(searchType, max)} + {sizeArea(searchType, get(fields, 'imageCornerCalc.value', 'image'))}
-
+ ); } @@ -102,36 +124,87 @@ const spatialOptions = () => { return l; }; + + +function calcCornerString(pv, method) { + if (method==='clear' || !pv) return ''; + const f5 = (v) => v.toFixed(5); + + var pt1, pt2, pt3, pt4; + const plot = primePlot(pv); + const sel= plot.attributes[PlotAttribute.SELECTION]; + var w = plot.dataWidth; + var h = plot.dataHeight; + var cc = CsysConverter.make(plot); + if (method==='image' || (!sel && method==='area-selection') ) { + pt1 = cc.getWorldCoords(makeImagePt(w/4,h/4)); + pt2 = cc.getWorldCoords(makeImagePt(3*w/4, h/4)); + pt3 = cc.getWorldCoords(makeImagePt(3*w/4, 3*h/4)); + pt4 = cc.getWorldCoords(makeImagePt(w/4, 3*h/4)); + } + else if (method==='viewport') { + const {viewDim, scrollX, scrollY}= pv; + const {screenSize}= plot; + var sx1, sx3, sy1, sy3; + if (viewDim.width>screenSize.width) { + sx1= scrollX; + sx3= scrollX+ (screenSize.width-viewDim.width); + } + else { + sx1= 0; + sx3= screenSize.width; + } + if (viewDim.height>screenSize.height) { + sy1= scrollY; + sy3= scrollY+ (screenSize.height-viewDim.height); + } + else { + sy1= 0; + sy3= screenSize.height; + } + pt1= cc.getWorldCoords(makeScreenPt(sx1,sy1)); + pt2= cc.getWorldCoords(makeScreenPt(sx3,sy1)); + pt3= cc.getWorldCoords(makeScreenPt(sx3,sy3)); + pt4= cc.getWorldCoords(makeScreenPt(sx1,sy3)); + } + else if (method==='area-selection') { + pt1 = cc.getWorldCoords(sel.pt0); + pt3 = cc.getWorldCoords(sel.pt1); + pt2 = makeWorldPt( pt1.x, pt3.y, pt1.cSys ); + pt4 = makeWorldPt( pt3.x, pt1.y, pt1.cSys ); + } + return `${f5(pt1.x)} ${f5(pt1.y)}, ${f5(pt2.x)} ${f5(pt2.y)}, ${f5(pt3.x)} ${f5(pt3.y)}, ${f5(pt4.x)} ${f5(pt4.y)}`; +} + + + /** * Return a {SizeInputFields} component by passing in the few paramters needed only. * labelwidth = 100 is fixed. - * @param {string} label by default is 'Radius' - * @param {string} tooltip by default is the radius size tooltip - * @param {number} min by default 1 arcsec - * @param {number} max by default is 1 degree (3600 arcsec) - * @returns {XML} SizeInputFields component + * @param {Object} p + * @param {string} p.label by default is 'Radius' + * @param {string} p.tooltip by default is the radius size tooltip + * @param {number} p.min by default 1 arcsec + * @param {number} p.max by default is 1 degree (3600 arcsec) + * @returns {Object} SizeInputFields component */ -function radiusInField({label = 'Radius:', tooltip = 'Enter radius of the search', min = 1 / 3600, max = 1}) { +function radiusInField({label = 'Radius:'}) { return ( ); } -function sizeArea(searchType, max) { +function sizeArea(searchType, imageCornerCalc) { if (searchType === SpatialMethod.Cone.value) { return (
- {radiusInField({max})} + {radiusInField({})}
); } else if (searchType === SpatialMethod.Elliptical.value) { @@ -165,12 +238,7 @@ function sizeArea(searchType, max) { return (
- {radiusInField({ - label: 'Side:', - tooltip: 'Enter side size of the box search', - min: 1 / 3600, - max: 7200 / 3600 - })} + {radiusInField({ label: 'Side:' })}
); @@ -189,29 +257,33 @@ function sizeArea(searchType, max) { ); } else if (searchType === SpatialMethod.Polygon.value) { - let val = ''; - var pv = primePlot(visRoot()); - if (pv) { - var plot = pv; - var w = plot.dataWidth; - var h = plot.dataHeight; - var cc = CsysConverter.make(plot); - var pt1 = cc.getWorldCoords(makeImagePt(w/4,h/4)); - var pt2 = cc.getWorldCoords(makeImagePt(3*w/4, h/4)); - var pt3 = cc.getWorldCoords(makeImagePt(3*w/4, 3*h/4)); - var pt4 = cc.getWorldCoords(makeImagePt(w/4, 3*h/4)); - val = `${pt1.x} ${pt1.y}, ${pt2.x} ${pt2.y},${pt3.x} ${pt3.y},${pt4.x} ${pt4.y}`; + const cornerTypeOps= + [ + {label: 'Image', value: 'image'}, + {label: 'ViewPort', value: 'viewport'}, + {label: 'User', value: 'user'} + ]; + + + + const pv= getActivePlotView(visRoot()); + var plot = primePlot(pv); + + if (imageCornerCalc!=='clear' && plot) { + const sel= plot.attributes[PlotAttribute.SELECTION]; + if (sel) { + cornerTypeOps.splice(cornerTypeOps.length-1, 0, {label: 'Selection', value: 'area-selection'}); + } } return (
- - Vertices must be separated by a comma (,)
  • - Example: 20.7 21.5, 20.5 20.5, 21.5 20.5, 21.5 21.5
  • +
    + {pv && + } +
    ); @@ -247,7 +334,8 @@ function renderTargetPanel(groupKey, searchType) { } CatalogSearchMethodType.propTypes = { - groupKey: PropTypes.string.isRequired + groupKey: PropTypes.string.isRequired, + polygonDefWhenPlot: PropTypes.bool, }; /*CatalogSearchMethodType.contextTypes = { @@ -272,4 +360,56 @@ var initRadiusArcSec = (max) => { } else { return parseFloat(1 / 3600).toString(); } -}; \ No newline at end of file +}; + + + +function searchMethodTypeReducer(inFields, action) { + if (!inFields) { + return fieldInit(); + } + else { + const {fieldKey}= action.payload; + const rFields= clone(inFields); + if (action.type===VALUE_CHANGE && fieldKey==='polygoncoords') { + rFields.imageCornerCalc= clone(inFields.imageCornerCalc, {value:'user'}); + } + else { + const cornerCalcV= get(inFields.imageCornerCalc, 'value', 'user'); + const pv= getActivePlotView(visRoot()); + + + if (pv && (cornerCalcV==='image' || cornerCalcV==='viewport' || cornerCalcV==='area-selection')) { + const plot = primePlot(pv); + const sel= plot.attributes[PlotAttribute.SELECTION]; + if (!sel && cornerCalcV==='area-selection') { + rFields.imageCornerCalc= clone(inFields.imageCornerCalc, {value:'image'}); + } + const {value:cornerCalcV}= rFields.imageCornerCalc; + const v= calcCornerString(pv,cornerCalcV); + rFields.polygoncoords= clone(inFields.polygoncoords, {value:v}); + } + } + rFields && rFields.polygoncoords && console.log(rFields.polygoncoords.value); + return rFields; + } +} + +function fieldInit() { + return ( + { + conesize: { + fieldKey: 'conesize', + value: initRadiusArcSec(3600), + unit: 'arcsec', + min: 1 / 3600, + max: 100, + }, + imageCornerCalc: { + fieldKey: 'imageCornerCalc', + value: 'image' + } + + } + ); +} diff --git a/src/firefly/js/visualize/ZoomUtil.js b/src/firefly/js/visualize/ZoomUtil.js index 1795d869e0..37372f7ccd 100644 --- a/src/firefly/js/visualize/ZoomUtil.js +++ b/src/firefly/js/visualize/ZoomUtil.js @@ -258,7 +258,7 @@ export function getNextZoomLevel(currLevel, zoomType) { else if (zoomType===UserZoomTypes.ONE) { newLevel= 1; } - else if (zoomType==UserZoomTypes.DOWN) { + else if (zoomType===UserZoomTypes.DOWN) { newLevel= levels[0]; let found= false; for(let i= levels.length-1; (i>=0); i--) { diff --git a/src/firefly/js/visualize/task/PlotImageTask.js b/src/firefly/js/visualize/task/PlotImageTask.js index c8a78c604e..bb28179460 100644 --- a/src/firefly/js/visualize/task/PlotImageTask.js +++ b/src/firefly/js/visualize/task/PlotImageTask.js @@ -56,7 +56,7 @@ const getFirstReq= (wpRAry) => isArray(wpRAry) ? wpRAry.find( (r) => r?true:fals function makeSinglePlotPayload(vr, rawPayload ) { - var {wpRequest,plotId, threeColor, viewerId, attributes, + var {wpRequest,plotId, threeColor, viewerId, attributes, setNewPlotAsActive, holdWcsMatch= false, pvOptions= {}, addToHistory= false,useContextModifications= true}= rawPayload; wpRequest= ensureWPR(wpRequest); @@ -84,7 +84,7 @@ function makeSinglePlotPayload(vr, rawPayload ) { plotGroupId:req.getPlotGroupId(), groupLocked:req.isGroupLocked(), attributes, viewerId, pvOptions, addToHistory, - useContextModifications, threeColor}; + useContextModifications, threeColor, setNewPlotAsActive}; if (threeColor) { if (isArray(wpRequest)) { diff --git a/src/firefly/js/visualize/ui/CatalogSelectViewPanel.jsx b/src/firefly/js/visualize/ui/CatalogSelectViewPanel.jsx index 7ea9a8ceaa..419a67a85f 100644 --- a/src/firefly/js/visualize/ui/CatalogSelectViewPanel.jsx +++ b/src/firefly/js/visualize/ui/CatalogSelectViewPanel.jsx @@ -5,7 +5,7 @@ import React, {Component, PropTypes} from 'react'; import sCompare from 'react-addons-shallow-compare'; import {FormPanel} from '../../ui/FormPanel.jsx'; -import { get, merge, isEmpty} from 'lodash'; +import { get, merge, isEmpty, isFunction} from 'lodash'; import {updateMerge} from '../../util/WebUtil.js'; import {ListBoxInputField} from '../../ui/ListBoxInputField.jsx'; import {doFetchTable, makeTblRequest, makeIrsaCatalogRequest, makeVOCatalogRequest, getTblById} from '../../tables/TableUtil.js'; @@ -13,7 +13,6 @@ import {CatalogTableListField} from './CatalogTableListField.jsx'; import {CatalogConstraintsPanel} from './CatalogConstraintsPanel.jsx'; import {FieldGroup} from '../../ui/FieldGroup.jsx'; import FieldGroupCntlr from '../../fieldGroup/FieldGroupCntlr.js'; -import {fieldGroupConnector} from '../../ui/FieldGroupConnector.jsx'; import FieldGroupUtils from '../../fieldGroup/FieldGroupUtils'; import {FieldGroupTabs, Tab} from '../../ui/panel/TabPanel.jsx'; import {dispatchHideDropDown} from '../../core/LayoutCntlr.js'; @@ -26,6 +25,7 @@ import {parseWorldPt} from '../../visualize/Point.js'; import {VoSearchPanel} from '../../ui/VoSearchPanel.jsx'; import {FileUpload} from '../../ui/FileUpload.jsx'; import {convertAngle} from '../VisUtil.js'; +import {masterTableFilter} from './IrsaMasterTableFilters.js'; import './CatalogTableListField.css'; import './CatalogSelectViewPanel.css'; @@ -34,6 +34,7 @@ import './CatalogSelectViewPanel.css'; * group key for fieldgroup comp */ export const gkey = 'CATALOG_PANEL'; +export const gkeySpacial = 'CATALOG_PANEL_spacial'; const dropdownName = 'IrsaCatalogDropDown'; @@ -78,7 +79,7 @@ export class CatalogSelectViewPanel extends Component {
    onSearchSubmit(request)} onCancel={hideSearchPanel}> @@ -104,11 +105,12 @@ function validConstraints(groupKey) { function onSearchSubmit(request) { console.log('original request
    ' + JSON.stringify(request)); - if (request.Tabs === 'catalog') { - const wp = parseWorldPt(request[ServerParams.USER_TARGET_WORLD_PT]); - if (!wp && (request.spatial === SpatialMethod.Cone.value - || request.spatial === SpatialMethod.Box.value - || request.spatial === SpatialMethod.Elliptical.value)) { + if (request[gkey].Tabs === 'catalog') { + const {spatial} = request[gkeySpacial]; + const wp = parseWorldPt(request[gkeySpacial][ServerParams.USER_TARGET_WORLD_PT]); + if (!wp && (spatial === SpatialMethod.Cone.value + || spatial === SpatialMethod.Box.value + || spatial === SpatialMethod.Elliptical.value)) { showInfoPopup('Target is required'); return; } @@ -116,11 +118,11 @@ function onSearchSubmit(request) { doCatalog(request); } } - else if (request.Tabs === 'loadcat') { - doLoadTable(request); + else if (request[gkey].Tabs === 'loadcat') { + doLoadTable(request[gkey]); } - else if (request.Tabs === 'vosearch') { - doVoSearch(request); + else if (request[gkey].Tabs === 'vosearch') { + doVoSearch(request[gkey]); } else { console.log('request no supported'); @@ -132,55 +134,60 @@ function hideSearchPanel() { function doCatalog(request) { - const conesize = convertAngle('deg', 'arcsec', request.conesize); - var title = `${request.project}-${request.cattable}`; + const catPart= request[gkey]; + const spacPart= request[gkeySpacial]; + const {catalog, project, cattable}= catPart; + const {spatial}= spacPart; + + const conesize = convertAngle('deg', 'arcsec', spacPart.conesize); + var title = `${catPart.project}-${catPart.cattable}`; var tReq = {}; - if (request.spatial === SpatialMethod.get('Multi-Object').value) { - var filename = request.fileUpload; + if (spatial === SpatialMethod.get('Multi-Object').value) { + var filename = catPart.fileUpload; var radius = conesize; - tReq = makeIrsaCatalogRequest(title, request.project, request.cattable, { + tReq = makeIrsaCatalogRequest(title, catPart.project, catPart.cattable, { filename, radius, - SearchMethod: request.spatial, - RequestedDataSet: request.catalog + SearchMethod: spacPart.spatial, + RequestedDataSet: catalog }); } else { - title += ` (${request.spatial}`; - if (request.spatial === SpatialMethod.Box.value || request.spatial === SpatialMethod.Cone.value || request.spatial === SpatialMethod.Elliptical.value) { + title += ` (${spatial}`; + if (spatial === SpatialMethod.Box.value || spatial === SpatialMethod.Cone.value || spatial === SpatialMethod.Elliptical.value) { title += ':' + conesize + '\'\''; } title += ')'; - tReq = makeIrsaCatalogRequest(title, request.project, request.cattable, { - SearchMethod: request.spatial, - RequestedDataSet: request.catalog + tReq = makeIrsaCatalogRequest(title, project, cattable, { + SearchMethod: spatial, + RequestedDataSet: catalog }); } // change and merge others parameters in request if elliptical // plus change spatial name to cone // (Gator search method for elliptical is cone) - if (request.spatial === SpatialMethod.Elliptical.value) { + if (spatial === SpatialMethod.Elliptical.value) { - const pa = get(request, 'posangle', 0); - const ar = get(request, 'axialratio', 0.26); + const pa = get(spacPart, 'posangle', 0); + const ar = get(spacPart, 'axialratio', 0.26); // see PA and RATIO string values in edu.caltech.ipac.firefly.server.catquery.GatorQuery merge(tReq, {'posang': pa, 'ratio': ar}); } - if (request.spatial === SpatialMethod.Cone.value - || request.spatial === SpatialMethod.Box.value - || request.spatial === SpatialMethod.Elliptical.value) { - merge(tReq, {[ServerParams.USER_TARGET_WORLD_PT]: request[ServerParams.USER_TARGET_WORLD_PT]}); - if (request.spatial === SpatialMethod.Box.value) { + if (spatial === SpatialMethod.Cone.value + || spatial === SpatialMethod.Box.value + || spatial === SpatialMethod.Elliptical.value) { + merge(tReq, {[ServerParams.USER_TARGET_WORLD_PT]: spacPart[ServerParams.USER_TARGET_WORLD_PT]}); + if (spatial === SpatialMethod.Box.value) { tReq.size = conesize; } else { tReq.radius = conesize; } } - if (request.spatial === SpatialMethod.Polygon.value) { - tReq.polygon = request.polygoncoords; + if (spatial === SpatialMethod.Polygon.value) { + tReq.polygon = spacPart.polygoncoords; } const {tableconstraints} = FieldGroupUtils.getGroupFields(gkey); @@ -292,7 +299,10 @@ class CatalogSelectView extends Component { loadMasterCatalogTable() { const request = {id: 'irsaCatalogMasterTable'}; //Fetch master table - doFetchTable(request).then((tableModel) => { + doFetchTable(request).then((originalTableModel) => { + + const filter= get(window.firefly, 'irsaCatalogFilter', 'defaultFilter'); + const tableModel= isFunction(filter) ? filter(tableModel) : masterTableFilter[filter](originalTableModel); var data = tableModel.tableData.data; @@ -486,12 +496,12 @@ var userChangeDispatch = function () { } //No need to act on other fields if user change user wpt or spatial method - if (fieldKey === 'UserTargetWorldPt' - || fieldKey === 'conesize') { - - break; - - } + // if (fieldKey === 'UserTargetWorldPt' + // || fieldKey === 'conesize') { + // + // break; + // + // } const radius = parseFloat(catTable[currentIdx].cat[7]); const coldef = catTable[currentIdx].cat[9] === 'null' ? catTable[currentIdx].cat[8] : catTable[currentIdx].cat[9]; @@ -514,7 +524,7 @@ var userChangeDispatch = function () { break; case FieldGroupCntlr.CHILD_GROUP_CHANGE: - console.log('Child group change called...'); + // console.log('Child group change called...'); break; default: break; @@ -611,10 +621,21 @@ class CatalogDDList extends Component { // selProject0 = selProj; //} // Build option list for project, sub-project and catalog table based on the selected or initial value of project and sub-project + + + + optProjects = getProjectOptions(this.props.master.catmaster); optList = getSubProjectOptions(catmaster, selProj); catTable = getCatalogOptions(catmaster, selProj, selCat).option; + //HERE HERE HERE + const currentIdx = get(this.props.fields, 'cattable.indexClicked', 0); + const radius = parseFloat(catTable[currentIdx].cat[7]); + const coneMax= radius / 3600; + const boxMax= coneMax*2; + //HERE HERE HERE + let catname0 = get(FieldGroupUtils.getGroupFields(gkey), 'cattable.value', catTable[0].value); if(isEmpty(catname0)){ catname0 = catTable[0].value; @@ -624,6 +645,11 @@ class CatalogDDList extends Component { const tbl_id = `${catname0}-${shortdd}-dd-table-constraint`; const {cols} = this.props.master; + + + const polygonDefWhenPlot= get(window.firefly, 'catalogSpacialOp')==='polygonWhenPlotExist'; + + return (
    @@ -657,7 +683,8 @@ class CatalogDDList extends Component { />
    - +
    {/* @@ -683,7 +710,8 @@ class CatalogDDList extends Component { } CatalogSelectViewPanel.propTypes = { - name: PropTypes.oneOf([dropdownName]) + name: PropTypes.oneOf([dropdownName]), + fields: PropTypes.object }; CatalogSelectViewPanel.defaultProps = { diff --git a/src/firefly/js/visualize/ui/IrsaMasterTableFilters.js b/src/firefly/js/visualize/ui/IrsaMasterTableFilters.js new file mode 100644 index 0000000000..5b55b0cd10 --- /dev/null +++ b/src/firefly/js/visualize/ui/IrsaMasterTableFilters.js @@ -0,0 +1,39 @@ +/* + * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt + */ +import {getColumnIdx} from '../../tables/TableUtil.js'; +import {clone} from '../../util/WebUtil.js'; + + +export const masterTableFilter = { + defaultFilter : (tableModel) => tableModel, + lsstFilter : lsstFilter +}; + + +const filterOut= ['TAP_SCHEMA']; +const lsstTblOrder= ['Gaia', 'WISE', '2MASS', 'SPITZER']; + +function getColPriority(c) { + const idx= lsstTblOrder.findIndex( (v) => v===c); + return idx===-1 ? lsstTblOrder.length : idx; +} + + +function lsstFilter(tableModel) { + const pIdx= getColumnIdx(tableModel, 'projectshort'); + if (pIdx<0) return tableModel; + + var retData= tableModel.tableData.data + .filter((r) => !filterOut.find( (out) => out===r[pIdx])) + .sort( (r1,r2) => { + const c1P= getColPriority(r1[pIdx]); + const c2P= getColPriority(r2[pIdx]); + return c1P { - return dispatchExtensionActivate(ext,makeExtActivateData(ext,pv,dlAry))}/> + return ( + dispatchExtensionActivate(ext,makeExtActivateData(ext,pv,dlAry))}/> + ); } ); } +function recenterToSelection(pv) { + const p= primePlot(pv); + if (!p) return; + const {viewDim,plotId}= pv; + const cc= CysConverter.make(p); + const sel= p.attributes[PlotAttribute.SELECTION]; + if (!sel) return; + + const sp0= cc.getScreenCoords(sel.pt0); + const sp2= cc.getScreenCoords(sel.pt1); + + + const centerPt= makeScreenPt( Math.abs(sp0.x-sp2.x)/2+ Math.min(sp0.x,sp2.x), + Math.abs(sp0.y-sp2.y)/2 + Math.min(sp0.y,sp2.y)); + + const newScrollPt= makeScreenPt(centerPt.x - viewDim.width/2, centerPt.y - viewDim.height/2); + + dispatchProcessScroll({plotId,scrollPt:newScrollPt}); +} + + +function zoomIntoSelection(pv) { + + const p= primePlot(pv); + if (!p) return; + const {viewDim,plotId}= pv; + const cc= CysConverter.make(p); + const sel= p.attributes[PlotAttribute.SELECTION]; + if (!sel) return; + + const sp0= cc.getScreenCoords(sel.pt0); + const sp2= cc.getScreenCoords(sel.pt1); + const newScrollPt= cc.getImageCoords(makeScreenPt(Math.min(sp0.x,sp2.x), Math.min(sp0.y,sp2.y))); + + const level= (viewDim.width / Math.abs(sp0.x-sp2.x)) * p.zoomFactor; + + dispatchZoom({ plotId, userZoomType: UserZoomTypes.LEVEL, level }); + dispatchProcessScroll({plotId,scrollPt:newScrollPt}); + dispatchDetachLayerFromPlot(SelectArea.TYPE_ID,pv.plotId,true); +} + + /** * * @param pv @@ -301,6 +348,17 @@ export class VisCtxToolbarView extends Component { visible={showClearFilter} onClick={() => clearFilterCatalog(pv,dlAry)}/> + zoomIntoSelection(pv)}/> + recenterToSelection(pv)}/> + {makeExtensionButtons(extensionAry,pv,dlAry)}