Add SCL support for exporting subscription data as CSV
[simantics/platform.git] / bundles / org.simantics.charts / scl / Simantics / Chart.scl
index efbe3143f27103a0b810e7044ac04e0d2d763855..3972fd95c9317f58730eac5a193037a6ed840775 100644 (file)
@@ -54,3 +54,150 @@ chartsOf model = recurse (toResource model)
         charts + concatMap recurse chartGrp
     isChart r = isInstanceOf r CHART.TimeSeriesChart
     isChartGroup r = isInstanceOf r CHART.ChartGroup
+
+//-----------------------------------------------------------------------------
+// Support for exporting subscription data in CSV format
+
+import "UI/Progress" as Progress
+import "File"
+
+importJava "org.simantics.history.csv.DecimalSeparator" where
+    data DecimalSeparator
+
+    @JavaName fromPreference
+    """
+    Possible arguments are:
+    
+        Dot (.)
+        Comma (,)
+    """
+    decimalSeparatorFromString :: String -> <Proc> DecimalSeparator
+
+importJava "org.simantics.history.csv.ColumnSeparator" where
+    data ColumnSeparator
+
+    @JavaName fromPreference
+    """
+    Possible arguments are: 
+    
+        Comma (,)
+        Tabulator (\\t)
+        Semicolon (;)
+        Colon (:)
+        Space ( )
+    """
+    columnSeparatorFromString :: String -> <Proc> ColumnSeparator
+
+importJava "org.simantics.history.csv.ExportInterpolation" where
+    data ExportInterpolation
+
+    @JavaName fromPreference
+    """
+    Possible arguments are:
+    
+        Linear Interpolation (lerp)
+        Previous Sample (previous)
+    """
+    exportInterpolationFromString :: String -> <Proc> ExportInterpolation
+
+importJava "org.simantics.charts.ui.CSVExportPlan" where
+    @FieldNames [startTime, timeStep, decimalSeparator, columnSeparator, resample, samplingMode, timeDigits, floatDigits, doubleDigits]
+    
+    """
+    Example of construction:
+    
+        plan = CSVExportPlan {
+            startTime = 0.0,
+            timeStep = 1.0,
+            decimalSeparator = decimalSeparatorFromString ".",
+            columnSeparator = columnSeparatorFromString ",",
+            resample = True,
+            samplingMode = exportInterpolationFromString "lerp",
+            timeDigits = 7,
+            floatDigits = 9,
+            doubleDigits = 15
+        }
+    """
+    data CSVExportPlan = CSVExportPlan {
+        startTime :: Double,
+        timeStep :: Double,
+        decimalSeparator :: DecimalSeparator,
+        columnSeparator :: ColumnSeparator,
+        resample :: Boolean,
+        samplingMode :: ExportInterpolation ,
+        timeDigits :: Integer,
+        floatDigits :: Integer,
+        doubleDigits :: Integer
+    }
+    
+    @JavaName setItems
+    @private
+    setCSVExportPlanItems :: CSVExportPlan -> [Resource] -> <Proc> ()
+
+"""
+Example of construction:
+
+    plan = SubscriptionCSVExportPlan {
+        modelName = "Model",
+        filePath = "D:/folder/output.csv",
+        subscriptionNames = ["Default"],
+        exportPlan = CSVExportPlan {}
+    }
+"""
+data SubscriptionCSVExportPlan = SubscriptionCSVExportPlan {
+    modelName :: String,
+    subscriptionNames :: [String],
+    filePath :: String,
+    exportPlan :: CSVExportPlan
+}
+
+@private
+modelNameOf SubscriptionCSVExportPlan { modelName } = modelName
+@private
+subscriptionNamesOf SubscriptionCSVExportPlan { subscriptionNames } = subscriptionNames
+@private
+filePathOf SubscriptionCSVExportPlan { filePath } = filePath
+@private
+exportPlanOf SubscriptionCSVExportPlan { exportPlan } = exportPlan
+
+importJava "org.simantics.charts.ui.CSVExporter" where
+    @JavaName doExport
+    @private
+    exportSubscriptionsCSVInternal :: Progress.ProgressMonitor -> File -> CSVExportPlan -> <Proc> ()
+
+"""
+Exports subscription data as CSV values in a similar manner as the CSV Exporter provided by the user interface
+
+Example of usage:
+
+    exportSubscriptionsCSV SubscriptionCSVExportPlan {
+        modelName = "Model",
+        filePath = "D:/folder/output.csv",
+        subscriptionNames = ["Default"],
+        exportPlan = CSVExportPlan {
+            startTime = 0.0,
+            timeStep = 1.0,
+            decimalSeparator = decimalSeparatorFromString ".",
+            columnSeparator = columnSeparatorFromString ",",
+            resample = True,
+            samplingMode = exportInterpolationFromString "lerp",
+            timeDigits = 7,
+            floatDigits = 9,
+            doubleDigits = 15
+        }
+    }
+"""
+exportSubscriptionsCSV :: SubscriptionCSVExportPlan -> <Proc> ()
+exportSubscriptionsCSV subscriptionExportPlan = do
+    items = syncRead (\_ -> resolveSubscriptionItems (modelNameOf subscriptionExportPlan) (subscriptionNamesOf subscriptionExportPlan))
+    csvExportPlan = exportPlanOf subscriptionExportPlan
+    setCSVExportPlanItems csvExportPlan items
+    exportSubscriptionsCSVInternal (Progress.createNullProgressMonitor ()) (file (filePathOf subscriptionExportPlan)) csvExportPlan
+
+@private
+resolveSubscriptionItems :: String -> [String] -> <Proc, ReadGraph> [Resource]
+resolveSubscriptionItems modelName subscriptionNames = concatMap itemsOf (filter nameFilter subscriptions)
+    where
+        nameFilter sub = elem (relatedValue2 sub L0.HasLabel) subscriptionNames
+        subscriptions = (objectsWithType (model modelName) L0.ConsistsOf MOD.Subscription)
+        itemsOf subscription = objectsWithType subscription L0.ConsistsOf MOD.Subscription.Item