diff --git a/.gitignore b/.gitignore
index e016ea6..3a1a973 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
node_modules
+node_modules/*
.tmp
dist
.api
@@ -7,7 +8,6 @@ dist
.tmp/*
dist/*
.tmp/drop/pbiviz.json
-.tmp/drop/pbiviz.json
.tmp/drop/visual.js
.tmp/precompile/src/visual.ts
.tmp/drop/pbiviz.json
@@ -25,4 +25,8 @@ dist/PowerBI-visuals-forcasting-exp.pbiviz
out.html.tmp
out.html.*
out.html_files/*
-out.html_files
\ No newline at end of file
+out.html_files
+dist/PowerBI-visuals-forcasting-exp.pbiviz
+assets/Presentation1.pptx
+assets/*_testing.pbix
+dist/PowerBI-visuals-forcasting-exp.pbiviz
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..d4e749d
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,13 @@
+{
+ "version": "0.1.0",
+ "configurations": [
+ {
+ "name": "Debugger",
+ "type": "chrome",
+ "request": "attach",
+ "port": 9222,
+ "sourceMaps": true,
+ "webRoot": "${cwd}/"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..040bf4b
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,37 @@
+{
+ "editor.tabSize": 4,
+ "editor.insertSpaces": true,
+ "files.eol": "\n",
+ "files.watcherExclude": {
+ "**/.git/objects/**": true,
+ "**/node_modules/**": true,
+ ".tmp": true
+ },
+ "files.exclude": {
+ ".tmp": true
+ },
+ "search.exclude": {
+ ".tmp": true,
+ "typings": true
+ },
+ "json.schemas": [
+ {
+ "fileMatch": [
+ "/pbiviz.json"
+ ],
+ "url": "./.api/v1.10.0/schema.pbiviz.json"
+ },
+ {
+ "fileMatch": [
+ "/capabilities.json"
+ ],
+ "url": "./.api/v1.10.0/schema.capabilities.json"
+ },
+ {
+ "fileMatch": [
+ "/dependencies.json"
+ ],
+ "url": "./.api/v1.10.0/schema.dependencies.json"
+ }
+ ]
+}
diff --git a/assets/CaptureSettings.PNG b/assets/CaptureSettings.PNG
new file mode 100644
index 0000000..7d6173d
Binary files /dev/null and b/assets/CaptureSettings.PNG differ
diff --git a/assets/forecast_custom_RV_HTML-based.pbix b/assets/forecast_custom_RV_HTML-based.pbix
index 2ee69c5..5f10a9d 100644
Binary files a/assets/forecast_custom_RV_HTML-based.pbix and b/assets/forecast_custom_RV_HTML-based.pbix differ
diff --git a/capabilities.json b/capabilities.json
index d1745fc..c985805 100644
--- a/capabilities.json
+++ b/capabilities.json
@@ -62,7 +62,7 @@
},
"settings_forecastPlot_params": {
"displayName": "Forecasting settings",
- "description": "Basic decomposition models are: 1. Additive: x[t] = Trend + Seasonal + Random, 2. Multiplicative: x[t] = Trend * Seasonal * Random. Hybrid models are allowed. Any forbiden model combination will be replaced by `Automatic`",
+ "description": "Basic decomposition models are: 1. Additive: x[t] = Trend + Seasonal + Remainder, 2. Multiplicative: x[t] = Trend * Seasonal * Remainder. Hybrid models are allowed. Any forbiden model combination will be replaced by `Automatic`",
"properties": {
"forecastLength": {
@@ -72,7 +72,7 @@
},
"errorType": {
- "displayName": "Error component",
+ "displayName": "Remainder component",
"type": {
"enumeration": [
{
@@ -201,34 +201,125 @@
"show": {
"type": {"bool": true}
},
- "percentile": { "displayName": "Confidence", "type": { "numeric": true } },
- "upperConfIntervalFactor": {
- "displayName": "Upper interval factor",
- "description": "Upper Confidence = Confidence + (100 - Confidence)*UpperIntervalFactor ",
- "type": {
- "enumeration": [
- {
- "displayName": "0",
- "value": "0"
- },
- {
- "displayName": "0.5",
- "value": "0.5"
- },
- {
- "displayName": "0.75",
- "value": "0.75"
- },
- {
- "displayName": "0.9",
- "value": "0.9"
- },
- {
- "displayName": "0.95",
- "value": "0.95"
- }
- ]
- }
+ "confInterval1": {
+ "displayName": "Confidence level",
+ "description": "Select first confidence interval",
+ "type": {
+ "enumeration": [
+ {
+ "displayName": "0",
+ "value": "0"
+ },
+ {
+ "displayName": "0.2",
+ "value": "0.2"
+ },
+ {
+ "displayName": "0.4",
+ "value": "0.4"
+ },
+ {
+ "displayName": "0.5",
+ "value": "0.5"
+ },
+ {
+ "displayName": "0.75",
+ "value": "0.75"
+ },
+ {
+ "displayName": "0.8",
+ "value": "0.8"
+ },
+ {
+ "displayName": "0.9",
+ "value": "0.9"
+ },
+ {
+ "displayName": "0.95",
+ "value": "0.95"
+ },
+ {
+ "displayName": "0.975",
+ "value": "0.975"
+ },
+ {
+ "displayName": "0.98",
+ "value": "0.98"
+ },
+ {
+ "displayName": "0.99",
+ "value": "0.99"
+ },
+ {
+ "displayName": "0.995",
+ "value": "0.995"
+ },
+ {
+ "displayName": "0.999",
+ "value": "0.999"
+ }
+ ]
+ }
+ },
+ "confInterval2": {
+ "displayName": "Confidence level #2",
+ "description": "Select additional confidence interval",
+ "type": {
+ "enumeration": [
+ {
+ "displayName": "0",
+ "value": "0"
+ },
+ {
+ "displayName": "0.2",
+ "value": "0.2"
+ },
+ {
+ "displayName": "0.4",
+ "value": "0.4"
+ },
+ {
+ "displayName": "0.5",
+ "value": "0.5"
+ },
+ {
+ "displayName": "0.75",
+ "value": "0.75"
+ },
+ {
+ "displayName": "0.8",
+ "value": "0.8"
+ },
+ {
+ "displayName": "0.9",
+ "value": "0.9"
+ },
+ {
+ "displayName": "0.95",
+ "value": "0.95"
+ },
+ {
+ "displayName": "0.975",
+ "value": "0.975"
+ },
+ {
+ "displayName": "0.98",
+ "value": "0.98"
+ },
+ {
+ "displayName": "0.99",
+ "value": "0.99"
+ },
+ {
+ "displayName": "0.995",
+ "value": "0.995"
+ },
+ {
+ "displayName": "0.999",
+ "value": "0.999"
+ }
+ ]
+ }
}
}
},
@@ -276,10 +367,56 @@
}
}
}
+ },
+ "settings_export_params": {
+ "displayName": "Export data",
+ "description": "Export result of clustering",
+ "properties": {
+ "show": {
+ "type": {
+ "bool": true
+ }
+ },
+ "limitExportSize": {
+ "displayName": "Maximum exported rows",
+ "description": "Limit number of rows",
+ "type": {
+ "enumeration": [{
+ "displayName": "1000",
+ "value": "1000"
+ },
+ {
+ "displayName": "10000",
+ "value": "10000"
+ },
+ {
+ "displayName": "50000",
+ "value": "50000"
+ },
+ {
+ "displayName": "unlimited",
+ "value": "100000"
+ }
+ ]
+ }
+ },
+ "method": {
+ "displayName": "Method",
+ "description": "Method",
+ "type": {
+ "enumeration": [{
+ "displayName": "copy to clipboard",
+ "value": "copy"
+ },
+ {
+ "displayName": "download (only service)",
+ "value": "download"
+ }
+ ]
+ }
+ }
+ }
}
-
-
-
},
"suppressDefaultTitle": true
}
\ No newline at end of file
diff --git a/dependencies.json b/dependencies.json
index e710848..70a90ee 100644
--- a/dependencies.json
+++ b/dependencies.json
@@ -39,6 +39,11 @@
"name": "XML",
"displayName": "XML",
"url": "https://cran.r-project.org/web/packages/XML/index.html"
+ },
+ {
+ "name": "caTools",
+ "displayName": "caTools",
+ "url": "https://cran.r-project.org/web/packages/caTools/index.html"
}
]
diff --git a/dist/PowerBI-visuals-forcasting-exp.pbiviz b/dist/PowerBI-visuals-forcasting-exp.pbiviz
index b4f8a01..7a45bf7 100644
Binary files a/dist/PowerBI-visuals-forcasting-exp.pbiviz and b/dist/PowerBI-visuals-forcasting-exp.pbiviz differ
diff --git a/package.json b/package.json
index 128fe46..9ddc23c 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
{
"name": "visual",
"scripts": {
- "postinstall": "pbiviz update 1.7.0",
+ "postinstall": "pbiviz update 1.10.0",
"pbiviz": "pbiviz",
"package": "pbiviz package",
"lint": "tslint -r \"node_modules/tslint-microsoft-contrib\" \"+(src)/**/*.ts\"",
@@ -10,6 +10,7 @@
"devDependencies": {
"tslint": "^4.4.2",
"tslint-microsoft-contrib": "^4.0.0",
- "powerbi-visuals-tools": "1.7.1"
+ "powerbi-visuals-tools": "1.10.0",
+ "powerbi-visuals-utils-dataviewutils": "1.2.0"
}
-}
+}
\ No newline at end of file
diff --git a/pbiviz.json b/pbiviz.json
index 3c9e54d..c78b58e 100644
--- a/pbiviz.json
+++ b/pbiviz.json
@@ -4,12 +4,12 @@
"displayName": "Forecasting",
"guid": "PBI_CV_8EDDC07B_EE79_4418_A84C_D73897C0E21F_HTML",
"visualClassName": "Visual",
- "version": "1.0.3",
- "description": "Time series forecasting is the use of a model to predict future values based on previously observed values. Current visual implements well known exponential smoothing method for the forecasting. The prediction is based on trend and seasonality modeling. You can control the algorithm parameters and the visual attributes to suit your needs.Service prerequisites: R-powered custom visual is used in service seamlesslyDesktop prerequisites: To run R scripts in Power BI Desktop, you must separately install R on your local computer. You can download and install R for free from the Revolution Open download page or the CRAN Repository R package dependencies(auto-installed): graphics, scales, forecast, zoo, ggplot2, htmlWidgets, XML, plotly Supports R versions: R 3.3.1, R 3.3.0, MRO 3.3.1, MRO 3.3.0, MRO 3.2.2 ",
+ "version": "1.0.4",
+ "description": "Time series forecasting is the use of a model to predict future values based on previously observed values. Current visual implements well known exponential smoothing method for the forecasting. The prediction is based on trend and seasonality modeling. You can control the algorithm parameters and the visual attributes to suit your needs.Service prerequisites: R-powered custom visual is used in service seamlesslyDesktop prerequisites: To run R scripts in Power BI Desktop, you must separately install R on your local computer. You can download and install R for free from the Revolution Open download page or the CRAN Repository R package dependencies(auto-installed): graphics, scales, forecast, zoo, ggplot2, htmlWidgets, XML, plotly Supports R versions: R 3.3.1, R 3.3.0, R 3.4.1, MRO 3.3.1, MRO 3.3.0, MRO 3.2.2 ",
"supportUrl": "http://community.powerbi.com/",
"gitHubUrl": "https://github.com/microsoft/PowerBI-visuals-forcasting-exp"
},
- "apiVersion": "1.7.0",
+ "apiVersion": "1.10.0",
"author": {
"name": "Microsoft",
"email": "pbicvsupport@microsoft.com"
@@ -17,8 +17,11 @@
"assets": {
"icon": "assets/icon.png"
},
- "externalJS": [],
+ "externalJS": [
+ "node_modules/powerbi-visuals-utils-dataviewutils/lib/index.js"
+ ],
"style": "style/visual.less",
"capabilities": "capabilities.json",
- "dependencies": "dependencies.json"
+ "dependencies": "dependencies.json",
+ "stringResources": []
}
diff --git a/r_files/flatten_HTML.r b/r_files/flatten_HTML.r
index b0e387f..8e73e56 100644
--- a/r_files/flatten_HTML.r
+++ b/r_files/flatten_HTML.r
@@ -115,5 +115,14 @@ FindSrcReplacement <- function(str)
str = paste('https://cdn.plot.ly/plotly-', verstr,'.min.js', sep='')
return(str)
}
+#ReadFullFileReplaceString
+ReadFullFileReplaceString <- function(fnameIn, fnameOut, sourceString,targetString)
+{
+ if(!file.exists(fnameIn))
+ return(NULL)
+
+ tx <- readLines(fnameIn)
+ tx2 <- gsub(pattern = sourceString, replace = targetString, x = tx)
+ writeLines(tx2, con = fnameOut)
+}
#################################################
-
diff --git a/script.r b/script.r
index ce3c379..84168fa 100644
--- a/script.r
+++ b/script.r
@@ -29,21 +29,11 @@
source('./r_files/flatten_HTML.r')
############### Library Declarations ###############
-libraryRequireInstall("ggplot2");
+libraryRequireInstall("ggplot2")
libraryRequireInstall("plotly")
+libraryRequireInstall("caTools")
####################################################
-#DEBUG
-# fileRda = "C:/Users/boefraty/projects/PBI/R/tempData.Rda"
-# if(file.exists(dirname(fileRda)))
-# {
-# if(Sys.getenv("RSTUDIO")!="")
-# load(file= fileRda)
-# else
-# save(list = ls(all.names = TRUE), file=fileRda)
-# }
-
-
Sys.setlocale("LC_ALL","English") # Internationalization
############ User Parameters #########
@@ -106,20 +96,34 @@ drawConfidenceLevels = TRUE
if(exists("settings_conf_params_show"))
drawConfidenceLevels = settings_conf_params_show
-
-lowerConfInterval = 0.8
-if (exists("settings_conf_params_percentile"))
-{
- lowerConfInterval = as.numeric(settings_conf_params_percentile)/100
- if(is.na(lowerConfInterval))
- lowerConfInterval = 0.8
-
- lowerConfInterval = max(min(lowerConfInterval,0.99),0)
+##PBI_PARAM: Confidence level
+#Type:enum, Default:"0.8", Range:NA, PossibleValues:0, 0.5 etc, Remarks: NA
+confInterval1 = 0.8
+if(exists("settings_conf_params_confInterval1"))
+{
+ confInterval1 = as.numeric(settings_conf_params_confInterval1)
}
-upperConfInterval = 0.98
-if (exists("settings_conf_params_upperConfIntervalFactor"))
-{ upperConfInterval = lowerConfInterval+(1-lowerConfInterval)*as.numeric(settings_conf_params_upperConfIntervalFactor)}
+
+##PBI_PARAM: Confidence level
+#Type:enum, Default:"0.95", Range:NA, PossibleValues:0, 0.5 etc, Remarks: NA
+confInterval2 = 0.95
+if(exists("ssettings_conf_params_confInterval2"))
+{
+ confInterval2 = as.numeric(settings_conf_params_confInterval2)
+}
+
+
+if(confInterval1 > confInterval2)
+{#switch places
+ temp = confInterval1
+ confInterval1 = confInterval2
+ confInterval2 = temp
+}
+
+lowerConfInterval = confInterval1
+upperConfInterval = confInterval2
+
if(drawConfidenceLevels==FALSE)
lowerConfInterval=upperConfInterval=0
@@ -164,6 +168,23 @@ cexSub = 0.75
if(exists("settings_additional_params_textSize"))
cexSub = as.numeric(settings_additional_params_textSize)/12
+##PBI_PARAM: export out data to HTML?
+#Type:logical, Default:FALSE, Range:NA, PossibleValues:NA, Remarks: NA
+keepOutData = FALSE
+if(exists("settings_export_params_show"))
+ keepOutData = settings_export_params_show
+
+##PBI_PARAM: method of export interface
+#Type: string , Default:"copy", Range:NA, PossibleValues:"copy", "download", Remarks: NA
+exportMethod = "copy"
+if(exists("settings_export_params_method"))
+ exportMethod = settings_export_params_method
+
+##PBI_PARAM: limit the out table exported
+#Type: string , Default:1000, Range:NA, PossibleValues:"1000", "10000", Inf, Remarks: NA
+limitExportSize = 1000
+if(exists("settings_export_params_limitExportSize"))
+ limitExportSize = as.numeric(settings_export_params_limitExportSize)
###############Internal parameters definitions#################
@@ -376,6 +397,65 @@ getAngleXlabels = function(mylabels)
}
+ConvertDF64encoding = function (df, withoutEncoding = FALSE)
+{
+ header_row <- paste(names(df), collapse=", ")
+ tab <- apply(df, 1, function(x)paste(x, collapse=", "))
+
+ if(withoutEncoding){
+ text <- paste(c(header_row, tab), collapse="\n")
+ x <- text
+ }
+ else
+ {
+ text <- paste(c(header_row, tab), collapse="\n")
+ x <- caTools::base64encode(text)
+ }
+ return(x)
+}
+
+
+KeepOutDataInHTML = function(df, htmlFile = 'out.html', exportMethod = "copy", limitExportSize = 1000)
+{
+ if(nrow(df)>limitExportSize)
+ df = df[1:limitExportSize,]
+
+ outDataString64 = ConvertDF64encoding(df)
+
+ linkElem = '\nexport \n'
+ updateLinkElem = paste(' ', sep =' ')
+ var64 = paste('', sep ="")
+ var64href = paste('', sep ="")
+
+ buttonElem = 'copy to clipboard '
+ funcScript = ''
+
+ if(exportMethod == "copy")
+ endOfBody = paste(var64,funcScript, buttonElem,'\n