dependencies dependencies cluster_DataVisualizationModule cluster_DataVisualizationModule_providers DatasetsService DatasetsService DataVisualizationModule DataVisualizationModule DatasetsService->DataVisualizationModule

File

lib/features/src/data-visualization/data-visualization.module.ts

Providers

Methods

Static forChild
forChild(reportPreparatorClasses: Type[])
Parameters :
Name Type Optional
reportPreparatorClasses Type<ReportPreparator>[] No
Returns : ModuleWithProviders<DataVisualizationModule>

Data visualization [needs refinement].

Data visualization to this point means visualization of report data. (Report)

Data visualization happens in two steps:

  1. Preparing raw data into something comprehensible. ReportPreparator
  2. Providing a widget that actually visualizes the prepared data. [HowTo Widgets]](/modules/WidgetsModule.html#readme)

1.Preparation

The Preparation of raw data (for now only raw report data) is done with a ReportPreparator. ReportPreparators are injectables, that can make use of other services, and have a single method to turn reports into Datasets). The BasicReportPreparatorModule already provides a preparator for each question. So for every report and every question Question that has an answer in that Report, we already get a separate dataset Dataset.

Why so complicated?

The raw data only contains the data of answers (as Entries) and those in turn do NOT contain the wording of a question, but only the questionId. In order to visualize the data and e.g. add an appropriate label the wording of the question would be great to have. The wording though is stored somewhere else. Whatever part of the app does the actual visualization should not be concerend with gathering data from multiple sources. Instead we should compile the relevant data and then hand it over to the part that does the actual visualization. (And that will be a Widget, see below.) That's what the preparators do.

Here's another case why the process should be split into two steps:

Example ReportPreparator

Let's say we care a about a certain set of questions, that share a tag and have the same numerical answer options. For example:

  • How is your back?
  • How are your joints?
  • How is your head?

Answer options: 0,1,2,3,4 (corresponding to, terrible/bad/okay/fine/splendid). All tagged with #my-physical-state.

Now we're interested in the overall physical state; and instead of asking 'How are you overall physically?' we aggregate the answer to the previous questions into a new Dataset.

Checkout ExampleReportPreparatorModule for a complete example implementation.

How to add a custom preparator

To add a custom preparator, define a new injectable extending the base class (ReportPreparator), then register it with the DataVisualizationModule:

    @Injectable()
    export class MyReportPreparator extends ReportPreparator{
        ...
    }

    ...


    @NgModule({
    imports: [
        DataVisualizationModule.forChild( [MyReportPreparator] ),
    ],
    providers: [
        MyReportPreparator
    ]
})
export class MyModule{}

If your new ReportPreparator class, does not depend on any other injectables, you don't have to make it injectable and also don't have to provide it, just register your new class with DataVisualizationModule.forChild().

For an example see ExampleReportPreparator source.

2. Provide a widget

See Widgets howto to see how widgets work generally. For data visualization (of reports) you have to provide a component extending WidgetComponent<DataViewControl>

Every DataViewControl comes with one or more associated Datasets. If your Widget cannot handle that many Datasets dont match it!

    @Component()
    export class MyDataViewWidget extends WidgetComponent<DataViewControl> {

        static match(dataViewControl: DataViewControl){

            //can't handle more than one Dataset:
            if(dataViewControl.data.length > 1) return -1

            ...

            return 0

        }
    }

If your widget is meant to handle a certain type of data, adjust the matching method. In the ExampleReportPreparatorModule we add a virtual Question with the help of a ReportPreparator (see example source) and this question gets tagged with #my-physical-state-overall. The new widget now is meant to take the job for any dataViewControl that comes with a secondary Dataset that matches this tag:

    @Component()
    export class MyDataViewWidget extends WidgetComponent<DataViewControl> {

        static match(dataViewControl: DataViewControl){

            // This widget can deal with just one Dataset:
            if(dataViewControl.data.length == 1) return 1

            // If there is no data set or more than two, this widget cannot do the trick:
            if(dataViewControl.data.length != 2) return -1

            // If the second Dataset is tagged with #my-physical-state-overall, this widget is a perfect match!
            if(dataViewControl.data[1].question.tags.includes('#my-physical-state-overall')) return 2

            // In any other case; i.e. the tag is missing, this widget has no clue what to do:
            return -1

        }
    }

import	{	
			NgModule,
			ModuleWithProviders,
			Type		
		}										from '@angular/core'

import	{	DatasetsService					}	from './data-sets/data-sets.service'

import	{	
			ReportPreparator,
			REPORT_PREPARATORS,				
		}										from './data-sets/data-sets.commons'




@NgModule({
	declarations: [
	],
	providers: [
		DatasetsService,
	]
})
export class DataVisualizationModule { 

	static forChild(reportPreparatorClasses: Type<ReportPreparator>[]): ModuleWithProviders<DataVisualizationModule> {

		console.log("DataVisualizationModule.forChild don't use this method, implement provideReportPreparator")

		return {
			ngModule: 	DataVisualizationModule,
			providers:	[
							...(reportPreparatorClasses||[]).map( reportPreparatorClass => ({ provide: REPORT_PREPARATORS, useValue: reportPreparatorClass, multi: true })),							
						]
		}
	}


}

results matching ""

    No results matching ""