/*
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
*/
//===================================================================================
//-----------------------------------------------------------------------------------
// Build the firefly high level api
// This file should have has no imports. It should be build the high level api completely from the lowlevel.
// There are two reasons for this.
// 1. It will be an example of how to use the lowlevel api
// 2. We want to make sure the the lowlevel api is only built with the high level. That
// way we know that the lowlevel is complete.
//-----------------------------------------------------------------------------------
//===================================================================================
/**
* @public
* @desc build highLevelApi using the lowLevelApi as an input
*/
/**
* @param llApi the lowlevel api
* @returns {Object}
* @ignore
*
*/
export function buildHighLevelApi(llApi) {
const current= build(llApi);
const deprecated= buildDeprecated(llApi);
return Object.assign({}, deprecated, current);
}
const STANDARD= 'standard';
const ENCAPSULATE= 'encapsulate';
var globalImageViewDefParams= {};
var globalPrefs= {imageDisplayType:STANDARD};
/**
* Build the deprecated API
* @param llApi
* @returns {Object}
* @ignore
*/
function build(llApi) {
const commonPart= buildCommon(llApi);
const imagePart= buildImagePart(llApi);
const chartPart= buildChartPart(llApi);
const tablePart= buildTablePart(llApi);
return Object.assign({}, commonPart, imagePart,chartPart,tablePart);
}
/*----------------------------< TABLE PART ----------------------------*/
var divToGrp = (() => {
// workaround to support mapping first targetDiv to 'main'
var main;
return (div) => {
if (!main) main = div;
return div === main ? 'main' : div;
};
})();
function oldApi(llApi, params, options) {
const {getBoolean} = llApi.util;
const {makeFileRequest} = llApi.util.table;
const oldOpts = params.tableOptions && params.tableOptions.split(',').reduce((rval, s) => {
const kval = s && s.trim().split('=');
rval[kval[0]] = kval[1];
return rval;
}, {}); // convert 'key=value' array into {key: value}.
options.showFilters = getBoolean(oldOpts, 'show-filter');
options.showTitle = getBoolean(oldOpts, 'show-title');
options.showToolbar = getBoolean(oldOpts, 'show-toolbar');
options.showOptionButton = getBoolean(oldOpts, 'show-options');
options.showPaging = getBoolean(oldOpts, 'show-paging');
options.showSave = getBoolean(oldOpts, 'show-save');
options.showUnits = getBoolean(oldOpts, 'show-units');
// options.?? = getBoolean(oldOpts, 'show-popout');
// options.?? = getBoolean(oldOpts, 'show-table-view');
var {Title, source, alt_source, type, filters, sortInfo, pageSize, startIdx, fixedLength, expandable, rowHeight} = params;
var request = makeFileRequest(Title, source, alt_source, {filters, sortInfo, pageSize, startIdx});
options.selectable = type === 'selectable';
options.help_id = 'tables';
options.expandable = !!expandable;
options.rowHeight = rowHeight;
return request;
}
function doShowTable(llApi, targetDiv, request, options={}) {
const {dispatchTableSearch}= llApi.action;
const {renderDOM}= llApi.util;
const {TablesContainer}= llApi.ui;
if ((typeof targetDiv).match(/string|HTMLDivElement/) === null) {
// old api.. need to setup request and options before continue.
const params = targetDiv;
targetDiv = request;
request = oldApi(llApi, params, options);
}
options = Object.assign({tbl_group: divToGrp(targetDiv)}, options);
const contProps = {tbl_group: options.tbl_group};
Object.keys(options).forEach( (k) => {
if (options[k] === undefined) {
Reflect.deleteProperty(options, k);
}
});
dispatchTableSearch(request, options);
renderDOM(targetDiv, TablesContainer, contProps);
}
function buildTablePart(llApi) {
/**
* @global
* @public
* @typedef {object} TblOptions
* @prop {string} tbl_group the group this table belongs to. Defaults to 'main'.
* @prop {number} pageSize the starting page size. Will use the request's pageSize if not given.
* @prop {boolean} removable true if this table can be removed from view. Defaults to true.
* @prop {boolean} backgroundable true if this search can be sent to background. Defaults to false.
* @prop {boolean} showUnits defaults to false
* @prop {boolean} showTypes defaults to false
* @prop {boolean} showFilters defaults to false
* @prop {boolean} selectable defaults to true
* @prop {boolean} expandable defaults to true
* @prop {boolean} showToolbar defaults to true
* @prop {boolean} showTitle defaults to true
* @prop {boolean} showPaging defaults to true
* @prop {boolean} showSave defaults to true
* @prop {boolean} showOptionButton defaults to true
* @prop {boolean} showFilterButton defaults to true
* @prop {boolean} showInfoButton defaults to false
* @prop {boolean} border defaults to true
* @prop {boolean} help_id link to help if applicable
* @prop {function[]} leftButtons an array of functions that returns a button-like component laid out on the left side of this table header. Function will be called with table's state.
* @prop {function[]} rightButtons an array of functions that returns a button-like component laid out on the left side of this table header. Function will be called with table's state.
*/
/**
* @param {string|HTMLDivElement} targetDiv to put the table in.
* @param {TableRequest} request request object created from
* @param {TblOptions} options table options.
* @memberof firefly
* @public
* @example var tblReq = firefly.util.table.makeIrsaCatalogRequest(
* 'allwise-500', 'WISE', 'allwise_p3as_psd',
* {position: '10.68479;41.26906;EQ_J2000',
* SearchMethod: 'Cone',
* radius: 300},
* {tbl_id: 'test-tbl',
* META_INFO: {defaultChartDef: JSON.stringify({data: [{x: 'tables::w1mpro', y: 'tables::w2mpro', mode: 'markers'}]})}
* });
* firefly.showTable('table-1', tblReq, {tbl_group: 'allwise'});
*/
// @param {module:firefly.TblOptions} options table options.
const showTable= (targetDiv, request, options) => doShowTable(llApi, targetDiv, request, options);
return {showTable};
}
/*---------------------------- TABLE PART >----------------------------*/
function buildChartPart(llApi) {
/**
* @summary The general function to plot a Plotly chart.
* @param {string|HTMLDivElement} targetDiv - div to put the chart in.
* @param {object} parameters
* @param {array.object} parameters.data - plotly data array (possibly with firefly extensions)
* @param {object} parameters.layout - plotly layout object (possibly with firefly extensions)
* @param {boolean} parameters.noChartToolbar - set true for non-interactive chart with no toolbar
* @memberof firefly
* @public
*/
const showChart = (targetDiv, parameters) => doShowChart(llApi, targetDiv, parameters);
/**
* @summary The general plotting function to plot an XY Plot.
* @param {string|HTMLDivElement} targetDiv - div to put the chart in.
* @param {XYPlotOptions} parameters - object literal with the chart parameters
* @memberof firefly
* @public
* @deprecated
* @example firefly.showXYPlot('myDiv', {source: 'mySourceFile', {xCol: 'ra', yCol: 'dec'})
*/
const showXYPlot= (targetDiv, parameters) => doShowXYPlot(llApi, targetDiv, parameters);
/**
* @summary Add XYPlot view of a table. Deprecated: use showXYPlot with tbl_id in @link{XYPlotOptions} instead.
* @param {string|HTMLDivElement} targetDiv - div to put the chart in.
* @param {XYPlotOptions} parameters - object literal with the chart parameters
* @memberof firefly
* @deprecated
* @example firefly.addXYPlot('myDiv', {tbl_id: <tbl_id>, {xCol: 'ra', yCol: 'dec'})
*/
const addXYPlot= (targetDiv, parameters) => doShowXYPlot(llApi, targetDiv, parameters);
/**
* @summary The general plotting function to plot Histogram.
* @param {string|HTMLDivElement} targetDiv - div to put the chart in.
* @param {HistogramOptions} parameters - object literal with the chart parameters
* @memberof firefly
* @public
* @deprecated
* @example firefly.showHistogram
*/
const showHistogram= (targetDiv, parameters) => doShowHistogram(llApi, targetDiv, parameters);
return {showChart, showXYPlot, addXYPlot, showHistogram};
}
function buildCommon(llApi) {
/**
* @summary Sets the root path for any relative URL. If this method has not been called then relative URLs use the page's root.
* @param {string} rootUrlPath
* @memberof firefly
* @public
*/
const setRootPath= (rootUrlPath) => llApi.action.dispatchRootUrlPath(rootUrlPath);
const setGlobalPref= (pref)=> Object.assign(globalPrefs, pref);
return {setRootPath,setGlobalPref};
}
function buildImagePart(llApi) {
const {RequestType}= llApi.util.image;
/**
* @summary object for web plot request
* @description Below is a list of predefined parameters available for web plot request.
* Some parameters control how to get an image, a image can be retrieved from a service, a url, of a file on the server.
* Others control the zoom, stretch, and color, title, and default overlays. There are also parameters to pre-process an
* image, such as crop, rotate or flip.
* @typedef {object} WebPlotParams
* @prop {string} Type the request type, see available types at {@link RequestType}.
* @prop {string} File file name of a file on the server if Type=='File'
* @prop {string} URL url reference to a fits file if Type=='URL'
* @prop {string} Service the service type if Type=='SERVICE', see available services at {@link ServiceType}
* @prop {string} plotId plot ID
* @prop {string} plotGroupId plot group ID
* @prop {String} ObjectName object name that can be looked up by NED or Simbad
* @prop {string} Resolver the object name resolver to use, options are: NED, Simbad, NedThenSimbad, SimbadThenNed, PTF.
* @prop {string} SizeInDeg the radius or side (in degrees) depending of the service type, used with Type=='SERVICE' or 'HiPS'
* @prop {string} SurveyKey the survey, used with Type='SERVICE'
* @prop {string} SurveyKeyBand the survey band, used with Type=='SERVICE' and Service='WISE', 'TWOMASS' or 'ATLAS'
* @prop {string} WorldPt target for service request or HiPS request in serialized version
* @prop {string} PlotId plot Id
* @prop {string} PlotGroupId plot group id
* @prop {string} Title plot title
* @prop {string} TitleOptions title options, see available options at {@link TitleOptions}
* @prop {string} PreTitle a String to append at the beginning of the title of the plot
* @prop {string} PostTitle a String to append at the end of the title of the plot
* @prop {string} hipsRootUrl HiPS root url or IVOID, e.g.: ivo://CDS/P/2MASS/J, used with Type='HiPS'
* @prop {string} ZoomType zoom type, see {@link ZoomType}
* @prop {string} ZoomToWidth the width of the viewable area to determine the zoom level, used with ZoomType.TO_WIDTH_HEIGHT, ZoomType.TO_WIDTH
* @prop {string} ZoomToHeight the height of the viewable area to determine the zoom level, used with ZoomType.TO_WIDTH_HEIGHT, ZoomType.TO_HEIGHT
* @prop {string} InitZoomLevel initialize zoom level, used with ZoomType.LEVEL
* @prop {string} ZoomArcsecPerScreenPix the arcseconds per screen pixel that will be used to determine the zoom level, Used with ZoomType.ARCSEC_PER_SCREEN_PIX
* @prop {boolean} RotateNorth plot should come up rotated north
* @prop {CoordinateSys} RotateNorthType set to coordinate system for rotate north, eq EQ_J2000 is the default
* @prop {boolean} Rotate set to rotate, if true, the angle should also be set
* @prop {string} RotationAngle set the angle to rotate to
* @prop {string} RotateFromNorth rotate angle from north
* @prop {boolean} FlipY set if this image should be flipped on the Y axis
* @prop {boolean} FlipX set if this image should be flipped on the X axis
* @prop {boolean} PostCrop crop the image before returning it. If rotation is set then the crop will happen post rotation
* @prop {boolean} PostCropAndCenter crop and center the image before returning it. Note: SizeInDeg and WorldPt are required
* @prop {CoordinateSys} PostCropAndCenterType set to coordinate system for crop and center, eq EQ_J2000 is the default
* @prop {string} CropPt1 one corner of the rectangle, in image coordinates, to crop out of the image.
* @prop {string} CropPt2 second corner of the rectangle, in image coordinates, to crop out of the image.
* @prop {string} CropWorldPt1 one corner of the rectangle, in world coordinates, to crop out of the image.
* @prop {string} CropWorldPt2 second corner of the rectangle, in world coordinates, to crop out of the image.
* @prop {string} OverlayPosition string of overlay position in world coordinates
* @prop {string} ColorTable color table id, value 0 - 21 to represent different predefined color tables
* @prop {string} RangeValues a complex string for specify the stretch of this plot.
* Use the method firefly.serializeRangeValues() to produce this string
* @prop {string} MultiImageIdx number index of image
* @prop {string} MultiImageExts image extension list. ex: '3,4,5' for extension 3, 4, 5
* @prop {string} GridOn turn the coordinate grid on after the image is plotted, 'true' or 'false'
* @prop {number} thumbnailSize thumbnail size
* @prop {boolean} ContinueOnFail for 3 color, if this request fails then keep trying to make a plot with the other request
*
* @global
* @public
*/
/**
* @summary The general plotting function to plot a FITS image.
* @param {String|HTMLDivElement} targetDiv to put the image in.
* @param {WebPlotParams|WebPlotRequest} request a request object with the plotting parameters
* @param {HipsImageConversionSettings} [hipsImageConversion= undefined] if defined, use these parameter to
* convert between image and HiPS
* @param {boolean} userCanDelete User can delete the image
*
* @memberof firefly
* @public
* @example firefly.showImage('myPlot',
* {Type: 'SERVICE',
* plotId: 'myImage',
* plotGroupId: 'myGroup',
* Service: 'WISE'
* Title: 'Wise'
* GridOn: true,
* SurveyKey: 'Atlas'
* SurveyKeyBand: '2'
* WorldPt: '10.68479;41.26906;EQ_J2000',
* SizeInDeg: '.12'});
*
*
*/
const showImage= (targetDiv, request, hipsImageConversion, userCanDelete) =>
showImageInMultiViewer(llApi, targetDiv, request, false, hipsImageConversion, userCanDelete);
/**
* @summary A convenience plotting function to plot a file on the server or a url. If first looks for the file then
* the url is the fallback
* @param {string|HTMLDivElement} targetDiv to put the image in.
* @param {string} file file on server
* @param {string} url url reference to a fits file
* @memberof firefly
* @public
* @ignore
* @example firefly.showImageFileOrUrl
*/
const showImageFileOrUrl= (targetDiv, file,url) =>
showImageInMultiViewer(llApi, targetDiv,
{'File' : file,
'URL' : url,
'Type' : RequestType.TRY_FILE_THEN_URL
}, false);
/**
* @summary set global fallback params for every image plotting call
* @param {Object} params a object literal such as any image plot or showImage uses
* @memberof firefly
* @public
* @ignore
* @example firefly.setGlobalImageDef
*/
const setGlobalImageDef= (params) => globalImageViewDefParams= params;
/**
*
* @param {string|HTMLDivElement} div - targetDiv to put the coverage in.
* @param {CoverageOptions} options - an object literal containing a list of the coverage options
* @memberof firefly
* @public
* @example firefly.showCoverage('myDiv', {gridOn: true})
*/
const showCoverage= (div,options) => initCoverage(llApi,div,options);
/**
* @summary The plotting function to display a HiPS
* @param {String|HTMLDivElement} targetDiv to put the image in.
* @param {WebPlotParams|WebPlotRequest} request a request object with Type=='HiPS' used to display a HiPS
* @param {HipsImageConversionSettings} [hipsImageConversion=undefined] if defined, use these parameter to
* convert between image and HiPS
* @param {boolean} userCanDelete User can delete the image
* @memberof firefly
* @public
* @example firefly.showHiPS('hipsDIV1',
* {
* plotId : 'aHipsID1-1',
* WorldPt : '148.892;69.0654;EQ_J2000',
* title : 'A HiPS',
* hipsRootUrl: 'CDS/P/SDSS9/color'
* },
* {
* imageRequestRoot: {
* Service : 'WISE',
* Title : 'Wise',
* SurveyKey: '3a',
* SurveyKeyBand: '2'
* },
* fovDegFallOver: .5
* };
* );
*
*
*/
const showHiPS= (targetDiv, request, hipsImageConversion, userCanDelete) =>
showImageInMultiViewer(llApi, targetDiv, request, true, hipsImageConversion, userCanDelete);
/**
* @summary The plotting function to display a HiPS or an image
* @param {String|HTMLDivElement} targetDiv to put the image in.
* @param {WebPlotParams|WebPlotRequest} hipsRequest a request object used to display a HiPS
* @param {WebPlotParams|WebPlotRequest} imageRequest a request object used to display an image
* @param {number} fovDegFallOver the field of view size to determine when to move between a HiPS and an image
* @param {WebPlotParams|WebPlotRequest} allSkyRequest a request object used to display allsky image.
* @param {boolean} plotAllSkyFirst if plot allsky first
*
* @memberof firefly
* @public
* @example firefly.showImageOrHiPS('hipsDiv6',
* {
* plotId: 'aHipsID6',
* title : 'A HiPS - 0.2',
* hipsRootUrl: 'http://alasky.u-strasbg.fr/AllWISE/RGB-W4-W2-W1',
* SizeInDeg:.2
* },
* {
* Service: 'WISE',
* Title: 'Wise',
* SurveyKey: '3a',
* SurveyKeyBand: '2',
* WorldPt: '148.892;69.0654;EQ_J2000'
* }, 0.5
* );
*
*
*/
const showImageOrHiPS = (targetDiv, hipsRequest, imageRequest, fovDegFallOver, allSkyRequest, plotAllSkyFirst) =>
showImageOrHiPSInMultiViewer(llApi, targetDiv, hipsRequest, imageRequest,
fovDegFallOver, allSkyRequest, plotAllSkyFirst);
return {showImage, showHiPS, showImageOrHiPS, showImageFileOrUrl, setGlobalImageDef, showCoverage};
}
/**
* Build the deprecated API
* @param llApi
* @returns {Object}
* @deprecated
* @ignore
*/
function buildDeprecated(llApi) {
const dApi= {};
const {RequestType}= llApi.util.image;
dApi.makeImageViewer= (plotId) => {
llApi.util.debug('makeImageViewer is deprecated, use firefly.showImage() instead');
highlevelImageInit(llApi);
const plotSimple= makePlotSimple(llApi,plotId);
return {
defP: {},
setDefaultParams(params) {
this.defP= params;
},
plot(request) {
plotSimple(Object.assign({},this.defP, request));
},
plotFile(file) {
plotSimple(Object.assign({},this.defP,{'File' : file}));
},
plotURL(url) {
plotSimple(Object.assign({},this.defP,{'URL' : url}));
},
plotFileOrURL(file,url) {
plotSimple(Object.assign({},this.defP,
{'File' : file,
'URL' : url,
'Type' : RequestType.TRY_FILE_THEN_URL
}));
}
};
};
dApi.setGlobalDefaultParams= (params) => globalImageViewDefParams= params;
//!!!!!!! Add more Deprecated Api for table, histogram, xyplot here
return dApi;
}
//================================================================
//---------- Private Image functions
//================================================================
function makePlotSimple(llApi, plotId) {
return (request) => {
llApi.util.renderDOM(plotId, llApi.ui.ImageViewer, {plotId});
llApi.action.dispatchPlotImage({plotId, wpRequest:Object.assign({}, globalImageViewDefParams,request)});
};
}
function validatePlotRequest(llApi, targetDiv, request) {
const {findInvalidWPRKeys,confirmPlotRequest}= llApi.util.image;
const {debug, getWsConnId}= llApi.util;
const testR= Array.isArray(request) ? request : [request];
testR.forEach( (r) => {
const badList= findInvalidWPRKeys(r);
if (badList.length) debug(`plot request has the following bad keys: ${badList}`);
});
return confirmPlotRequest(request,globalImageViewDefParams,targetDiv,makePlotId(getWsConnId));
}
function getPlotIdFromRequest(request) {
if (Array.isArray(request)) {
const rWithPId = request.find((r) => r.plotId);
return rWithPId ? rWithPId.plotId : null;
} else {
return request.plotId;
}
}
function showImageOrHiPSInMultiViewer(llApi, targetDiv, hipsRequest, imageRequest,
fovDegFallOver, allSkyRequest, plotAllSkyFirst) {
const {dispatchPlotImageOrHiPS, dispatchAddViewer}= llApi.action;
const {IMAGE, NewPlotMode}= llApi.util.image;
const {MultiImageViewer, MultiViewStandardToolbar}= llApi.ui;
const {renderDOM}= llApi.util;
highlevelImageInit(llApi);
hipsRequest = validatePlotRequest(llApi, targetDiv, hipsRequest);
hipsRequest.Type = 'HiPS';
imageRequest = validatePlotRequest(llApi, targetDiv, imageRequest);
dispatchAddViewer(targetDiv, NewPlotMode.create_replace.key, IMAGE);
const plotId= getPlotIdFromRequest(hipsRequest) || getPlotIdFromRequest(imageRequest);
dispatchPlotImageOrHiPS({plotId, hipsRequest, viewerId: targetDiv,
imageRequest, allSkyRequest, plotAllSkyFirst, fovDegFallOver});
renderDOM(targetDiv, MultiImageViewer,
{viewerId:targetDiv, canReceiveNewPlots:NewPlotMode.create_replace.key, Toolbar:MultiViewStandardToolbar });
}
var firstShowImage= false;
var imageRenderType;
function showImageInMultiViewer(llApi, targetDiv, request, isHiPS, hipsImageConversion, userCanDelete=true) {
const {dispatchPlotImage, dispatchPlotHiPS, dispatchAddViewer, dispatchUpdateCustom}= llApi.action;
const {IMAGE, NewPlotMode}= llApi.util.image;
const {renderDOM}= llApi.util;
const {MultiImageViewer, ApiFullImageDisplay, MultiViewStandardToolbar}= llApi.ui;
request = validatePlotRequest(llApi, targetDiv, request);
const plotId= getPlotIdFromRequest(request);
const viewerId= targetDiv;
if (!firstShowImage) {
firstShowImage= true;
imageRenderType= globalPrefs.imageDisplayType;
if (imageRenderType===STANDARD) highlevelImageInit(llApi);
}
dispatchAddViewer(targetDiv, NewPlotMode.create_replace.key, IMAGE);
dispatchUpdateCustom(viewerId, {independentLayout: true});
if (isHiPS) {
request.Type= 'HiPS';
if (hipsImageConversion && !hipsImageConversion.hipsRequestRoot) {
hipsImageConversion.hipsRequestRoot= request;
}
dispatchPlotHiPS({plotId, wpRequest:request, viewerId,
hipsImageConversion, pvOptions: { userCanDeletePlots: userCanDelete}
});
}
else {
if (hipsImageConversion && !hipsImageConversion.imageRequestRoot) {
hipsImageConversion.imageRequestRoot= request;
}
dispatchPlotImage({plotId, wpRequest:request, viewerId,
hipsImageConversion, pvOptions: { userCanDeletePlots: userCanDelete}
});
}
if (imageRenderType===STANDARD) {
renderDOM(targetDiv, MultiImageViewer,
{viewerId, canReceiveNewPlots:NewPlotMode.create_replace.key, Toolbar:MultiViewStandardToolbar });
}
else {
renderDOM(targetDiv, ApiFullImageDisplay,
{viewerId, renderTreeId:viewerId, canReceiveNewPlots:NewPlotMode.create_replace.key, Toolbar:MultiViewStandardToolbar });
}
}
function initCoverage(llApi, targetDiv,options= {}) {
const {MultiImageViewer, MultiViewStandardToolbar}= llApi.ui;
const {renderDOM,debug}= llApi.util;
const {startCoverageWatcher,NewPlotMode}= llApi.util.image;
highlevelImageInit(llApi);
const {canReceiveNewPlots=NewPlotMode.replace_only.key}= options;
renderDOM(targetDiv, MultiImageViewer,
{viewerId:targetDiv, canReceiveNewPlots, canDelete:false, Toolbar:MultiViewStandardToolbar });
options= Object.assign({},options, {viewerId:targetDiv});
startCoverageWatcher(options);
}
var imageInit= false;
function highlevelImageInit(llApi) {
if (!imageInit) {
llApi.action.dispatchApiToolsView(true);
llApi.util.image.initAutoReadout();
imageInit= true;
}
}
var plotCnt= 0;
function makePlotId(wsConnIdGetter) {
return () => {
plotCnt++;
return `apiPlot-${wsConnIdGetter()}-${plotCnt}`;
};
}
//================================================================
//---------- Private Table functions
//================================================================
//================================================================
//---------- Private XYPlot or Histogram functions
//================================================================
function doShowChart(llApi, targetDiv, params={}) {
const {dispatchChartAdd}= llApi.action;
const {uniqueChartId} = llApi.util.chart;
const {renderDOM} = llApi.util;
const {ChartsContainer}= llApi.ui;
const tbl_group = params.tbl_group;
// when tbl_group parameter is set, show a default chart
// for an active table in this table group
if (!tbl_group) {
params = Object.assign({
chartId: uniqueChartId(`${targetDiv}`),
viewerId: targetDiv,
chartType: 'plot.ly'
}, params);
dispatchChartAdd(params);
}
renderDOM(targetDiv, ChartsContainer,
{
key: `${targetDiv}-plot`,
viewerId: targetDiv,
tbl_group,
addDefaultChart: Boolean(tbl_group),
closeable: false,
expandedMode: false,
noChartToolbar: params.noChartToolbar
}
);
}
function doShowXYPlot(llApi, targetDiv, params={}) {
const {dispatchTableFetch, dispatchChartAdd}= llApi.action;
const {renderDOM} = llApi.util;
const {makeFileRequest} = llApi.util.table;
const {ChartsContainer}= llApi.ui;
if ((typeof targetDiv).match(/string|HTMLDivElement/) === null) {
// old api.. need to change targetDiv and params
const oldApiParams = targetDiv;
targetDiv = params;
params = oldApiParams;
}
// it is not quite clear how to handle situation when there are multiple tables in a group
// for now we are connecting to the currently active table in the group
const tblGroup = params.QUERY_ID || params.tbl_group; // QUERY_ID is deprecated, should be removed at some point
var tblId = params.tbl_id;
// standalone plot, not connected to an existing table
if (!tblGroup && !tblId) {
const searchRequest = makeFileRequest(
params.chartTitle||'', // title
params.source, // source
null, // alt_source
{pageSize: 1} // options
);
tblId = searchRequest.tbl_id;
dispatchTableFetch(searchRequest);
params = Object.assign({}, params, {tbl_id: tblId});
}
const help_id = params.help_id;
const chartId = targetDiv;
dispatchChartAdd({chartId, chartType: 'scatter', help_id, deletable: false, viewerId: targetDiv, params});
renderDOM(targetDiv, ChartsContainer,
{
key: `${targetDiv}-xyplot`,
viewerId: targetDiv,
tbl_group: tblGroup,
addDefaultChart: Boolean(tblGroup),
closeable: false,
expandedMode: false
}
);
}
function doShowHistogram(llApi, targetDiv, params={}) {
const {dispatchTableFetch, dispatchChartAdd}= llApi.action;
const {renderDOM} = llApi.util;
const {makeFileRequest} = llApi.util.table;
const {ChartsContainer}= llApi.ui;
// it is not quite clear how to handle situation when there are multiple tables in a group
// for now we are connecting to the currently active table in the group
const tblGroup = params.tbl_group;
var tblId = params.tbl_id;
// standalone plot, not connected to an existing table
if (!tblGroup && !tblId) {
const searchRequest = makeFileRequest(
params.chartTitle||'', // title
params.source, // source
null, // alt_source
{pageSize: 1} // options
);
tblId = searchRequest.tbl_id;
dispatchTableFetch(searchRequest);
params = Object.assign({}, params, {tbl_id: tblId});
}
const help_id = params.help_id;
const chartId = targetDiv;
dispatchChartAdd({chartId, chartType: 'histogram', help_id, deletable: false, viewerId: targetDiv, params});
renderDOM(targetDiv, ChartsContainer,
{
key: `${targetDiv}-histogram`,
viewerId: targetDiv,
tbl_group: tblGroup,
addDefaultChart: Boolean(tblGroup),
closeable: false,
expandedMode: false
}
);
}