diff --git a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/component/Observation.java b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/component/Observation.java index 09e9dc35..2f80b759 100644 --- a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/component/Observation.java +++ b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/component/Observation.java @@ -15,8 +15,6 @@ import io.redlink.more.studymanager.core.ui.DataView; import io.redlink.more.studymanager.core.ui.DataViewInfo; -import java.util.Set; - public abstract class Observation extends Component { protected final MoreObservationSDK sdk; @@ -25,10 +23,24 @@ protected Observation(MoreObservationSDK sdk, C properties) throws Configuration this.sdk = sdk; } + /** + * Gets an array of DataViewInfo, which represents all possibilities to show this observation data. + * + * @return an array of DataViewInfo representing all possible views of the observation data + */ public DataViewInfo[] listViews() { return new DataViewInfo[0]; } + /** + * Retrieves a specific DataView based on the given parameters. + * + * @param viewName the name of the view to retrieve + * @param studyGroupId the ID of the study group for filter reasons + * @param participantId the ID of the participant for filter reasons + * @param timerange the time range for the data view for filter reasons + * @return the requested DataView, or null if not found + */ public DataView getView(String viewName, Integer studyGroupId, Integer participantId, TimeRange timerange) { return null; } diff --git a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataView.java b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataView.java index 5d64fefa..5f94bb0b 100644 --- a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataView.java +++ b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataView.java @@ -8,11 +8,21 @@ */ package io.redlink.more.studymanager.core.ui; +/** + * Represents a data view with information, chart type, and data. + * + * @param viewInfo the information about the data view + * @param chartType the type of chart to be displayed + * @param data the data to be displayed in the view + */ public record DataView( DataViewInfo viewInfo, ChartType chartType, DataViewData data ) { + /** + * Enumeration of possible chart types. + */ public enum ChartType { LINE, BAR, diff --git a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewData.java b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewData.java index 92a0ace3..472ca383 100644 --- a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewData.java +++ b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewData.java @@ -1,7 +1,21 @@ +/* + * Copyright LBI-DHP and/or licensed to LBI-DHP under one or more + * contributor license agreements (LBI-DHP: Ludwig Boltzmann Institute + * for Digital Health and Prevention -- A research institute of the + * Ludwig Boltzmann Gesellschaft, Österreichische Vereinigung zur + * Förderung der wissenschaftlichen Forschung). + * Licensed under the Elastic License 2.0. + */ package io.redlink.more.studymanager.core.ui; import java.util.List; +/** + * Represents the data in a data view. + * + * @param labels the labels for the data + * @param rows the rows of data + */ public record DataViewData( List labels, List rows diff --git a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewInfo.java b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewInfo.java index d3383cde..25bf45a0 100644 --- a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewInfo.java +++ b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewInfo.java @@ -9,9 +9,43 @@ package io.redlink.more.studymanager.core.ui; public interface DataViewInfo { + /** + * Gets the name of the data view. + * The name is the identifier of a specific view. + * + * @return the name of the data view + */ String name(); + + /** + * Gets the label of the data view. + * The label is a short indicator to differ between multiple views. + * + * @return the label of the data view + */ String label(); + + /** + * Gets the title of the data view. + * The title is a short textual information about the observation data. + * + * @return the title of the data view + */ String title(); + + /** + * Gets the description of the data view. + * The description explains what the given observation data shows. + * + * @return the description of the data view + */ String description(); + + /** + * Gets the chart type of the data view. + * The chartType indicates how the given observation data is visually shown. + * + * @return the chart type of the data view + */ DataView.ChartType chartType(); } \ No newline at end of file diff --git a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewRow.java b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewRow.java index f55bce15..f3ecf8fd 100644 --- a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewRow.java +++ b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/DataViewRow.java @@ -10,6 +10,12 @@ import java.util.List; +/** + * Represents a row of data in a data view. + * + * @param label the label of the data row + * @param values the list of values in the data row + */ public record DataViewRow( String label, List values diff --git a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/ViewConfig.java b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/ViewConfig.java index 1b3deed6..7c77bd22 100644 --- a/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/ViewConfig.java +++ b/studymanager-core/src/main/java/io/redlink/more/studymanager/core/ui/ViewConfig.java @@ -10,18 +10,31 @@ import java.util.List; +/** + * Represents the configuration of a data view. + * + * @param filters the list of filters applied to the data view + * @param rowAggregation the aggregation method for rows + * @param seriesAggregation the aggregation method for series + * @param operation the operation applied to the data + */ public record ViewConfig( List filters, Aggregation rowAggregation, Aggregation seriesAggregation, Operation operation ) { - + /** + * Represents a filter applied to the data view. + */ public record Filter( ) { } + /** + * Enumeration of possible aggregation methods. + */ public enum Aggregation { TIME, STUDY_GROUP, @@ -29,12 +42,21 @@ public enum Aggregation { TERM_FIELD, } + /** + * Represents an operation applied to the data. + * + * @param operator the operator to be used + * @param field the field to which the operation is applied + */ public record Operation( Operator operator, String field ) { } + /** + * Enumeration of possible operators. + */ public enum Operator { AVG, SUM, diff --git a/studymanager-observation/README.md b/studymanager-observation/README.md new file mode 100644 index 00000000..6d64e315 --- /dev/null +++ b/studymanager-observation/README.md @@ -0,0 +1,41 @@ +# More Studymanager Observation + +## Data Preview + +### How to extend a given observation to show different visualisations +If you want to modify existing data views for observations or want to add a new data view for a specific observation, +you need to edit the corresponding observation file under `studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation` + +Each Observation (e.g. `PolarVerityObservation` or `QuestionObservation`) has two methods which are necessary for the data view. +- `listViews` (Returns an array of DataViewInfo objects, which represents all possibilities to show observation data) +- `getView` (Returns a specific DataView based on the given parameters) + +A `private enum DataViewInfoType` defines all possible types as DataViewInfoType and needs to be implemented in the +corresponding `*Observation.java` file. The name of an enum type is the identifier of a specific view, +which you need for the request, when you want to receive the data for this DataView. + +In the DataViewInfoType, you need to define some information about the data view: +- The translation keys for the label, title and description. These keys needs to be defined in the studymanager-frontend Repository as well (in de.json and en.json) +- The chartType (one type of DataView.ChartType enum) which represents the visual representation (e.g. Pie, Bar or Line) +- The viewConfig which defines how the data will be fetched and aggregated from elastic search + +#### ViewConfig (detailed explanation) +1. The first argument of a ViewConfig record is a List of filters, where you can additionally define filters, which are applied in the elastic query later on (not yet implemented, because currently not needed). +2. The second argument of a ViewConfig record is an Aggregation, where you can define which data points should be shown. The Aggregation can be one of the enum values (e.g. TIME, STUDY_GROUP, PARTICIPANT or TERM_FIELD). +3. The third argument of a ViewConfig record is an Aggregation as well, where you can define the aggregation for the x-axis. +4. The fourth argument of a ViewConfig record is an Operation, where you can define which aggregation function (e.g. AVG, COUNT, SUM) should be applied on which field (e.g. "hr"), which then represents the y-axis. + +#### Example (PolarVerityObservation) +When you request the API endpoint `/studies/{studyId}/observations/{observationId}/views` with the corresponding studyId and observationId (for the Polar Verity Sensor), +you'll get back a list of all possible views, in this case `["heart_rate"]`. +Now you can fetch the observation data view information with the API endpoint `/studies/{studyId}/observations/{observationId}/views/{viewName}`, where `viewName` is `heart_rate`. + +Explanation of the example screenshot below (chart in the Frontend): +- "Heart rate" shown as a Tab in the FE, is the "label" defined in `DataViewInfoType` +- "Average heart rate per part..." shown as the title of the chart, is the "title" defined in `DataViewInfoType` +- "Compares the average heart rate of all ..." shown under the title of the chart, is the "description" defined in `DataViewInfoType` +- Each participant alias is shown in the chart legend, and its query definition is defined in the `ViewConfig.rowAggregation` +- The query definition for the x-axis labels (time) is defined in the `ViewConfig.seriesAggregration` +- The values (y-axis) for each participant is the average heart rate over time and its query definition is defined in the `ViewConfig.Operation`, where you need to define the corresponding observation data (e.g. "hr") and operation type (e.g. `ViewConfig.Operator.AVG`) + +![Heart rate chart](./images/heart_rate_chart.png) \ No newline at end of file diff --git a/studymanager-observation/images/heart_rate_chart.png b/studymanager-observation/images/heart_rate_chart.png new file mode 100644 index 00000000..74929f2f Binary files /dev/null and b/studymanager-observation/images/heart_rate_chart.png differ diff --git a/studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation/PolarVerityObservation.java b/studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation/PolarVerityObservation.java index a45c634f..1e43c399 100644 --- a/studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation/PolarVerityObservation.java +++ b/studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation/PolarVerityObservation.java @@ -18,9 +18,6 @@ import io.redlink.more.studymanager.core.ui.DataViewInfo; import io.redlink.more.studymanager.core.ui.ViewConfig; import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class PolarVerityObservation extends Observation { public PolarVerityObservation(MoreObservationSDK sdk, C properties) throws ConfigurationValidationException { diff --git a/studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation/QuestionObservation.java b/studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation/QuestionObservation.java index 2279e88b..d4af1c84 100644 --- a/studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation/QuestionObservation.java +++ b/studymanager-observation/src/main/java/io/redlink/more/studymanager/component/observation/QuestionObservation.java @@ -18,9 +18,6 @@ import io.redlink.more.studymanager.core.ui.DataViewInfo; import io.redlink.more.studymanager.core.ui.ViewConfig; import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; -import java.util.stream.Stream; public class QuestionObservation extends Observation { diff --git a/studymanager/src/main/java/io/redlink/more/studymanager/service/ElasticDataService.java b/studymanager/src/main/java/io/redlink/more/studymanager/service/ElasticDataService.java index 32dc5613..b1d4f1a7 100644 --- a/studymanager/src/main/java/io/redlink/more/studymanager/service/ElasticDataService.java +++ b/studymanager/src/main/java/io/redlink/more/studymanager/service/ElasticDataService.java @@ -1,3 +1,11 @@ +/* + * Copyright LBI-DHP and/or licensed to LBI-DHP under one or more + * contributor license agreements (LBI-DHP: Ludwig Boltzmann Institute + * for Digital Health and Prevention -- A research institute of the + * Ludwig Boltzmann Gesellschaft, Österreichische Vereinigung zur + * Förderung der wissenschaftlichen Forschung). + * Licensed under the Elastic License 2.0. + */ package io.redlink.more.studymanager.service; import co.elastic.clients.elasticsearch.ElasticsearchClient;