
prerna.reactor.algorithms.CreateNLPVizReactor Maven / Gradle / Ivy
The newest version!
package prerna.reactor.algorithms;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.stream.Stream;
import org.apache.logging.log4j.Logger;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import prerna.ds.OwlTemporalEngineMeta;
import prerna.ds.r.RDataTable;
import prerna.masterdatabase.utility.MasterDatabaseUtility;
import prerna.reactor.frame.r.AbstractRFrameReactor;
import prerna.sablecc2.PixelRunner;
import prerna.sablecc2.om.GenRowStruct;
import prerna.sablecc2.om.ReactorKeysEnum;
import prerna.sablecc2.om.nounmeta.NounMetadata;
import prerna.util.DIHelper;
import prerna.util.Utility;
public class CreateNLPVizReactor extends AbstractRFrameReactor {
/**
* Reads in the Columns and Database IDs and returns the visualization string, which
* is then appended to the NLP search
*/
protected static final String SORT_PIXEL = "sortPixel";
protected static final String VIZ_SELECTION = "vizSelection";
protected static final String CLASS_NAME = CreateNLPVizReactor.class.getName();
public CreateNLPVizReactor() {
this.keysToGet = new String[] { ReactorKeysEnum.DATABASE.getKey(), ReactorKeysEnum.COLUMNS.getKey(), SORT_PIXEL,
ReactorKeysEnum.FRAME.getKey(), ReactorKeysEnum.PANEL.getKey(), VIZ_SELECTION };
}
@Override
public NounMetadata execute() {
init();
organizeKeys();
Logger logger = this.getLogger(CLASS_NAME);
String baseFolder = DIHelper.getInstance().getProperty("BaseFolder");
String databaseId = this.keyValue.get(this.keysToGet[0]);
String panelId = getPanelId();
List cols = getColumns();
String sortPixel = this.keyValue.get(this.keysToGet[2]);
String vizSelection = this.keyValue.get(this.keysToGet[5]);
RDataTable frame = (RDataTable) this.getFrame();
String frameName = frame.getName();
StringBuilder rsb = new StringBuilder();
Map aliasHash = new HashMap();
String fileroot = "dataitem";
OwlTemporalEngineMeta metadata = frame.getMetaData();
String databaseName = "Multiple";
if (!databaseId.contains("Multiple") && !databaseId.contains("null")) {
databaseName = MasterDatabaseUtility.getDatabaseAliasForId(databaseId).replace(" ", "_");
}
boolean allStrings = true;
// check if packages are installed
String[] packages = { "data.table", "plyr", "jsonlite" };
this.rJavaTranslator.checkPackages(packages);
// have pixel to paint as grid
String gridPixel = "Frame () | QueryAll ( ) | " + sortPixel + " AutoTaskOptions ( panel = [ \"" + panelId
+ "\" ] , layout = [ \"Grid\" ] ) | Collect ( 500 );";
// if user wants 'Grid' then visualize as grid
if (vizSelection.equals("Grid")) {
PixelRunner runner = this.insight.runPixel(gridPixel);
return runner.getResults().get(0);
}
// sort the columns list in ascending order of unique inst
// put the aggregate columns last
Collections.sort(cols, new Comparator() {
public int compare(String firstCol, String secondCol) {
if (isAggregate(firstCol)) {
return 1;
} else {
return frame.getUniqueInstanceCount(firstCol) - frame.getUniqueInstanceCount(secondCol);
}
}
});
// let's first create the input frame
String inputFrame = "inputFrame" + Utility.getRandomString(5);
rsb.append(inputFrame
+ " <- data.frame(reference1 = character(), reference2 = character(), reference3 = integer(), stringsAsFactors = FALSE);");
int rowCounter = 1;
for (String col : cols) {
String tableName = null;
String colName = null;
// lets get the table name, column name, and type (if possible)
if (col.contains("__")) {
// this both a table and a column
String[] parsedCol = col.split("__");
tableName = parsedCol[0];
colName = parsedCol[1];
} else {
// this is a table and column (primary key)
// or an aggregate
tableName = frameName;
colName = col;
}
// get datatype
String dataType = metadata.getHeaderTypeAsString(tableName + "__" + colName);
// If it is an int or double, convert to NUMBER
if (dataType.equalsIgnoreCase("INT") || dataType.equalsIgnoreCase("DOUBLE")) {
dataType = "NUMBER";
}
// catch the date functions and flip it to string if so
String[] dates = { "DAYNAME", "MONTHNAME", "WEEK", "QUARTER", "YEAR" };
if(Stream.of(dates).anyMatch(colName.toUpperCase()::startsWith)) {
dataType = "STRING";
}
// check to make sure at least one column is not a string
if (!dataType.equalsIgnoreCase("STRING")) {
allStrings = false;
}
// get unique column values -- if it is an aggregate, then make it 30
int uniqueValues = 0;
if (isAggregate(col)) {
uniqueValues = 30;
} else {
uniqueValues = frame.getUniqueInstanceCount(colName);
}
rsb.append(inputFrame + "[" + rowCounter + ",] <- c(\"" + databaseId + "$" + databaseName + "$" + tableName + "$"
+ colName + "\",");
rsb.append("\"" + dataType + "\",");
rsb.append(uniqueValues + ");");
// add column alias hash so we can look up alias later
aliasHash.put(colName + "_" + tableName + "_" + databaseId, col.toString());
rowCounter++;
}
// if user wants 'Recommended' then call function to use usual flow
// otherwise, use new flow
// now let's look for the shared history vs personal history
File userHistory = new File(baseFolder + DIR_SEPARATOR + "R" + DIR_SEPARATOR + "Recommendations"
+ DIR_SEPARATOR + "dataitem-user-history.rds");
if (!userHistory.exists()) {
// user history does not exist, let's use shared history
fileroot = "shared";
logger.info("Selecting proper visualization for insight");
}
// now lets run the script and return a json
String json = "";
String outputJson = "outputJson" + Utility.getRandomString(5);
String recommend = "recommend" + Utility.getRandomString(5);
String wd = "wd" + Utility.getRandomString(5);
rsb.append(wd + " <- getwd();");
rsb.append("setwd(\"" + baseFolder.replace("\\", "/") + "/R/Recommendations/\");");
rsb.append("source(\"viz_recom.r\");");
// change int/double to number in the history
rsb.append("sync_numeric(\"" + fileroot + "\",\"" + fileroot + "\");");
if (vizSelection.equals("Recommended")) {
// if it only has one column or one row, just return it as a grid
if (cols.size() < 2 || frame.getNumRows(frameName) < 2 || allStrings) {
PixelRunner runner = this.insight.runPixel(gridPixel);
return runner.getResults().get(0);
}
// run function and create json
rsb.append(recommend + "<-viz_recom_mgr(\"" + fileroot + "\", " + inputFrame + ", \"Grid\", 1);");
rsb.append("library(jsonlite);");
rsb.append(outputJson + " <-toJSON(" + recommend + ", byrow = TRUE, colNames = TRUE);");
rsb.append("setwd(" + wd + ");");
this.rJavaTranslator.runR(rsb.toString());
// receive json string from R
json = this.rJavaTranslator.getString(outputJson + ";");
} else {
rsb.append("source(\"viz_selection.r\");");
// run function and create json
rsb.append(recommend + " <- get_viz_choices(\"" + fileroot + "\"," + inputFrame + ",\"" + vizSelection + "\");");
rsb.append("library(jsonlite);");
rsb.append(outputJson + " <-toJSON(" + recommend + ", byrow = TRUE, colNames = TRUE);");
rsb.append("setwd(" + wd + ");");
this.rJavaTranslator.runR(rsb.toString());
// receive json string from R
json = this.rJavaTranslator.getString(outputJson + ";");
}
Map recommendations = new HashMap>();
// if no recommendation was found, lets just return it in a grid
if (json == null || json.equals("[]")) {
PixelRunner runner = this.insight.runPixel(gridPixel);
return runner.getResults().get(0);
}
// converting physical column names to frame aliases
Gson gson = new Gson();
ArrayList
© 2015 - 2025 Weber Informatics LLC | Privacy Policy