|
@@ -0,0 +1,312 @@
|
|
|
+
|
|
|
+function renderMessages(id, messages) {
|
|
|
+ if (messages && messages.length > 0) {
|
|
|
+ let errorDiv = document.createElement('div');
|
|
|
+ let style='padding: 10px; background-color: #ffe5e5;'
|
|
|
+ style+='color: #d83f48; font-weight: bold;';
|
|
|
+ errorDiv.setAttribute('style', style);
|
|
|
+ errorDiv.innerHTML = messages.join('<br/>');
|
|
|
+ document.getElementById(id).appendChild(errorDiv);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+function validateChartConfig(chartConfig, aes, scales, measureStore) {
|
|
|
+ let hasNoDataMsg = LABKEY.vis.GenericChartHelper.validateResponseHasData(measureStore, false);
|
|
|
+ if (hasNoDataMsg != null)
|
|
|
+ return {"success": false, "messages": [hasNoDataMsg]};
|
|
|
+
|
|
|
+ let measureNames = Object.keys(chartConfig.measures);
|
|
|
+ for (let i = 0; i < measureNames.length; i++) {
|
|
|
+ let measureProps = chartConfig.measures[measureNames[i]];
|
|
|
+ if (measureProps &&
|
|
|
+ measureProps.name &&
|
|
|
+ measureStore.records()[0][measureProps.name] == undefined){
|
|
|
+
|
|
|
+ let retVal=new Object();
|
|
|
+ retVal.success=false;
|
|
|
+ retVal.messages=['The measure, ' +
|
|
|
+ measureProps.label +
|
|
|
+ ', is not available. It may have been renamed or removed.']
|
|
|
+ return retVal;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ let messages = [];
|
|
|
+ let axisMeasureNames = ['x', 'xSub', 'y'];
|
|
|
+ for (let i = 0; i < axisMeasureNames.length; i++) {
|
|
|
+ if (measureNames.indexOf(axisMeasureNames[i]) > 0) {
|
|
|
+ let validation = LABKEY.vis.GenericChartHelper.validateAxisMeasure(
|
|
|
+ chartConfig.renderType, chartConfig, axisMeasureNames[i],
|
|
|
+ aes, scales, measureStore.records());
|
|
|
+ if (validation.message != null)
|
|
|
+ messages.push(validation.message);
|
|
|
+ if (!validation.success)
|
|
|
+ return {"success": false, "messages": messages};
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return {"success": true, "messages": messages};
|
|
|
+
|
|
|
+}
|
|
|
+function selectRowsCallback(renderConfig, measureStore) {
|
|
|
+ let responseMetaData = measureStore.getResponseMetadata();
|
|
|
+
|
|
|
+ // chartConfig is the saved information about the chart (labels, scales, etc.)
|
|
|
+
|
|
|
+ let chartConfig = new Object();
|
|
|
+ chartConfig.renderType="line_plot";
|
|
|
+
|
|
|
+ let mX=new Object();
|
|
|
+ mX.displayFieldJsonType="";
|
|
|
+ mX.hidden=false;
|
|
|
+ mX.fieldKey="percentile";
|
|
|
+ mX.label="Percentile";
|
|
|
+ mX.schemaName="study";
|
|
|
+ mX.type="float";
|
|
|
+ mX.normalizedType="float";
|
|
|
+ mX.measure=true;
|
|
|
+ mX.name="percentile";
|
|
|
+ mX.queryName="SUVQuantiles";
|
|
|
+ mX.alias="percentile";
|
|
|
+ mX.shortCaption="Percentile";
|
|
|
+ mX.dimension=false;
|
|
|
+
|
|
|
+ let mY=new Object();
|
|
|
+ mY.displayFieldJsonType="";
|
|
|
+ mY.hidden=false;
|
|
|
+ mY.fieldKey="value";
|
|
|
+ mY.label="Value";
|
|
|
+ mY.schemaName="study";
|
|
|
+ mY.type="float";
|
|
|
+ mY.normalizedType="float";
|
|
|
+ mY.measure=true;
|
|
|
+ mY.name="value";
|
|
|
+ mY.queryName="SUVQuantiles";
|
|
|
+ mY.alias="value";
|
|
|
+ mY.shortCaption="Value";
|
|
|
+ mY.dimension=false;
|
|
|
+
|
|
|
+
|
|
|
+ let mS=new Object();
|
|
|
+ mS.displayFieldJsonType="";
|
|
|
+ mS.hidden=false;
|
|
|
+ mS.fieldKey="ParticipantId";
|
|
|
+ mS.label="Participant ID";
|
|
|
+ mS.schemaName="study";
|
|
|
+ mS.type="string";
|
|
|
+ mS.normalizedType="string";
|
|
|
+ mS.measure=false;
|
|
|
+ mS.name="ParticipantId";
|
|
|
+ mS.queryName="SUVQuantiles";
|
|
|
+ mS.alias="ParticipantId";
|
|
|
+ mS.shortCaption="Participant ID";
|
|
|
+ mS.dimension=true;
|
|
|
+
|
|
|
+ chartConfig.measures=new Object();
|
|
|
+ chartConfig.measures.x=mX;
|
|
|
+ chartConfig.measures.y=mY;
|
|
|
+ chartConfig.measures.series=mS;
|
|
|
+ chartConfig.measures.pointClickFn=null;
|
|
|
+ chartConfig.scales=new Object();
|
|
|
+ chartConfig.scales.x=new Object();
|
|
|
+ chartConfig.scales.x.trans="linear";
|
|
|
+ chartConfig.scales.y=new Object();
|
|
|
+ chartConfig.scales.y.trans="linear";
|
|
|
+ chartConfig.labels=new Object();
|
|
|
+ chartConfig.labels.main="SUVQuantiles";
|
|
|
+ chartConfig.labels.subtitle="";
|
|
|
+ chartConfig.labels.x="Percentile";
|
|
|
+ chartConfig.labels.y="Value";
|
|
|
+ chartConfig.width=null;
|
|
|
+ chartConfig.height=null;
|
|
|
+ chartConfig.pointType="outliers";
|
|
|
+ chartConfig.geomOptions=new Object();
|
|
|
+ chartConfig.geomOptions.label="SUVQuantiles";
|
|
|
+ chartConfig.geomOptions.subtitle="";
|
|
|
+ chartConfig.geomOptions.width=null;
|
|
|
+ chartConfig.geomOptions.height=null;
|
|
|
+ chartConfig.geomOptions.pointType="outliers";
|
|
|
+ chartConfig.pointFillColor="3366FF";
|
|
|
+ chartConfig.lineWidth="3";
|
|
|
+ chartConfig.lineColor="000000";
|
|
|
+ chartConfig.boxFillColor="3366FF";
|
|
|
+ chartConfig.hideDataPoints=false;
|
|
|
+ chartConfig.colorPaletteScale="ColorDiscrete";
|
|
|
+ chartConfig.chartLayout="single";
|
|
|
+ chartConfig.chartSubjectSelection="subjects";
|
|
|
+ chartConfig.displayIndividual=true;
|
|
|
+ chartConfig.displayAggregate=false;
|
|
|
+ chartConfig.errorBars="None";
|
|
|
+ chartConfig.pieInnerRadius=0;
|
|
|
+ chartConfig.pieOuterRadius=80;
|
|
|
+ chartConfig.showPiePercentages=true;
|
|
|
+ chartConfig.pieHideWhenLessThanPercentage=5;
|
|
|
+ chartConfig.piePercentagesColor="333333";
|
|
|
+ chartConfig.gradientPercentage=95;
|
|
|
+ chartConfig.gradientColor="FFFFFF";
|
|
|
+ chartConfig.binThreshold=10000;
|
|
|
+ chartConfig.binShapeGroup="hex";
|
|
|
+ chartConfig.binColorGroup="BlueWhite";
|
|
|
+ chartConfig.binSingleColor="000000";
|
|
|
+ chartConfig.showOutliers=true;
|
|
|
+ chartConfig.binShape="hex";
|
|
|
+
|
|
|
+ if (!chartConfig.hasOwnProperty('width') ||
|
|
|
+ chartConfig.width == null)
|
|
|
+ chartConfig.width = 1000;
|
|
|
+ if (!chartConfig.hasOwnProperty('height') ||
|
|
|
+ chartConfig.height == null)
|
|
|
+ chartConfig.height = 600;
|
|
|
+ if (renderConfig.hasOwnProperty('width')){
|
|
|
+ chartConfig.width=renderConfig.width;
|
|
|
+ chartConfig.height=0.6*renderConfig.width;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ let xAxisType = chartConfig.measures.x ? (
|
|
|
+ chartConfig.measures.x.normalizedType ||
|
|
|
+ chartConfig.measures.x.type) : null;
|
|
|
+ let chartType = LABKEY.vis.GenericChartHelper.getChartType(
|
|
|
+ chartConfig.renderType, xAxisType);
|
|
|
+ let aes = LABKEY.vis.GenericChartHelper.generateAes(
|
|
|
+ chartType, chartConfig.measures,
|
|
|
+ responseMetaData.schemaName, responseMetaData.queryName);
|
|
|
+ let valueConversionResponse =
|
|
|
+ LABKEY.vis.GenericChartHelper.doValueConversion(
|
|
|
+ chartConfig, aes, chartType, measureStore.records());
|
|
|
+ if (!Ext4.Object.isEmpty(valueConversionResponse.processed)) {
|
|
|
+ Ext4.Object.merge(chartConfig.measures,
|
|
|
+ valueConversionResponse.processed);
|
|
|
+ aes = LABKEY.vis.GenericChartHelper.generateAes(
|
|
|
+ chartType, chartConfig.measures,
|
|
|
+ responseMetaData.schemaName, responseMetaData.queryName);
|
|
|
+ }
|
|
|
+ let data = measureStore.records();
|
|
|
+ if (chartType == 'scatter_plot' &&
|
|
|
+ data.length > chartConfig.geomOptions.binThreshold) {
|
|
|
+ chartConfig.geomOptions.binned = true;
|
|
|
+ }
|
|
|
+ let scales = LABKEY.vis.GenericChartHelper.generateScales(
|
|
|
+ chartType, chartConfig.measures, chartConfig.scales,
|
|
|
+ aes, measureStore);
|
|
|
+ let geom = LABKEY.vis.GenericChartHelper.generateGeom(
|
|
|
+ chartType, chartConfig.geomOptions);
|
|
|
+ let labels = LABKEY.vis.GenericChartHelper.generateLabels(
|
|
|
+ chartConfig.labels);
|
|
|
+
|
|
|
+ if (chartType == 'bar_chart' || chartType == 'pie_chart') {
|
|
|
+ let dimName = null, subDimName = null; measureName = null,
|
|
|
+ aggType = 'COUNT';
|
|
|
+
|
|
|
+ if (chartConfig.measures.x) {
|
|
|
+ dimName = chartConfig.measures.x.converted ?
|
|
|
+ chartConfig.measures.x.convertedName :
|
|
|
+ chartConfig.measures.x.name;
|
|
|
+ }
|
|
|
+ if (chartConfig.measures.xSub) {
|
|
|
+ subDimName = chartConfig.measures.xSub.converted ?
|
|
|
+ chartConfig.measures.xSub.convertedName :
|
|
|
+ chartConfig.measures.xSub.name;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (chartConfig.measures.y) {
|
|
|
+ measureName = chartConfig.measures.y.converted ?
|
|
|
+ chartConfig.measures.y.convertedName :
|
|
|
+ chartConfig.measures.y.name;
|
|
|
+
|
|
|
+ if (Ext4.isDefined(chartConfig.measures.y.aggregate)) {
|
|
|
+ aggType = chartConfig.measures.y.aggregate;
|
|
|
+ }
|
|
|
+ else if (measureName != null) {
|
|
|
+ aggType = 'SUM';
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ data = LABKEY.vis.getAggregateData(data, dimName, subDimName,
|
|
|
+ measureName, aggType, '[Blank]', false);
|
|
|
+ }
|
|
|
+
|
|
|
+ let plotConfig = LABKEY.vis.GenericChartHelper.generatePlotConfig(
|
|
|
+ renderConfig.chartId,chartConfig, labels, aes, scales, geom, data);
|
|
|
+
|
|
|
+ let validation = validateChartConfig(chartConfig, aes, scales, measureStore);
|
|
|
+ renderMessages(renderConfig.chartId, validation.messages);
|
|
|
+ if (!validation.success)
|
|
|
+ return;
|
|
|
+
|
|
|
+ let plot;
|
|
|
+ if (chartType == 'pie_chart') {
|
|
|
+ new LABKEY.vis.PieChart(plotConfig);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ plot = new LABKEY.vis.Plot(plotConfig);
|
|
|
+ plot.render();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+function dependencyCallback() {
|
|
|
+
|
|
|
+ let organs=["3","4","5"];
|
|
|
+
|
|
|
+ for (let i=0;i < organs.length; i++){
|
|
|
+
|
|
|
+ let renderConfig=new Object();
|
|
|
+ //all additional configuration stuff goes in here
|
|
|
+
|
|
|
+ renderConfig.chartId='SUV_organ'+organs[i];
|
|
|
+ renderConfig.width=500;
|
|
|
+ renderConfig.participantCode=document.getElementById("participantCode").innerHTML;
|
|
|
+ renderConfig.visitCode=document.getElementById("visitCode").innerHTML;
|
|
|
+
|
|
|
+ // When all the dependencies are loaded we then load the data via the MeasureStore selectRows API.
|
|
|
+ // The queryConfig object stores all the information needed to make a selectRows request
|
|
|
+
|
|
|
+ let queryConfig = new Object;
|
|
|
+ queryConfig.schemaName="study";
|
|
|
+ queryConfig.queryName="SUVQuantiles";
|
|
|
+ queryConfig.viewName=null;
|
|
|
+ queryConfig.dataRegionName="Dataset";
|
|
|
+ queryConfig.queryLabel="SUVQuantiles";
|
|
|
+ queryConfig.parameters= new Object();
|
|
|
+ queryConfig.requiredVersion=13.2;
|
|
|
+ queryConfig.maxRows=-1;
|
|
|
+ queryConfig.sort="lsid";
|
|
|
+ queryConfig.method="POST";
|
|
|
+ queryConfig.columns=["percentile","value","ParticipantId"];
|
|
|
+ queryConfig.filterArray=new Array();
|
|
|
+ queryConfig.filterArray.push({
|
|
|
+ "name":"patientCode",
|
|
|
+ "value":renderConfig.participantCode,
|
|
|
+ "type":"eq"});
|
|
|
+ queryConfig.filterArray.push({
|
|
|
+ "name":"visitCode",
|
|
|
+ "value":renderConfig.visitCode,
|
|
|
+ "type":"eq"});
|
|
|
+ queryConfig.filterArray.push({
|
|
|
+ "name":"organ",
|
|
|
+ "value":organs[i],
|
|
|
+ "type":"eq"});
|
|
|
+
|
|
|
+ if (queryConfig.filterArray &&
|
|
|
+ queryConfig.filterArray.length > 0) {
|
|
|
+ let filters = [];
|
|
|
+ for (let i = 0; i < queryConfig.filterArray.length; i++) {
|
|
|
+ let f = queryConfig.filterArray[i];
|
|
|
+ filters.push(LABKEY.Filter.create(
|
|
|
+ f.name, f.value,
|
|
|
+ LABKEY.Filter.getFilterTypeForURLSuffix(f.type)));
|
|
|
+ }
|
|
|
+ queryConfig.filterArray = filters;
|
|
|
+ }
|
|
|
+ queryConfig.success = function(data){
|
|
|
+ selectRowsCallback(renderConfig,data);};
|
|
|
+ queryConfig.containerPath = "/IPNUMMprospektiva/Study";
|
|
|
+ LABKEY.Query.MeasureStore.selectRows(queryConfig);
|
|
|
+ }
|
|
|
+};
|