File

src/app/modules/program-dashboard/shared/sb-chart/sb-chart.component.ts

Implements

OnInit OnChanges

Metadata

Index

Properties
Methods
Inputs

Constructor

constructor(resourceService: ResourceService, dialog: MatDialog, filterService: PdServiceService)
Parameters :
Name Type Optional
resourceService ResourceService No
dialog MatDialog No
filterService PdServiceService No

Inputs

appliedFilters
Type : any
chart
Type : any
hideElements
Type : boolean
Default value : false

Methods

changeChartType
changeChartType(change)
Parameters :
Name Optional
change No
Returns : void
checkForGlobalChanges
checkForGlobalChanges()
Returns : void
closeDialog
closeDialog()
Returns : void
filterChanged
filterChanged(data: any)
Parameters :
Name Type Optional
data any No
Returns : void
filterModalPopup
filterModalPopup(operator)
Parameters :
Name Optional
operator No
Returns : void
ngOnChanges
ngOnChanges(_changes: SimpleChanges)
Parameters :
Name Type Optional
_changes SimpleChanges No
Returns : void
ngOnInit
ngOnInit()
Returns : void
openDialog
openDialog()
Returns : void
resetForm
resetForm()
Returns : void

Properties

availableChartTypeOptions
Type : []
Default value : ['Bar', 'Line']
chartConfig
chartData
currentFilters
Type : Array<literal type>
Public dialog
Type : MatDialog
dialogRef
Type : any
filterPopUpMat
Type : TemplateRef<any>
Decorators :
@ViewChild('filterPopUpMat')
Public filterService
Type : PdServiceService
filterType
Type : string
Default value : 'chart-filter'
globalChange
Type : boolean
globalData
lastUpdatedOn
lib
Type : any
Decorators :
@ViewChild('lib', {static: false})
loadash
Default value : _
resetFilters
Public resourceService
Type : ResourceService
selectedFilters
Type : literal type
showLastUpdatedOn
Type : boolean
Default value : false
type
Type : string
updatedData
import { Component, Input, OnChanges, OnInit, SimpleChanges, TemplateRef, ViewChild } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ResourceService } from '@sunbird/shared';
import * as _ from "lodash-es";
import { PdServiceService } from '../services/pd-service/pd-service.service';
import dayjs from 'dayjs';
@Component({
  selector: 'app-sb-chart',
  templateUrl: './sb-chart.component.html',
  styleUrls: ['./sb-chart.component.scss'],
})
export class SbChartComponent implements OnInit, OnChanges {
  @Input() chart;
  lastUpdatedOn;
  @Input() hideElements = false;
  @Input() appliedFilters;
  chartData;
  chartConfig;
  currentFilters: Array<{}>;
  resetFilters;
  updatedData;
  type: string;
  globalChange: boolean;
  globalData;
  selectedFilters: {};
  loadash = _;
  availableChartTypeOptions = ['Bar', 'Line'];
  @ViewChild('lib', { static: false }) lib: any;
  @ViewChild('filterPopUpMat') filterPopUpMat: TemplateRef<any>;
  filterType = 'chart-filter';
  dialogRef: any;
  showLastUpdatedOn: boolean = false;
  constructor(
    public resourceService: ResourceService,
    public dialog: MatDialog,
    public filterService:PdServiceService
  ) { }

  ngOnInit() {
    this.updatedData = this.chartData = _.compact(this.chart.chartData);
    this.chartConfig = _.cloneDeep(this.chart.chartConfig);
    this.type = this.chartConfig.chartType;
    if(_.get(this.chart,'lastUpdatedOn')){
      this.lastUpdatedOn = dayjs(this.chart.lastUpdatedOn).format('DD-MMMM-YYYY');
      if (_.get(this.chartConfig, 'options.showLastUpdatedOn') || this.lastUpdatedOn) {
        this.showLastUpdatedOn = true;
      }
    }
  }

  ngOnChanges(_changes: SimpleChanges): void {
    this.checkForGlobalChanges();
  }

  checkForGlobalChanges() {
    if (Object.keys(this.appliedFilters).length) {
      this.globalData = this.filterService.getFilteredData(this.chartData,this.appliedFilters)
      this.currentFilters = [];
      this.globalChange = true;
      this.updatedData = this.globalData;
      this.lib.instance.update({ data: this.globalData });
    } else {
      this.globalChange = false;
      this.updatedData = this.chartData
      this.lib?.instance?.update({ data: this.chartData });
    }
  }

  changeChartType(change) {
    this.type = _.lowerCase(_.get(change, 'value'));
    this.chartConfig['chartType'] = this.type;
    this.chartConfig.filters.map(data => {
      delete data?.options
    })
    this.lib.instance.update({ data: this.updatedData, type: this.type, config: this.chartConfig })
  }

  filterChanged(data: any): void {
    this.currentFilters = data.filters;
    if (data.filters) {
      if (this.globalChange) {
        this.globalData['selectedFilters'] = data.filters
      } else {
        this.chartData['selectedFilters'] = data.filters
      }
    } else {

      if (this.globalChange) {
        this.globalData['selectedFilters'] = {}
      } else {
        this.chartData['selectedFilters'] = {}
      }
      this.resetFilters = { data: (this.globalChange ? this.globalData : this.chartData), reset: true };
    }
    this.updatedData = data.chartData[0].data;
    this.lib.instance.update({ data: this.updatedData });

  }

  resetForm() {
    this.chartData['selectedFilters'] = {};
    if (this.globalChange) { this.globalData['selectedFilters'] = {}; }
    this.currentFilters = [];
    this.updatedData = this.globalChange ? this.globalData : this.chartData
    this.resetFilters = { data: (this.globalChange ? this.globalData : this.chartData), reset: true };
    this.lib.instance.update({ data: this.updatedData });
  }

  filterModalPopup(operator) {
    if (operator === false) {
      this.closeDialog();
    } else {
      if (this.currentFilters) {
        let dashletData;
        if (this.globalChange) {
          this.globalData['selectedFilters'] = this.currentFilters;
          dashletData = this.globalData;
        } else {
          this.chartData['selectedFilters'] = this.currentFilters;
          dashletData = this.chartData;
        }
        this.resetFilters = { data: dashletData, reset: true };
      } else {
        if(this.globalChange){
          this.globalData['selectedFilters'] = {}
        }else{
          this.chartData['selectedFilters'] = {}
        }
      }
      this.openDialog();
    }

  }


  openDialog() {
    if (this.filterPopUpMat) {
      this.dialogRef = this.dialog.open(this.filterPopUpMat, {
        data: (this.globalChange ? this.globalData['selectedFilters'] : this.chartData['selectedFilters'])
      });
    }
  }

  closeDialog() {
    if (this.dialogRef) {
      this.dialogRef.close();
    }
  }

}
  <div class="d-flex flex-dr">
    <label class="pad5 col-6 chart-title">
      {{ chart?.chartConfig?.options?.title?.text }}
    </label>
    <div class="ml-auto flex-as-flex-end" *ngIf="
        chart?.chartConfig?.chartType === 'bar' ||
        chart?.chartConfig?.chartType === 'line'
      " [ngClass]="{ hide: hideElements }">
      <label class="mr-16">
        <mat-form-field appearance="fill" class="sb-mat__dropdown">
          <mat-label>Select ChartType</mat-label>
          <mat-select role="radio" aria-label="Select Chart type" class="selection"
            (selectionChange)="changeChartType($event)">
            <mat-option class="mat-dropdown__options" role="option" *ngFor="let option of availableChartTypeOptions"
              [value]="option" attr.aria-label="{{ option }}">{{ option }}</mat-option>
          </mat-select>
        </mat-form-field>
      </label>
      <button class="sb-btn sb-btn-normal sb-btn-primary" (click)="filterModalPopup(true)"
        [ngClass]="{ hide: hideElements }">
        {{ resourceService?.frmelmnts?.lbl?.filters }}
      </button>
    </div>
  </div>
  <div *ngIf="showLastUpdatedOn && lastUpdatedOn" class="sb-last-update-status mb-8">
    <span>{{ resourceService?.frmelmnts?.lbl?.lastUpdatedOn }}&nbsp;: </span>
    &nbsp; {{ lastUpdatedOn }}
  </div>
  <div [ngSwitch]="type" class="mt-16">
    <div class="sb-filter-label pt-16 pb-8" *ngIf="currentFilters">
      <div *ngFor="let key of loadash.keys(currentFilters)" class="d-inline-flex flex-w-wrap pr-10">
          <span class="sb-label-name mb-4">{{key}}:</span><span class="sb-label-value"
            *ngFor="let val of currentFilters[key]">{{val}}
          </span>
      </div>
    </div>
    <sb-dashlet *ngSwitchCase="'bar'" [type]="type" [data]="(globalChange ? globalData:updatedData) | chartType" [config]="chartConfig | chartType"
      class="chart-container mt-32 customGraph" #lib>
      <ng-template sbTemplateRef="filter" let-context>
        <ng-template #filterPopUpMat>
          <ng-container *ngTemplateOutlet="chartFilter"></ng-container>
        </ng-template>
      </ng-template>
    </sb-dashlet>
    <sb-dashlet *ngSwitchCase="'line'" [type]="type" [data]="(globalChange ? globalData:updatedData) | chartType" [config]="chartConfig | chartType"
      class="chart-container mt-32 customGraph" #lib>
      <ng-template sbTemplateRef="filter" let-context>
        <ng-template #filterPopUpMat>
          <ng-container *ngTemplateOutlet="chartFilter"></ng-container>
        </ng-template>
      </ng-template>
    </sb-dashlet>
    <sb-dashlet *ngSwitchDefault [type]="type" [data]="(globalChange ? globalData:updatedData) | chartType" [config]="chartConfig | chartType"
      class="chart-container mt-32 customGraph" #lib>
      <ng-template sbTemplateRef="filter" let-context>
        <ng-template #filterPopUpMat>
          <ng-container *ngTemplateOutlet="chartFilter"></ng-container>
        </ng-template>
      </ng-template>
    </sb-dashlet>
    <ng-template #chartFilter>
      <div class="sb-modal sb-modal-addsummary">
        <div class="transition ui dimmer page modals active visible">
          <div class="ui modal transition active visible normal">
            <!--Header-->
            <div mat-dialog-title class="mb-0">
              <button aria-label="close dialog" (click)="closeDialog()" mat-dialog-close class="mat-close-btn">
                <span>&times;</span>
              </button>
            </div>
            <!--/Header-->
            <!--content-->
            <mat-dialog-content align="left">
              <div class="sb-modal-header">
                {{ resourceService?.frmelmnts?.lbl?.selectFilters }}
              </div>
              <div class="sb-filter mb-10px">
                <div class="sb-filter__container">
                  <div class="sb-filter__content">
                    <div class="sb-filter__content">
                      <app-filter [filterType]="filterType" [selectedFilter]="selectedFilters" [resetFilters]="resetFilters" [hideElements]="hideElements"
                        [filters]="chart.chartConfig.filters" (filterChanged)="filterChanged($event)" [chartData]="
                          chartConfig.id | filterChart: (globalChange ? globalData:chartData):currentFilters
                        " #appFilter>
                      </app-filter>
                    </div>
                  </div>
                </div>
              </div>
            </mat-dialog-content>
            <!--/content-->
            <!--Actions-->
            <mat-dialog-actions align="center" class="mb-0">
              <div class="sb-modal-actions p-0">
                <button (click)="resetForm()" class="sb-btn sb-btn-normal sb-btn-outline-primary" tabindex="0">
                  {{ resourceService?.frmelmnts?.btn?.reset }}
                  {{ resourceService?.frmelmnts?.lbl?.filters }}
                </button>
              </div>
            </mat-dialog-actions>
            <!--/Actions-->
          </div>
        </div>
      </div>
    </ng-template>
  </div>

./sb-chart.component.scss

@use "@project-sunbird/sb-styles/assets/mixins/mixins" as *;

.sb-last-update-status {
  font-size: calculateRem(12px);
  font-weight: bold;
}

.sb-label-name {
  font-size: 1rem;
}

.sb-label-value {
  border-radius: calculateRem(24px);
  padding: calculateRem(7px);
  padding-right: calculateRem(9px);
  padding-left: calculateRem(9px);
  background-color: var(---rc-e9e8d9) !important;
  box-shadow: calculateRem(4px) calculateRem(4px) calculateRem(3px) 0 var(--gray-100) !important;
  color: var(--gray-800);
  margin-bottom: 0.25rem;
  margin-right: 0.25rem;

}

::ng-deep {
  .sb-filter__content {
    .sb-prominent-filter-field {
      width: 48%;
      margin-bottom: calculateRem(10px);
    }
}
  .sb-filter-modal {
    @include respond-below(sm) {
      .ui.modal {
        margin: 0 0 0 0;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        width: 100%;
      }

      .ui.modal.scroll {
        position: fixed !important;
        top: 0;
        width: 100%;
        left: 0px;
        right: 0px;
        margin: 0px !important;
      }
    }
  }

  .mat-dialog-container {
    background-color: var(--rc-e9e8d9) !important;
    border-radius: calculateRem(24px);
  }

  .customGraph {
    .sb-filter-g__item {
      border-radius: 1.5rem !important;
    }

    .multiselect-dropdown .dropdown-btn {
      border-radius: 1.5rem !important;
    }
  }

  .bigNumberCard {
    border-bottom: 0.0625rem solid var(--rc-dddddd) !important;
    display: grid !important;
    grid-template-columns: 1fr 1fr 1fr !important;
    gap: 1.5rem !important;

    sb-dashlet {
      border-right: 0.0625rem solid var(--rc-dddddd) !important;

      &:nth-child(3n + 3) {
        border-right: 0rem solid var(--gray-100) !important;
      }
    }

    .card {
      flex: 1 !important;
      background-color: var(--gray-hs) !important;
      box-shadow: none !important;
      margin-top: 1.5rem !important;

      .header {
        font-size: 1.125rem !important;
        font-weight: unset !important;
      }

      .content {
        padding: 0% !important;
      }

      .description {
        color: var(--gray) !important;
        font-size: 2.5rem !important;
        font-weight: 700 !important;
        margin-top: 0% !important;
      }

      .meta {
        color: var(--gray-200);
        font-size: calculateRem(18px) !important;
      }

    }


  }

  .chart-title {
    font-size: 1rem;
    font-weight: 500;
    margin-bottom: 0.5rem !important;
    padding-top: 0.5rem;
  }
}

.sb-filter {
  &__container {
    width: 100%;
    height: 100vh;
    min-height: calculateRem(400px);
    background-color: var(--rc-e9e8d9) !important;
    padding: calculateRem(24px);
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    position: relative;
    overflow-y: auto;

    @include respond-above(sm) {
      border-radius: calculateRem(8px);
      max-width: calculateRem(1008px);
      height: auto;
    }
  }

  &__header {
    width: 100%;
    text-align: center;
    max-width: calculateRem(328px);


  }

  &__content {
    width: calculateRem(648px);
    max-width: 100%;
    margin-bottom: auto;
  }

  &__footer {
    margin-top: calculateRem(16px);
    width: 100%;
    text-align: center;

    @include respond-above(sm) {
      max-width: 80%;
    }
  }
}

Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""