-
Notifications
You must be signed in to change notification settings - Fork 0
Angular frontend architecture (new)
- Docker
- Nginx
- Angular 5
- Angular Material
- Plotly.js
The frontend is based on a docker architecture to simplify the deployment as much as possible. To serve the website built by Angular 5 in combination with Angular Material and Plotly.js for styling and data visualization, we use a Nginx-webserver.
Services are responsible for the API-Server communication and state synchronization. Directory: /src/app/services/
The Chain-selector service is responsible for providing the current chain selection by the user to other components. It also defines the ChainItem and ChainSelection interfaces. This is necessary to provide a consistent state between the chain-data-source-selector and the data-visualization-bar component.
name: string,
target: string,
isEmpty(): boolean
selectedChains: ChainSelection
setSelectedChains(selectedChains: ChainSelection): void
The data-retriever is responsible to fetch chain data from the API-server. It takes a target (protected Chains), a chain and a time span to fetch the correct data. If you have to get data from multiple chains (ChainSelection), the service joins them to one result in the getChainData() function. You can also load replay data with the data-retriever. This service also provides an interface for the chain data (ChainData).
access: string
avgBlocktime: Array<number>
avgDifficulty: Array<number>
avgGasPrice: Array<number>
avgHashrate: Array<number>
chainName: string
numberOfHosts: Array<number>
numberOfMiners: Array<number>
timestamp: Array<string>
target: string
getPublicChainApiData(chain: string, timeSpan: object): Observable<ChainData>
getPrivateChainApiData(chain: string, target: string, timeSpan: object): Observable<ChainData>
getChainData(selectedChains: ChainSelection, timeSpan): Observable<Array<ChainData>>
getReplayApiData(chain: string, target: string, startTime: string, endTime: string): Observable<object>
chainInfo(): Observable<string>
setChainParameters(parameters: object): Observable<string>
The Parameter-configurator is used to control the chains. You can get the current state of the chains and start and stop them. The API-server provides configuration options for the chain that can be manipulated by using setChainParameters().
chainInfo(): Observable<string>
setChainParameters(parameters: object): Observable<string>
startChain(chainName: string, target: string): Observable<string>
stopChain(chainName: string, target: string): Observable<string>
The Recording-handler is responsible for starting and stopping recordings. It also provides functions to receive all recordings, the current recording state and triggers a replay. To trigger the replay the service provides an interface with all necessary replay data for the data-visualization-bar component.
replaying: boolean
recordingTimes: object
selectedRecordingChains: ChainSelection
The Scenario-configurator is responsible for scenario uploads, creations and for the scenario selection by providing functions to receive scenario information.
upload(object): Observable<string>
createScenario(object): Observable<string>
getScenarios(): Observable<Object>
getScenario(id: string): Observable<Object>
The User-authentication service provides functions to authenticate / logout the user and check the current state to automatically logout the user.
authenticate(username: string, password: string): Observable<boolean>
checkAuthenticationStatus(): Observable<string>
logout(): Observable<string>
The frontend is splitted into separate components. All components compose out of following files:
- HTML-file (responsible for the structure of the component)
- .ts-file (responsible for the logic of the component)
- .ts.spec-file (responsible for testing the component)
- .scss-file (responsible for styling the component)
The main component is the app.component. This is the entry point for the construction of the site. All other components are integrated by the app.module file. All other components get included hierarchically in the HTML files. The app.component provides the general structure of the whole website (Header, Footer, content-structure). The content is divided into two bars (also two components). The smaller left bar is responsible for all adjustable options / configuration of the chain (selection-bar). The bigger right bar is responsible for displaying actual data. (data-visualization-bar)
The configuration bar is responsible for the configuration of the chains. Most of this part is hidden when you are not authenticated to the server. It also checks periodically if you are still logged in. The only element you can see if you are not logged in is the chain-datasource-selector component. If you are logged in, you have access to all sub-components. The Configuration bar is split into 4 parts:
- Chain parameter configuration (Parameter-setter)
- Chain data source selector (Chain-data-source-selector)
- Recorder (Chain-recorder)
- Scenario upload (File-reader)
The parameter-setter is the main component of the configuration bar. It is responsible for the chain parameter configuration. You can select a target and a chain and configure it. You can configure the same chain on different targets individually. The current state of the chain gets displayed above the input field. The input fields to manipulate the chain are generated by the possible configuration options provided by the API-server. Input fields appear if all necessary inputs are given (e.g. chain configuration pops up if you select a chain). You can also select a scenario for each blockchain individually in the scenario-selector component. If you select the special scenario 'Create', all chain configurations are disabled and a scenario creation menu appears to create a new scenario.
The scenario selector polls scenario data from the API-server. It also does the name lookup if a chain already runs a scenario (chain state is given by the API-server). You can select a chain and the selection gets passed to the parent component.
The scenario creator is responsible for creating generic scenarios. To create a scenario you have to fill the form information:
- Name
- Description
- Number of nodes
- Transaction interval
- Payload size
Number of nodes describes the minimal amount of nodes that have to exist for this scenario. Transaction interval and payload size are rendered as slider to border the amount (avoid DoS). If you create a scenario, the menu closes and the scenario will be added to all scenarios.
The chain data source selector is responsible for the user selection of the chains. It displays all currently provided chains (Provided does not have to be active. It displays all possible chains that are provided by the targets). It stores the state in the chain-selection service to make it accessible for the display components. (data-visualization-bar)
The chain recorder is responsible for recording the current execution. Because the recording is a global event upon initialisation has to been checked if a recording is already running. If so, it's name and how long it is already running for is fetched and displayed. Upon starting a recording, the global recording state is set to true, the timer is started and the recording handler service is given the recording name to start the recording. Because of the recordings global state, it's periodically checked Upon stopping, the recording set is set to false, the timer is reset and the recording handler service is told to stop the recording.
The chain recorder display displays all recordings to the backend. Upon starting a replay, the replaying state is set to true and the corresponding chains, end and start time are retrieved. The replay state is responsible for telling the visualisation bar which data to get from the backend. Upon stopping everything is reset and the replay state is set to false.
The file reader is responsible for the scenario upload. You can set a name, a description and upload a .xes scylla logfile. To upload the scylla file you can drag and drop it into the provided dropzone. To upload the scenario just click upload.
The data-visualization-bar is responsible for fetching, distributing and displaying actual data. It provides two main parts: The parameter visualization and the metric visualization. It is also responsible for calculating the metrics for the given parameters (metric-calculation-helper). The first part is composed by 3 elements. A time span selection, the line chart to display data and a toggle group to select the parameter that should be displayed on the line chart. The second part is an amount of bar charts that receive the metric that should be displayed. Following metrics will be calculated and provided for the charts:
- Mining time
- Stability
- Energy consumption
- Data transfer
- Throughput
To render the data we use Plotly.js.
The line chart receives data with corresponding timestamps. To keep the chart up to date it has a redraw() function that can be called by the parent component. It also redraws if the input data changes. If the component has to redraw, it purges the existing element and plots a new plot. The line chart has fixed ranges for the x-axis to display the data according to the given time span and not adjusted. Other options such as zooming or scrolling are disabled because they caused bugs.
The bar chart receives data sets of labels and chain names. It maps them together to display them correctly. It also can be redrawn by the parent component. The redraw behavior is analog to the line chart.
To style our components we use the Angular Material framework. Additionally to the already styled components we used SASS in combination with the local styling of Angular. Every component has a .scss-file in the directory that is used to style only this component.