=== Creating a FlatWidget

Data Visualisation in the Live-View is enabled with the link:https://github.com/OpenEMS/openems/tree/develop/ui/src/app/shared/genericComponents/flat[flat, window="_blank"] and https://github.com/OpenEMS/openems/tree/develop/ui/src/app/shared/genericComponents/modal[modal, window="_blank"]-widgets.

The FlatWidget is mandatory for a Modal-Widget. Its purpose is to show only  the most important or general data. It also acts as a button, that can open the ModalWidget.

[source,html]
----
<ng-container *ngIf="isInitialized">
    <oe-flat-widget (click)="presentModal()" [icon]="{name:'swap-vertical-outline'}" [title]="component.alias">
        <oe-flat-widget-line [name]="'General.state' | translate" [value]="propertyMode"
            [converter]="CONVERT_MANUAL_ON_OFF">
        </oe-flat-widget-line>

        <ng-container *ngIf="propertyMode === 'MANUAL_ON'">
            <oe-flat-widget-line [name]="chargeDischargePower.name" [value]="chargeDischargePower.value"
                [converter]="CONVERT_WATT_TO_KILOWATT">
            </oe-flat-widget-line>
        </ng-container>
    </oe-flat-widget>
</ng-container>
----

If we take another look at the example of FixActivePowers FlatWidget you can see that everything is wrapped up in a ```ng-container``` with a statement, that will return true, if the edge and the edgeConfig have been received from Backend or Edge. The Widget will not be shown, till this condition is met.

One step further there is a ```oe-flat-widget```. If you take a look at the link:https://github.com/OpenEMS/openems/blob/develop/ui/src/app/shared/genericComponents/flat/flat.ts[corresponding class, window="_blank"], you will see multiple `@Input()` properties. These properties can be passed with the Widget. If you are not familiar with `@Input()` and `@Output()`, window="_blank", take a look link:https://angular.io/guide/inputs-outputs[here].

Inside this `@Component`-tag, multiple other Components can be used.


[cols="2,2"]  
|===
a|
[source, html]
----
<oe-flat-widget-line [name]="chargeDischargePower.name"  [value]="chargeDischargePower.value"
[converter]="CONVERT_WATT_TO_KILOWATT">
</oe-flat-widget-line>
----

or

[source, html]
----
 <oe-flat-widget-line [name]="component.alias" 
 [channelAddress]="
 component.id + '/ActualPower'"
[converter]="CONVERT_WATT_TO_KILOWATT">
</oe-flat-widget-line>

----
a|image::ui-flat-widget-fixactivepower.png[FlatWidget FixActivePower]

Shows a row with a @Input() name left and @Input() value on the right. This value can also be converted with @Input() converter.

a|
[source, html]
----
<oe-flat-widget-percentagebar [channelAddress]="
component.id + '/Soc'">
</oe-flat-widget-percentagebar>
----

a| image::ui-flat-widget-autarchy.png[]



a|
[source, html]
----
<oe-flat-widget-horizontal-line></oe-flat-widget-horizontal-line>
----

a| 
image::ui-flat-widget-consumption.png[]
Shows a horizontal line, that is used to divide children of AbstractFlatWidgetLine.

|=== 

Passing data can be done two ways:

- @Input() channelAddress: provide channel, which will be subscribed in AbstractFlatWidgetLine.
-  @Input() value: subscribe in the ts-file and pass the subscribed value.

### Creating a modal

Creating a `modal-widget` is pretty similar to creating a `flat-widget`.
The model should act as the detailed view of a `flat-widget` and can also fit the purpose of user interaction.

There are multiple implementations of `modals` at the creation time of this page, but the one thats considered best practice is the unit-testable version.

#### Creating a Line

Lets take a look at one link:https://github.com/OpenEMS/openems/blob/develop/ui/src/app/edge/live/common/consumption/modal/modal.ts[example].

[source, html]
----
public static generateView(
    config: EdgeConfig, role: Role, translate: TranslateService)
    :OeFormlyView {

    // Total
    lines.push({
      type: 'channel-line',
      name: translate.instant('General.TOTAL'),
      channel: '_sum/ConsumptionActivePower',
      converter: Converter.ONLY_POSITIVE_POWER_AND_NEGATIVE_AS_ZERO
    });
    
    return {
      title: translate.instant('General.grid'),
      lines: lines
    };
}
----

Predefined fields in link:https://github.com/OpenEMS/openems/blob/develop/ui/src/app/shared/genericComponents/shared/oe-formly-component.ts[OeFormlyField] can be used here.

For this line we use the type 'channel-line'. This represents a line, where a channel has to be subscribed. You also need to specify the link:https://github.com/OpenEMS/openems/blob/develop/ui/src/app/shared/genericComponents/shared/converter.ts[converter], that uses the data coming from this channel and mutates it. A link:https://github.com/OpenEMS/openems/blob/develop/ui/src/app/shared/genericComponents/shared/filter.ts[filter], which has to return a boolean, decides if the line will be shown or not.

NOTE: Lines should always present one line of data visualisation. It could be consisting of a identifier and a value or just a value. The value or channel will be shown at the end of the line, the name, if provided, at the start.

This line will be looking like this:

image::modal-line-example-consumption.png[]
