Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@ public class HistogramProcessor extends IpacTablePartProcessor {
new DataType("binMin", Double.class),
new DataType("binMax", Double.class)
};
static {
// set default precision to 9 significant digits
DataType.FormatInfo fi = DataType.FormatInfo.createDefaultFormat(Double.class);
fi.setDataFormat("%.9g");
columns[1].setFormatInfo(fi);
columns[2].setFormatInfo(fi);
}
private final String FIXED_SIZE_ALGORITHM = "fixedSizeBins";
private final String NUMBER_BINS = "numBins";
private final String COLUMN = "columnExpression";
Expand Down Expand Up @@ -91,9 +98,11 @@ protected File loadDataFile(TableServerRequest request) throws IOException, Data
getParameters(request);
DataGroup sourceDataGroup = DataGroupReader.readAnyFormat(new File(fi.getInternalFilename()));
double[] columnData = getColumnData(sourceDataGroup);
DataGroup HistogramDataGroup = createHistogramTable(columnData);
DataGroup histogramDataGroup = createHistogramTable(columnData);
histogramDataGroup.addAttribute("column", columnExpression);
histogramDataGroup.addAttribute("searchRequest", sReq.toString());
File histogramFile = createFile(request);
DataGroupWriter.write(histogramFile, HistogramDataGroup, 0);
DataGroupWriter.write(histogramFile, histogramDataGroup, 0);
return histogramFile;
}

Expand Down Expand Up @@ -152,22 +161,6 @@ public DataGroup createHistogramTable(double[] columnData) throws DataAccessExce
double[] binMax = (double[]) obj[2];
int nPoints = numPointsInBin.length;

if (nPoints > 1) {
double firstBinRange = binMax[0] - binMin[0];
int firstSigDigitPos = (int) Math.floor(Math.log10(Math.abs(firstBinRange))) + 1;
if (firstSigDigitPos < -2) {
// increase precision
DataType.FormatInfo fi = DataType.FormatInfo.createFloatFormat(20, 3 - firstSigDigitPos);
tblcolumns = new DataType[]{
new DataType("numInBin", Integer.class),
new DataType("binMin", Double.class),
new DataType("binMax", Double.class)
};
tblcolumns[1].setFormatInfo(fi);
tblcolumns[2].setFormatInfo(fi);
}
}

//add each row to the DataGroup
HistogramTable = new DataGroup("histogramTable", tblcolumns);
for (int i = 0; i < nPoints; i++) {
Expand Down Expand Up @@ -277,63 +270,6 @@ private boolean isInSelection( int idx, ArrayList<Integer> list){
return false;
}


/**
* This method checks all the DataType contained in the input DataGroup to see if the required ColumnName is
* in it. If a DataType's columnName is the same as the input columnName, the corresponding DataType is found and
* is returned.
*
* @param dg
* @return
*/
private DataType[] getColumn(DataGroup dg) {
DataType[] inColumns = dg.getDataDefinitions();
ArrayList<DataType> colDataTypeList = new ArrayList<DataType>();
for (int i = 0; i < inColumns.length; i++) {
if (columnExpression.contains(inColumns[i].getKeyName())) {
colDataTypeList.add(inColumns[i]);
}

}
return colDataTypeList.toArray(new DataType[0]);
}

/**
* This method convert the numerical data of Object type to the type of Double, return a primitive double value.
*
* @param data
* @param numericColumn
* @return
*/
private double convertToADoubleValue(Object data, DataType numericColumn) {
Class type = numericColumn.getDataType();

if (type == Double.class) {

Double doubleData = (Double) data;

return doubleData.doubleValue();
} else if (type == Float.class) {
Float floatData = (Float) data;
return floatData.doubleValue();
} else if (type == Integer.class) {
Integer integerData = (Integer) data;
return integerData.doubleValue();

} else if (type == Short.class) {
Short shortData = (Short) data;
return shortData.doubleValue();
} else if (type == Long.class) {
Long longData = (Long) data;
return longData.doubleValue();

} else if (type == Byte.class) {
Byte byteData = (Byte) data;
return byteData.doubleValue();
}
return Double.NaN;
}

private double[] getColumnData(DataGroup dg) {
List<DataObject> objList = dg.values();
int nRow = objList.size();
Expand All @@ -345,8 +281,7 @@ private double[] getColumnData(DataGroup dg) {
DataObject row = objList.get(i);
data[i] = dGetter.getValue(row);
}

return data;
return Arrays.stream(data).filter(d -> !Double.isNaN(d)).toArray();
}

private static String[] getInputFilePath(String inputFileName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ protected File loadDataFile(TableServerRequest request) throws IOException, Data
}
DataGroup sourceDataGroup = DataGroupReader.readAnyFormat(new File(fi.getInternalFilename()));
DataGroup statisticsDataGroup = createTableStatistic(sourceDataGroup);
statisticsDataGroup.addAttribute("searchRequest", sReq.toString());
File statisticsFile = createFile(request);
DataGroupWriter.write(statisticsFile, statisticsDataGroup, 0);
return statisticsFile;
Expand All @@ -102,9 +103,12 @@ public static DataGroup createTableStatistic(DataGroup inDataGroup){
DataType[] inColumns =inDataGroup.getDataDefinitions();
DataType[] numericColumns = getNumericColumns(inColumns);

String[] columnNames = getDataTypeField(numericColumns, "name");
String[] columnDescription = getDataTypeField(numericColumns, "description");
String[] unit = getDataTypeField(numericColumns, "unit");
String[] columnNames = new String[numericColumns.length];
String[] unit = new String[numericColumns.length];
for (int i=0; i<numericColumns.length; i++){
columnNames[i]=numericColumns[i].getKeyName();
unit[i]=numericColumns[i].getDataUnit();
}

Object[] retArrays = getDataArrays (dgjList,numericColumns );
double[] minArray = (double[]) retArrays[0];
Expand All @@ -114,14 +118,16 @@ public static DataGroup createTableStatistic(DataGroup inDataGroup){
for (int i=0; i<minArray.length; i++){
DataObject row = new DataObject(statisticsTable);
row.setDataElement(columns[0], columnNames[i]);
row.setDataElement(columns[1], columnDescription[i]);
row.setDataElement(columns[1], ""); // description not available
row.setDataElement(columns[2], unit[i]);
row.setDataElement(columns[3], minArray[i]);
row.setDataElement(columns[4], maxArray[i]);
row.setDataElement(columns[5], numPointsArray [i]);
statisticsTable.add(row);
}

// adjust the width of all columns to fit the data
statisticsTable.shrinkToFitData(true);
return statisticsTable;
}
/**
Expand Down
2 changes: 1 addition & 1 deletion src/firefly/js/api/ApiUtilChart.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,5 @@ import * as XYPlotCntlr from '../charts/XYPlotCntlr.js';
export {uniqueChartId} from '../charts/ChartUtil.js';

export function loadPlotDataForTbl(tblId, chartId, xyPlotParams) {
XYPlotCntlr.dispatchLoadPlotData(chartId, xyPlotParams, tblId);
XYPlotCntlr.dispatchLoadPlotData({chartId, xyPlotParams, markAsDefault:true, tblId});
}
21 changes: 13 additions & 8 deletions src/firefly/js/charts/HistogramCntlr.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
*/
import {flux} from '../Firefly.js';

import {get, has, omit} from 'lodash';
import {cloneDeep, get, has, omit} from 'lodash';

import {updateSet, updateMerge} from '../util/WebUtil.js';
import {doFetchTable, getTblById, isFullyLoaded, makeTblRequest, cloneRequest} from '../tables/TableUtil.js';
Expand Down Expand Up @@ -42,12 +42,16 @@ export const UPDATE_COL_DATA = `${HISTOGRAM_DATA_KEY}/UPDATE_COL_DATA`;

/*
* Get column histogram data
* @param {Object} histogramParams - histogram options (column name, etc.)
* @param {string} tblId - table id
* @param {function} dispatcher only for special dispatching uses such as remote
* @param {Object} params - dispatch parameters
* @param {string} params.chartId - if no chart id is specified table id is used as chart id
* @param {Object} params.histogramParams - histogram options (column name, etc.)
* @param {boolean} params.markAsDefault - are the options considered to be "the default" to reset to
* @param {string} params.tblId - table id
* @param {function} params.dispatcher only for special dispatching uses such as remote
*/
export const dispatchLoadColData = function(chartId, histogramParams, tblId, dispatcher= flux.process) {
dispatcher({type: LOAD_COL_DATA, payload: {chartId, histogramParams, tblId}});
export const dispatchLoadColData = function(params) {
const {chartId, histogramParams, markAsDefault=false, tblId, dispatcher= flux.process} = params;
dispatcher({type: LOAD_COL_DATA, payload: {chartId: (chartId||tblId), histogramParams, markAsDefault, tblId}});
};

/*
Expand Down Expand Up @@ -135,9 +139,10 @@ export function reduceHistogram(state={}, action={}) {
}
case (LOAD_COL_DATA) :
{
const {chartId, tblId, histogramParams, tblSource, serverCallNeeded} = action.payload;
const {chartId, tblId, histogramParams, markAsDefault, tblSource, serverCallNeeded} = action.payload;
if (serverCallNeeded) {
return updateSet(state, chartId, {tblId, isColDataReady: false, tblSource, histogramParams});
const defaultParams = markAsDefault ? cloneDeep(histogramParams) : get(state, [chartId, 'defaultParams']);
return updateSet(state, chartId, {tblId, isColDataReady: false, tblSource, histogramParams, defaultParams});
} else {
// only histogram parameters changed
return updateSet(state, [chartId, 'histogramParams'], histogramParams);
Expand Down
29 changes: 17 additions & 12 deletions src/firefly/js/charts/XYPlotCntlr.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import {flux} from '../Firefly.js';

import {updateSet, updateMerge, updateDelete} from '../util/WebUtil.js';
import {get, has, omit, omitBy, isEmpty, isUndefined, isString} from 'lodash';
import {cloneDeep, get, has, omit, omitBy, isEmpty, isString, isUndefined} from 'lodash';

import {doFetchTable, getColumn, getTblById, isFullyLoaded, cloneRequest} from '../tables/TableUtil.js';
import * as TablesCntlr from '../tables/TablesCntlr.js';
Expand Down Expand Up @@ -66,13 +66,16 @@ const RESET_ZOOM = `${XYPLOT_DATA_KEY}/RESET_ZOOM`;

/*
* Load xy plot data
* @param {string} chartId - if no chart id is specified table id is used as chart id
* @param {Object} xyPlotParams - XY plot options (column names, etc.)
* @param {string} tblId - table id
* @param {function} dispatcher only for special dispatching uses such as remote
* @param {Object} params - dispatch parameters
* @param {string} params.chartId - if no chart id is specified table id is used as chart id
* @param {Object} params.xyPlotParams - XY plot options (column names, etc.)
* @param {boolean} params.markAsDefault - are the options considered to be "the default" to reset to
* @param {string} params.tblId - table id
* @param {function} params.dispatcher only for special dispatching uses such as remote
*/
export function dispatchLoadPlotData(chartId, xyPlotParams, tblId, dispatcher= flux.process) {
dispatcher({type: LOAD_PLOT_DATA, payload: {chartId: (chartId||tblId), xyPlotParams, tblId}});
export function dispatchLoadPlotData(params) {
const {chartId, xyPlotParams, markAsDefault=false, tblId, dispatcher=flux.process} = params;
dispatcher({type: LOAD_PLOT_DATA, payload: {chartId: (chartId||tblId), xyPlotParams, markAsDefault, tblId}});
}

/*
Expand All @@ -99,7 +102,7 @@ export function dispatchZoom(chartId, tblId, selection) {
const tableModel = getTblById(tblId);
if (tableModel) {
const paramsWithZoom = Object.assign({}, xyPlotParams, {zoom: xyPlotParams.selection});
dispatchLoadPlotData(chartId, paramsWithZoom, tblId);
dispatchLoadPlotData({chartId, xyPlotParams: paramsWithZoom, tblId});
}
} else {
dispatchSetZoom(chartId, selection);
Expand All @@ -110,7 +113,7 @@ export function dispatchZoom(chartId, tblId, selection) {
const tableModel = getTblById(tblId);
if (tableModel) {
const paramsWithoutZoom = omit(xyPlotParams, 'zoom');
dispatchLoadPlotData(chartId, paramsWithoutZoom, tblId);
dispatchLoadPlotData({chartId, xyPlotParams: paramsWithoutZoom, tblId});
}
} else {
dispatchResetZoom(chartId);
Expand All @@ -136,7 +139,7 @@ function dispatchResetZoom(chartId) {
export function loadPlotData (rawAction) {
return (dispatch) => {
let xyPlotParams = rawAction.payload.xyPlotParams;
const {chartId, tblId} = rawAction.payload;
const {chartId, tblId, markAsDefault} = rawAction.payload;
const tblSource = get(getTblById(tblId), 'tableMeta.tblFilePath');

const chartModel = get(getChartSpace(SCATTER), chartId);
Expand All @@ -153,7 +156,7 @@ export function loadPlotData (rawAction) {
xyPlotParams = getUpdatedParams(xyPlotParams, tableModel, dataBoundaries);
}

dispatch({ type : LOAD_PLOT_DATA, payload : {chartId, tblId, xyPlotParams, tblSource, serverCallNeeded}});
dispatch({ type : LOAD_PLOT_DATA, payload : {chartId, tblId, xyPlotParams, markAsDefault, tblSource, serverCallNeeded}});

if (serverCallNeeded) {
fetchPlotData(dispatch, tblId, xyPlotParams, chartId);
Expand Down Expand Up @@ -225,14 +228,16 @@ export function reduceXYPlot(state={}, action={}) {
}
case (LOAD_PLOT_DATA) :
{
const {chartId, xyPlotParams, tblId, tblSource, serverCallNeeded} = action.payload;
const {chartId, xyPlotParams, markAsDefault, tblId, tblSource, serverCallNeeded} = action.payload;
if (serverCallNeeded) {
const defaultParams = markAsDefault ? cloneDeep(xyPlotParams) : get(state, [chartId, 'defaultParams']);
return updateSet(state, chartId,
{
tblId,
isPlotDataReady: false,
tblSource,
xyPlotParams,
defaultParams,
decimatedUnzoomed: get(state, [chartId, 'decimatedUnzoomed'])
});
} else {
Expand Down
6 changes: 4 additions & 2 deletions src/firefly/js/charts/ui/ChartsTableViewPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -608,16 +608,18 @@ export class OptionsWrapper extends React.Component {
options = (<XYPlotOptions key={formName} groupKey={formName}
colValStats={tblStatsData.colStats}
xyPlotParams={get(tblPlotData, 'xyPlotParams')}
defaultParams={get(tblPlotData, 'defaultParams')}
onOptionsSelected={(xyPlotParams) => {
XYPlotCntlr.dispatchLoadPlotData(chartId, xyPlotParams, tableModel.tbl_id);
XYPlotCntlr.dispatchLoadPlotData({chartId, xyPlotParams, tblId: tableModel.tbl_id});
}
}/>);
} else {
options = (<HistogramOptions key={formName} groupKey={formName}
colValStats={tblStatsData.colStats}
histogramParams={get(tblHistogramData, 'histogramParams')}
defaultParams={get(tblHistogramData, 'defaultParams')}
onOptionsSelected={(histogramParams) => {
HistogramCntlr.dispatchLoadColData(chartId, histogramParams, tableModel.tbl_id);
HistogramCntlr.dispatchLoadColData({chartId, histogramParams, tblId: tableModel.tbl_id});
}
}/>);
}
Expand Down
7 changes: 4 additions & 3 deletions src/firefly/js/charts/ui/HistogramOptions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ export class HistogramOptions extends React.Component {
}

render() {
const { colValStats, groupKey, histogramParams, onOptionsSelected}= this.props;
const { colValStats, groupKey, histogramParams, defaultParams, onOptionsSelected}= this.props;
return (
<div style={{padding:'0 5px'}}>
<FieldGroup groupKey={groupKey} validatorFunc={null} keepState={true}>
Expand All @@ -137,7 +137,7 @@ export class HistogramOptions extends React.Component {
<div style={{flexGrow: 1}}/>
<div style={{flexGrow: 0}}>
<button type='button' className='button std' onClick={() => setOptions(groupKey, {})}>Clear</button>
<button type='button' className='button std' onClick={() => setOptions(groupKey, histogramParams)}>Reset</button>
<button type='button' className='button std' onClick={() => setOptions(groupKey, defaultParams)}>Reset</button>
</div>
</div>}

Expand Down Expand Up @@ -220,5 +220,6 @@ HistogramOptions.propTypes = {
groupKey: PropTypes.string.isRequired,
colValStats: PropTypes.arrayOf(PropTypes.instanceOf(ColValuesStatistics)).isRequired,
onOptionsSelected: PropTypes.func,
histogramParams: histogramParamsShape
histogramParams: histogramParamsShape,
defaultParams: histogramParamsShape
};
7 changes: 4 additions & 3 deletions src/firefly/js/charts/ui/XYPlotOptions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,7 @@ export class XYPlotOptions extends React.Component {
}

render() {
const { colValStats, groupKey, xyPlotParams, onOptionsSelected}= this.props;
const { colValStats, groupKey, xyPlotParams, defaultParams, onOptionsSelected}= this.props;

// 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;});
Expand Down Expand Up @@ -471,7 +471,7 @@ export class XYPlotOptions extends React.Component {
<div style={{flexGrow: 1}}/>
<div style={{flexGrow: 0}}>
<button type='button' className='button std' onClick={() => setOptions(groupKey, {})}>Clear</button>
<button type='button' className='button std' onClick={() => setOptions(groupKey, xyPlotParams)}>Reset</button>
<button type='button' className='button std' onClick={() => setOptions(groupKey, defaultParams)}>Reset</button>
</div>
</div>}

Expand Down Expand Up @@ -622,5 +622,6 @@ XYPlotOptions.propTypes = {
groupKey: PropTypes.string.isRequired,
colValStats: PropTypes.arrayOf(PropTypes.instanceOf(ColValuesStatistics)).isRequired,
onOptionsSelected: PropTypes.func,
xyPlotParams: plotParamsShape
xyPlotParams: plotParamsShape,
defaultParams: plotParamsShape
};
Loading