From 4afed2367416e46d19ccfca8be66e91ee578a042 Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sat, 15 Jun 2024 10:02:13 +0500 Subject: [PATCH 1/9] Added component --- package.json | 1 + src/app/components/navbar/navbar.component.ts | 7 +- src/app/models/salaries/salary.model.ts | 17 +-- .../historical-charts-page.component.html | 20 ++++ .../historical-charts-page.component.scss | 8 ++ .../historical-charts-page.component.spec.ts | 33 ++++++ .../historical-charts-page.component.ts | 110 ++++++++++++++++++ .../predefined-info-block.component.ts | 2 +- .../salaries-adding-chart.component.ts | 2 +- .../salaries-chart.component.ts | 4 +- .../salary-chart-global-filters.component.ts | 2 +- .../salaries-paginated-table.component.ts | 2 +- .../global-filters-form-group.ts | 1 - .../salaries-activated-route.ts | 2 +- .../salaries/salaries-routing.module.ts | 5 + src/app/modules/salaries/salaries.module.ts | 2 + src/app/services/historical-charts.service.ts | 59 ++++++++++ src/app/services/index.ts | 2 + 18 files changed, 263 insertions(+), 16 deletions(-) create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.scss create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.spec.ts create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts rename src/app/modules/salaries/components/{salaries-chart/salary-chart-global-filters => shared}/global-filters-form-group.ts (96%) rename src/app/modules/salaries/components/{salaries-chart => shared}/salaries-activated-route.ts (96%) create mode 100644 src/app/services/historical-charts.service.ts diff --git a/package.json b/package.json index 355e950e..b7882f1c 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "start": "ng serve -o", "build": "ng build", "build-prod": "ng build --configuration=production", + "serve-prod": "ng serve --configuration=production", "serve-staging": "ng serve --configuration=staging -o", "watch": "ng build --watch --configuration development", "test": "ng test", diff --git a/src/app/components/navbar/navbar.component.ts b/src/app/components/navbar/navbar.component.ts index 1cd590e6..12f3236b 100644 --- a/src/app/components/navbar/navbar.component.ts +++ b/src/app/components/navbar/navbar.component.ts @@ -142,7 +142,12 @@ export class NavbarComponent implements OnInit, OnDestroy { { title: "Опрос о пользе статистики", url: "/salaries/survey", - show: true, + show: hasCurrentUser, + }, + { + title: "Исторические данные", + url: "/salaries/historical-data", + show: hasCurrentUser, }, ], }, diff --git a/src/app/models/salaries/salary.model.ts b/src/app/models/salaries/salary.model.ts index 61c25d45..74e9612e 100644 --- a/src/app/models/salaries/salary.model.ts +++ b/src/app/models/salaries/salary.model.ts @@ -4,18 +4,17 @@ import { Currency } from "./currency"; import { KazakhstanCity } from "./kazakhstan-city"; import { Gender } from "@models/enums/gender.enum"; -export interface UserSalaryAdminDto extends UserSalary { - id: string; - updatedAt: Date | null; -} - -export interface UserSalary { +export interface UserSalarySimple { value: number; quarter: number; year: number; currency: Currency; company: CompanyType; grade: DeveloperGrade | null; + createdAt: Date; +} + +export interface UserSalary extends UserSalarySimple { city: KazakhstanCity | null; gender: Gender | null; age: number | null; @@ -25,5 +24,9 @@ export interface UserSalary { skillId: number | null; workIndustryId: number | null; professionId: number | null; - createdAt: Date; +} + +export interface UserSalaryAdminDto extends UserSalary { + id: string; + updatedAt: Date | null; } diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html new file mode 100644 index 00000000..589a05fb --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html @@ -0,0 +1,20 @@ +Исторические данные + +
+ +
+
+ + + + + +
+
+
+ + +
+ +
+
diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.scss b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.scss new file mode 100644 index 00000000..996b8c75 --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.scss @@ -0,0 +1,8 @@ +.progress-bar { + min-height: 30px; +} + +.progress { + min-height: 30px; + cursor: pointer; +} \ No newline at end of file diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.spec.ts b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.spec.ts new file mode 100644 index 00000000..e99af9bf --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.spec.ts @@ -0,0 +1,33 @@ +import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { + mostUsedImports, + mostUsedServices, + testUtilStubs, +} from "@shared/test-utils"; +import { HistoricalChartsService } from "@services/historical-charts.service"; +import { HistoricalChartsPageComponent } from "./historical-charts-page.component"; + +describe("HistoricalChartsPageComponent", () => { + let component: HistoricalChartsPageComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [HistoricalChartsPageComponent], + imports: [...mostUsedImports], + providers: [...testUtilStubs, ...mostUsedServices, HistoricalChartsService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HistoricalChartsPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts new file mode 100644 index 00000000..8464256d --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts @@ -0,0 +1,110 @@ +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { ActivatedRoute, Router } from "@angular/router"; +import { TitleService } from "@services/title.service"; +import { AuthService } from "@shared/services/auth/auth.service"; +import { CookieService } from "ngx-cookie-service"; +import { untilDestroyed } from "@shared/subscriptions/until-destroyed"; +import { formatNumber } from "@angular/common"; +import { GoogleAnalyticsService } from "ngx-google-analytics"; +import { GetSalariesHistoricalChartResponse, HistoricalChartsService } from "@services/historical-charts.service"; +import { SalariesChartActivatedRoute } from "../shared/salaries-activated-route"; +import { SalaryChartGlobalFiltersData } from "../shared/global-filters-form-group"; +import { UserSalariesService } from "@services/user-salaries.service"; +import { LabelEntityDto } from "@services/label-entity.model"; + +@Component({ + templateUrl: "./historical-charts-page.component.html", + styleUrls: ["./historical-charts-page.component.scss"], +}) +export class HistoricalChartsPageComponent implements OnInit, OnDestroy { + + readonly activatedRoute: SalariesChartActivatedRoute; + + data: GetSalariesHistoricalChartResponse | null = null; + filterData = new SalaryChartGlobalFiltersData(); + isAuthenticated = false; + + skills: Array = []; + industries: Array = []; + professions: Array = []; + private initialLoading = true; + + constructor( + private readonly service: HistoricalChartsService, + private readonly salariesService: UserSalariesService, + private readonly router: Router, + private readonly authService: AuthService, + private readonly cookieService: CookieService, + private readonly titleService: TitleService, + private readonly gtag: GoogleAnalyticsService, + activatedRouteSource: ActivatedRoute + ) { + titleService.setTitle("Опрос о пользе зарплатной статистики"); + this.activatedRoute = new SalariesChartActivatedRoute(activatedRouteSource); + } + + ngOnInit(): void { + if (this.authService.isAuthenticated()) { + + this.activatedRoute + .getQueryParams() + .pipe(untilDestroyed(this)) + .subscribe((x) => { + this.filterData = x; + this.load(this.filterData); + }); + return; + } + + this.cookieService.set("url", this.router.url); + this.authService.login(); + } + + ngOnDestroy(): void { + this.titleService.resetTitle(); + } + + load(data: SalaryChartGlobalFiltersData | null = null): void { + this.data = null; + + const shouldLoadSelectBoxItems = + this.skills.length === 0 || + this.industries.length === 0 || + this.professions. length === 0 || + this.initialLoading; + + if (shouldLoadSelectBoxItems) { + this.salariesService + .selectBoxItems() + .pipe(untilDestroyed(this)) + .subscribe((x) => { + this.skills = x.skills; + this.industries = x.industries; + this.professions = x.professions; + + this.loadChartWithFilter(data); + this.initialLoading = false; + }); + + return; + } + + this.loadChartWithFilter(data); + } + + loadChartWithFilter(data: SalaryChartGlobalFiltersData | null = null): void { + this.service + .salariesChart( + { + grade: data?.grade ?? null, + profsInclude: data?.profsInclude ?? null, + cities: data?.cities ?? null, + } + ) + .pipe(untilDestroyed(this)) + .subscribe((x) => { + this.isAuthenticated = x.hasAuthentication; + this.data = x; + }); + } +} diff --git a/src/app/modules/salaries/components/salaries-chart/predefined-filter-info/predefined-info-block.component.ts b/src/app/modules/salaries/components/salaries-chart/predefined-filter-info/predefined-info-block.component.ts index 74020d2b..6b7db7e9 100644 --- a/src/app/modules/salaries/components/salaries-chart/predefined-filter-info/predefined-info-block.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/predefined-filter-info/predefined-info-block.component.ts @@ -1,5 +1,5 @@ import { Component, Input } from "@angular/core"; -import { SalaryChartGlobalFiltersData } from "../salary-chart-global-filters/global-filters-form-group"; +import { SalaryChartGlobalFiltersData } from "../../shared/global-filters-form-group"; import { LabelEntityDto } from "@services/label-entity.model"; import { KazakhstanCityEnum } from "@models/salaries/kazakhstan-city"; import { DeveloperGrade } from "@models/enums"; diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component.ts b/src/app/modules/salaries/components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component.ts index 68b6ede7..01e4857d 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component.ts @@ -5,7 +5,7 @@ import { } from "@services/user-salaries.service"; import { untilDestroyed } from "@shared/subscriptions/until-destroyed"; import { SalariesAddingChart } from "./salaries-adding-chart"; -import { SalaryChartGlobalFiltersData } from "../salary-chart-global-filters/global-filters-form-group"; +import { SalaryChartGlobalFiltersData } from "../../shared/global-filters-form-group"; @Component({ selector: "app-salaries-adding-chart", diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.ts b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.ts index d4b1a7e1..8c60eda0 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.ts @@ -8,9 +8,9 @@ import { AuthService } from "@shared/services/auth/auth.service"; import { CookieService } from "ngx-cookie-service"; import { StubSalariesChart } from "./stub-salaries-chart"; import { DeveloperGrade } from "@models/enums"; -import { SalaryChartGlobalFiltersData } from "./salary-chart-global-filters/global-filters-form-group"; +import { SalaryChartGlobalFiltersData } from "../shared/global-filters-form-group"; import { GoogleAnalyticsService } from "ngx-google-analytics"; -import { SalariesChartActivatedRoute } from "./salaries-activated-route"; +import { SalariesChartActivatedRoute } from "../shared/salaries-activated-route"; import { ApiBackendAbsoluteUrl, ClipboardCopier, diff --git a/src/app/modules/salaries/components/salaries-chart/salary-chart-global-filters/salary-chart-global-filters.component.ts b/src/app/modules/salaries/components/salaries-chart/salary-chart-global-filters/salary-chart-global-filters.component.ts index aa8ea640..9af43934 100644 --- a/src/app/modules/salaries/components/salaries-chart/salary-chart-global-filters/salary-chart-global-filters.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/salary-chart-global-filters/salary-chart-global-filters.component.ts @@ -2,7 +2,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core"; import { GlobalFiltersFormGroup, SalaryChartGlobalFiltersData, -} from "./global-filters-form-group"; +} from "../../shared/global-filters-form-group"; import { SelectItem } from "@shared/select-boxes/select-item"; import { KazakhstanCity, diff --git a/src/app/modules/salaries/components/salaries-paginated-table/salaries-paginated-table.component.ts b/src/app/modules/salaries/components/salaries-paginated-table/salaries-paginated-table.component.ts index 60336ab4..7a0071a1 100644 --- a/src/app/modules/salaries/components/salaries-paginated-table/salaries-paginated-table.component.ts +++ b/src/app/modules/salaries/components/salaries-paginated-table/salaries-paginated-table.component.ts @@ -5,7 +5,7 @@ import { SelectBoxItemsResponse, UserSalariesService, } from "@services/user-salaries.service"; -import { SalaryChartGlobalFiltersData } from "../salaries-chart/salary-chart-global-filters/global-filters-form-group"; +import { SalaryChartGlobalFiltersData } from "../shared/global-filters-form-group"; import { untilDestroyed } from "@shared/subscriptions/until-destroyed"; import { SalaryTableRow } from "./salary-table-row"; import { LabelEntityDto } from "@services/label-entity.model"; diff --git a/src/app/modules/salaries/components/salaries-chart/salary-chart-global-filters/global-filters-form-group.ts b/src/app/modules/salaries/components/shared/global-filters-form-group.ts similarity index 96% rename from src/app/modules/salaries/components/salaries-chart/salary-chart-global-filters/global-filters-form-group.ts rename to src/app/modules/salaries/components/shared/global-filters-form-group.ts index d3f8f0e8..e19b59fd 100644 --- a/src/app/modules/salaries/components/salaries-chart/salary-chart-global-filters/global-filters-form-group.ts +++ b/src/app/modules/salaries/components/shared/global-filters-form-group.ts @@ -23,7 +23,6 @@ export class SalaryChartGlobalFiltersData { } equals(other: SalaryChartGlobalFiltersData): boolean { - // TODO mgorbatyuk: do more smart check that two arrays are not same return ( this.grade === other.grade && this.cities.length === other.cities.length && diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-activated-route.ts b/src/app/modules/salaries/components/shared/salaries-activated-route.ts similarity index 96% rename from src/app/modules/salaries/components/salaries-chart/salaries-activated-route.ts rename to src/app/modules/salaries/components/shared/salaries-activated-route.ts index 8b1473fd..a5f2b6e0 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-activated-route.ts +++ b/src/app/modules/salaries/components/shared/salaries-activated-route.ts @@ -1,7 +1,7 @@ import { DeveloperGrade } from "@models/enums"; import { ActivatedRouteExtended } from "@shared/routes/activated-route-extended"; import { Observable, map } from "rxjs"; -import { SalaryChartGlobalFiltersData } from "./salary-chart-global-filters/global-filters-form-group"; +import { SalaryChartGlobalFiltersData } from "./global-filters-form-group"; import { ActivatedRoute } from "@angular/router"; import { KazakhstanCity } from "@models/salaries/kazakhstan-city"; diff --git a/src/app/modules/salaries/salaries-routing.module.ts b/src/app/modules/salaries/salaries-routing.module.ts index a0df2abb..3a9aa315 100644 --- a/src/app/modules/salaries/salaries-routing.module.ts +++ b/src/app/modules/salaries/salaries-routing.module.ts @@ -2,6 +2,7 @@ import { NgModule } from "@angular/core"; import { RouterModule, Routes } from "@angular/router"; import { SalariesChartComponent } from "./components/salaries-chart/salaries-chart.component"; import { SalariesSurveyPageComponent } from "./components/salaries-survey-page/salaries-survey-page.component"; +import { HistoricalChartsPageComponent } from "./components/historical-charts-page/historical-charts-page.component"; const routes: Routes = [ { @@ -12,6 +13,10 @@ const routes: Routes = [ path: "survey", component: SalariesSurveyPageComponent, }, + { + path: 'historical-data', + component: HistoricalChartsPageComponent, + }, ]; @NgModule({ diff --git a/src/app/modules/salaries/salaries.module.ts b/src/app/modules/salaries/salaries.module.ts index 7bc54f2e..03a9ec09 100644 --- a/src/app/modules/salaries/salaries.module.ts +++ b/src/app/modules/salaries/salaries.module.ts @@ -27,6 +27,7 @@ import { SalariesSurveyBlockComponent } from "./components/salaries-survey-block import { SalariesSurveyPageComponent } from "./components/salaries-survey-page/salaries-survey-page.component"; import { SalariesAddingChartComponent } from "./components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component"; import { CurrencySelectBoxComponent } from "./components/salaries-chart/currency-select-box/currency-select-box.component"; +import { HistoricalChartsPageComponent } from "./components/historical-charts-page/historical-charts-page.component"; @NgModule({ declarations: [ @@ -54,6 +55,7 @@ import { CurrencySelectBoxComponent } from "./components/salaries-chart/currency SalariesSurveyPageComponent, SalariesAddingChartComponent, CurrencySelectBoxComponent, + HistoricalChartsPageComponent, ], imports: [ CommonModule, diff --git a/src/app/services/historical-charts.service.ts b/src/app/services/historical-charts.service.ts new file mode 100644 index 00000000..a3e8df68 --- /dev/null +++ b/src/app/services/historical-charts.service.ts @@ -0,0 +1,59 @@ +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { ApiService } from "./api.service"; +import { ConvertObjectToHttpParams } from "@shared/value-objects/convert-object-to-http"; +import { DeveloperGrade } from "@models/enums"; +import { KazakhstanCity } from "@models/salaries/kazakhstan-city"; +import { UserSalary, UserSalarySimple } from "@models/salaries/salary.model"; + +export interface SalariesCountWeekByWeekChartItem { + totalCount: number; + localMedian: number, + localAverage: number, + remoteMedian: number, + remoteAverage: number, +} + +export interface SalariesCountWeekByWeekChartGradeItem extends SalariesCountWeekByWeekChartItem { + grade: DeveloperGrade; +} + +export interface SalariesCountWeekByWeekChart { + weekEnds: Array; + totalCountItems: Array; + grades: Array; +} + +export interface GetSalariesHistoricalChartResponse { + salaries: Array; + + from: Date; + to: Date; + chartFrom: Date; + chartTo: Date; + + hasAuthentication: boolean; + shouldAddOwnSalary: boolean; + + salariesCountWeekByWeekChart: SalariesCountWeekByWeekChart | null; +} + +export interface SalariesChartFilterData { + grade: DeveloperGrade | null; + profsInclude: Array | null; + cities: Array | null; +} + +@Injectable() +export class HistoricalChartsService { + private readonly apiUrl: string; + + constructor(private readonly api: ApiService) { + this.apiUrl = `/api/historical-charts/`; + } + + salariesChart(params: SalariesChartFilterData): Observable { + return this.api.get( + this.apiUrl + 'salaries?' + new ConvertObjectToHttpParams(params).get()); + } +} diff --git a/src/app/services/index.ts b/src/app/services/index.ts index 52721b51..20f247c9 100644 --- a/src/app/services/index.ts +++ b/src/app/services/index.ts @@ -17,6 +17,7 @@ import { TelegramBotService } from "./telegram-bot.service"; import { SurveyService } from "./salaries-survey.service"; import { MetaTagService } from "./meta-tags.service"; import { AdminToolsService } from "./admin-tools.service"; +import { HistoricalChartsService } from "./historical-charts.service"; export * from "./authorization.service"; export * from "./api.service"; @@ -48,4 +49,5 @@ export const applicationServices = [ SurveyService, MetaTagService, AdminToolsService, + HistoricalChartsService, ]; From 75e4b40e19770affcaa0e6ea3e3e8222156c2307 Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sat, 15 Jun 2024 10:03:54 +0500 Subject: [PATCH 2/9] Removed unnecessary prop --- src/app/services/historical-charts.service.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/app/services/historical-charts.service.ts b/src/app/services/historical-charts.service.ts index a3e8df68..d1f01f9a 100644 --- a/src/app/services/historical-charts.service.ts +++ b/src/app/services/historical-charts.service.ts @@ -4,7 +4,6 @@ import { ApiService } from "./api.service"; import { ConvertObjectToHttpParams } from "@shared/value-objects/convert-object-to-http"; import { DeveloperGrade } from "@models/enums"; import { KazakhstanCity } from "@models/salaries/kazakhstan-city"; -import { UserSalary, UserSalarySimple } from "@models/salaries/salary.model"; export interface SalariesCountWeekByWeekChartItem { totalCount: number; @@ -25,8 +24,6 @@ export interface SalariesCountWeekByWeekChart { } export interface GetSalariesHistoricalChartResponse { - salaries: Array; - from: Date; to: Date; chartFrom: Date; From 15b53c3c0e205ad80c904ecd5fcfb23f1177ba40 Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sat, 15 Jun 2024 10:04:59 +0500 Subject: [PATCH 3/9] Added cached data --- data.json | 816 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 816 insertions(+) create mode 100644 data.json diff --git a/data.json b/data.json new file mode 100644 index 00000000..8215f9fc --- /dev/null +++ b/data.json @@ -0,0 +1,816 @@ +{ + "salariesCountWeekByWeekChart": { + "weekEnds": [ + "2024-02-03T05:00:10.5964449", + "2024-02-10T05:00:10.5964449", + "2024-02-17T05:00:10.5964449", + "2024-02-24T05:00:10.5964449", + "2024-03-02T05:00:10.5964449", + "2024-03-09T05:00:10.5964449", + "2024-03-16T05:00:10.5964449", + "2024-03-23T05:00:10.5964449", + "2024-03-30T05:00:10.5964449", + "2024-04-06T05:00:10.5964449", + "2024-04-13T05:00:10.5964449", + "2024-04-20T05:00:10.5964449", + "2024-04-27T05:00:10.5964449", + "2024-05-04T05:00:10.5964449", + "2024-05-11T05:00:10.5964449", + "2024-05-18T05:00:10.5964449", + "2024-05-25T05:00:10.5964449", + "2024-06-01T05:00:10.5964449", + "2024-06-08T05:00:10.5964449", + "2024-06-15T05:00:10.5964449" + ], + "totalCountItems": [ + { + "totalCount": 641, + "localMedian": 700000, + "localAverage": 794265.146484375, + "remoteMedian": 1400000, + "remoteAverage": 1443414.9302325582 + }, + { + "totalCount": 701, + "localMedian": 700000, + "localAverage": 787367.8914590747, + "remoteMedian": 1470000, + "remoteAverage": 1469098.0287769784 + }, + { + "totalCount": 726, + "localMedian": 700000, + "localAverage": 788989.2881646656, + "remoteMedian": 1470000, + "remoteAverage": 1480102.2797202796 + }, + { + "totalCount": 759, + "localMedian": 700000, + "localAverage": 800337.3032786886, + "remoteMedian": 1480000, + "remoteAverage": 1485601.5167785236 + }, + { + "totalCount": 772, + "localMedian": 700000, + "localAverage": 802770.0722311396, + "remoteMedian": 1480000, + "remoteAverage": 1485601.5167785236 + }, + { + "totalCount": 782, + "localMedian": 700000, + "localAverage": 806797.7027027027, + "remoteMedian": 1500000, + "remoteAverage": 1483494.2875816994 + }, + { + "totalCount": 928, + "localMedian": 700000, + "localAverage": 803129.6485411141, + "remoteMedian": 1435000, + "remoteAverage": 1479750.7241379311 + }, + { + "totalCount": 978, + "localMedian": 700000, + "localAverage": 810782.6503759399, + "remoteMedian": 1435000, + "remoteAverage": 1480154.9333333333 + }, + { + "totalCount": 1017, + "localMedian": 700000, + "localAverage": 815091.6826347306, + "remoteMedian": 1425000, + "remoteAverage": 1472528.076923077 + }, + { + "totalCount": 1041, + "localMedian": 700000, + "localAverage": 815573.5764294049, + "remoteMedian": 1460000, + "remoteAverage": 1477533.206521739 + }, + { + "totalCount": 1085, + "localMedian": 700000, + "localAverage": 808815.762806236, + "remoteMedian": 1470000, + "remoteAverage": 1519070.1069518717 + }, + { + "totalCount": 1173, + "localMedian": 700000, + "localAverage": 810014.9742798354, + "remoteMedian": 1400000, + "remoteAverage": 1496348.8059701493 + }, + { + "totalCount": 1210, + "localMedian": 700000, + "localAverage": 809258.8138138138, + "remoteMedian": 1400000, + "remoteAverage": 1505745.0663507108 + }, + { + "totalCount": 1265, + "localMedian": 700000, + "localAverage": 802990.9443911792, + "remoteMedian": 1366306.5, + "remoteAverage": 1478410.8513513512 + }, + { + "totalCount": 1296, + "localMedian": 700000, + "localAverage": 807915.2343017807, + "remoteMedian": 1377000, + "remoteAverage": 1478810.9475982534 + }, + { + "totalCount": 1306, + "localMedian": 700000, + "localAverage": 807396.0584958218, + "remoteMedian": 1377000, + "remoteAverage": 1478810.9475982534 + }, + { + "totalCount": 1345, + "localMedian": 700000, + "localAverage": 806082.8141831239, + "remoteMedian": 1377000, + "remoteAverage": 1476418.6450216451 + }, + { + "totalCount": 1428, + "localMedian": 700000, + "localAverage": 807632.0598146588, + "remoteMedian": 1355613, + "remoteAverage": 1472709.9958506224 + }, + { + "totalCount": 1484, + "localMedian": 700000, + "localAverage": 807066.872874494, + "remoteMedian": 1355613, + "remoteAverage": 1481016.502008032 + }, + { + "totalCount": 1697, + "localMedian": 700000, + "localAverage": 825096.4335465529, + "remoteMedian": 1400000, + "remoteAverage": 1489812.1103448276 + } + ], + "gradeItems": [ + { + "grade": 2, + "totalCount": 172, + "localMedian": 350000, + "localAverage": 358982.0512820513, + "remoteMedian": 375000, + "remoteAverage": 657789.5625 + }, + { + "grade": 5, + "totalCount": 283, + "localMedian": 718500, + "localAverage": 775343.75, + "remoteMedian": 1100000, + "remoteAverage": 1187634.4237288137 + }, + { + "grade": 8, + "totalCount": 121, + "localMedian": 1300000, + "localAverage": 1268116.524390244, + "remoteMedian": 2000000, + "remoteAverage": 2006921.8461538462 + }, + { + "grade": 11, + "totalCount": 55, + "localMedian": 1600000, + "localAverage": 1559767.441860465, + "remoteMedian": 1625000, + "remoteAverage": 1958792.5 + }, + { + "grade": 2, + "totalCount": 190, + "localMedian": 345000, + "localAverage": 355524.1379310345, + "remoteMedian": 375000, + "remoteAverage": 657789.5625 + }, + { + "grade": 5, + "totalCount": 307, + "localMedian": 725000, + "localAverage": 775526.5306122449, + "remoteMedian": 1100000, + "remoteAverage": 1194684.3709677418 + }, + { + "grade": 8, + "totalCount": 127, + "localMedian": 1275000, + "localAverage": 1259351.8452380951, + "remoteMedian": 2000000, + "remoteAverage": 2010559.3488372094 + }, + { + "grade": 11, + "totalCount": 67, + "localMedian": 1500000, + "localAverage": 1517692.3076923077, + "remoteMedian": 1650000, + "remoteAverage": 1955034 + }, + { + "grade": 2, + "totalCount": 197, + "localMedian": 340000, + "localAverage": 354395.55555555556, + "remoteMedian": 400000, + "remoteAverage": 663213.7058823529 + }, + { + "grade": 5, + "totalCount": 316, + "localMedian": 745000, + "localAverage": 777644.2687747036, + "remoteMedian": 1100000, + "remoteAverage": 1193181.4444444445 + }, + { + "grade": 8, + "totalCount": 134, + "localMedian": 1225000, + "localAverage": 1249950.611111111, + "remoteMedian": 2000000, + "remoteAverage": 2019410.2727272727 + }, + { + "grade": 11, + "totalCount": 69, + "localMedian": 1500000, + "localAverage": 1528679.2452830188, + "remoteMedian": 1825000, + "remoteAverage": 2032844.375 + }, + { + "grade": 2, + "totalCount": 205, + "localMedian": 330000, + "localAverage": 353984.94623655913, + "remoteMedian": 400000, + "remoteAverage": 635507 + }, + { + "grade": 5, + "totalCount": 325, + "localMedian": 720000, + "localAverage": 777839.6946564886, + "remoteMedian": 1100000, + "remoteAverage": 1193181.4444444445 + }, + { + "grade": 8, + "totalCount": 145, + "localMedian": 1250000, + "localAverage": 1270914.696969697, + "remoteMedian": 1950000, + "remoteAverage": 2001175.043478261 + }, + { + "grade": 11, + "totalCount": 74, + "localMedian": 1625000, + "localAverage": 1550357.142857143, + "remoteMedian": 2000000, + "remoteAverage": 2123639.4444444445 + }, + { + "grade": 2, + "totalCount": 210, + "localMedian": 330000, + "localAverage": 353200, + "remoteMedian": 400000, + "remoteAverage": 635507 + }, + { + "grade": 5, + "totalCount": 330, + "localMedian": 725000, + "localAverage": 778629.213483146, + "remoteMedian": 1100000, + "remoteAverage": 1193181.4444444445 + }, + { + "grade": 8, + "totalCount": 147, + "localMedian": 1300000, + "localAverage": 1290302.5247524753, + "remoteMedian": 1950000, + "remoteAverage": 2001175.043478261 + }, + { + "grade": 11, + "totalCount": 75, + "localMedian": 1650000, + "localAverage": 1552982.4561403508, + "remoteMedian": 2000000, + "remoteAverage": 2123639.4444444445 + }, + { + "grade": 2, + "totalCount": 210, + "localMedian": 330000, + "localAverage": 353200, + "remoteMedian": 400000, + "remoteAverage": 635507 + }, + { + "grade": 5, + "totalCount": 336, + "localMedian": 750000, + "localAverage": 783372.6937269373, + "remoteMedian": 1100000, + "remoteAverage": 1202622.0153846154 + }, + { + "grade": 8, + "totalCount": 150, + "localMedian": 1300000, + "localAverage": 1293888.8834951457, + "remoteMedian": 1900000, + "remoteAverage": 1997320.255319149 + }, + { + "grade": 11, + "totalCount": 76, + "localMedian": 1650000, + "localAverage": 1552982.4561403508, + "remoteMedian": 2000000, + "remoteAverage": 2053974.2105263157 + }, + { + "grade": 2, + "totalCount": 249, + "localMedian": 320000, + "localAverage": 351537.9912663755, + "remoteMedian": 375000, + "remoteAverage": 618731.65 + }, + { + "grade": 5, + "totalCount": 401, + "localMedian": 750000, + "localAverage": 776779.8165137614, + "remoteMedian": 1100000, + "remoteAverage": 1185654.472972973 + }, + { + "grade": 8, + "totalCount": 179, + "localMedian": 1300000, + "localAverage": 1277321.5853658537, + "remoteMedian": 1900000, + "remoteAverage": 2001572.357142857 + }, + { + "grade": 11, + "totalCount": 89, + "localMedian": 1675000, + "localAverage": 1588382.3529411764, + "remoteMedian": 2000000, + "remoteAverage": 1973595.7142857143 + }, + { + "grade": 2, + "totalCount": 260, + "localMedian": 300000, + "localAverage": 349800.8333333333, + "remoteMedian": 375000, + "remoteAverage": 618731.65 + }, + { + "grade": 5, + "totalCount": 426, + "localMedian": 750000, + "localAverage": 774361.0315186246, + "remoteMedian": 1100000, + "remoteAverage": 1195953.6493506494 + }, + { + "grade": 8, + "totalCount": 187, + "localMedian": 1300000, + "localAverage": 1279345.3875968992, + "remoteMedian": 1900000, + "remoteAverage": 1996367.4827586208 + }, + { + "grade": 11, + "totalCount": 95, + "localMedian": 1600000, + "localAverage": 1668969.8630136987, + "remoteMedian": 1825000, + "remoteAverage": 1924795.9090909092 + }, + { + "grade": 2, + "totalCount": 269, + "localMedian": 300000, + "localAverage": 347428.22580645164, + "remoteMedian": 350000, + "remoteAverage": 595088.3333333334 + }, + { + "grade": 5, + "totalCount": 443, + "localMedian": 745000, + "localAverage": 773641.095890411, + "remoteMedian": 1100000, + "remoteAverage": 1199210.6538461538 + }, + { + "grade": 8, + "totalCount": 194, + "localMedian": 1300000, + "localAverage": 1286658.4926470588, + "remoteMedian": 1900000, + "remoteAverage": 1996367.4827586208 + }, + { + "grade": 11, + "totalCount": 101, + "localMedian": 1590000, + "localAverage": 1660060.759493671, + "remoteMedian": 1825000, + "remoteAverage": 1924795.9090909092 + }, + { + "grade": 2, + "totalCount": 279, + "localMedian": 310000, + "localAverage": 350570.54263565893, + "remoteMedian": 350000, + "remoteAverage": 595088.3333333334 + }, + { + "grade": 5, + "totalCount": 450, + "localMedian": 720000, + "localAverage": 774002.6881720431, + "remoteMedian": 1100000, + "remoteAverage": 1199210.6538461538 + }, + { + "grade": 8, + "totalCount": 196, + "localMedian": 1300000, + "localAverage": 1278880.8333333333, + "remoteMedian": 1900000, + "remoteAverage": 1996367.4827586208 + }, + { + "grade": 11, + "totalCount": 106, + "localMedian": 1625000, + "localAverage": 1684814.6341463414, + "remoteMedian": 1825000, + "remoteAverage": 1925479.5833333333 + }, + { + "grade": 2, + "totalCount": 291, + "localMedian": 325000, + "localAverage": 352315.55555555556, + "remoteMedian": 350000, + "remoteAverage": 595088.3333333334 + }, + { + "grade": 5, + "totalCount": 473, + "localMedian": 700000, + "localAverage": 764989.8218829517, + "remoteMedian": 1100000, + "remoteAverage": 1206730.3875 + }, + { + "grade": 8, + "totalCount": 200, + "localMedian": 1300000, + "localAverage": 1275784.0780141845, + "remoteMedian": 1900000, + "remoteAverage": 2118462.9491525423 + }, + { + "grade": 11, + "totalCount": 111, + "localMedian": 1590000, + "localAverage": 1663618.3908045976, + "remoteMedian": 1825000, + "remoteAverage": 1925479.5833333333 + }, + { + "grade": 2, + "totalCount": 317, + "localMedian": 325000, + "localAverage": 352911.6438356164, + "remoteMedian": 350000, + "remoteAverage": 591874.2 + }, + { + "grade": 5, + "totalCount": 509, + "localMedian": 700000, + "localAverage": 764011.8483412323, + "remoteMedian": 1100000, + "remoteAverage": 1206188.8620689656 + }, + { + "grade": 8, + "totalCount": 220, + "localMedian": 1200000, + "localAverage": 1277889.5886075948, + "remoteMedian": 1950000, + "remoteAverage": 2112730.870967742 + }, + { + "grade": 11, + "totalCount": 117, + "localMedian": 1590000, + "localAverage": 1656288.1720430108, + "remoteMedian": 1825000, + "remoteAverage": 1925479.5833333333 + }, + { + "grade": 2, + "totalCount": 327, + "localMedian": 335000, + "localAverage": 355960.9271523179, + "remoteMedian": 350000, + "remoteAverage": 591874.2 + }, + { + "grade": 5, + "totalCount": 523, + "localMedian": 700000, + "localAverage": 761928.2407407408, + "remoteMedian": 1100000, + "remoteAverage": 1202795.7802197803 + }, + { + "grade": 8, + "totalCount": 226, + "localMedian": 1200000, + "localAverage": 1275661.8322981365, + "remoteMedian": 1900000, + "remoteAverage": 2108481.7538461536 + }, + { + "grade": 11, + "totalCount": 124, + "localMedian": 1590000, + "localAverage": 1654482.4742268042, + "remoteMedian": 2000000, + "remoteAverage": 1947393.4814814816 + }, + { + "grade": 2, + "totalCount": 343, + "localMedian": 327500, + "localAverage": 354921.01910828025, + "remoteMedian": 350000, + "remoteAverage": 576788.1034482758 + }, + { + "grade": 5, + "totalCount": 542, + "localMedian": 700000, + "localAverage": 754671.875, + "remoteMedian": 1100000, + "remoteAverage": 1203929.9574468085 + }, + { + "grade": 8, + "totalCount": 239, + "localMedian": 1200000, + "localAverage": 1252597.3823529412, + "remoteMedian": 1900000, + "remoteAverage": 2056540.7826086956 + }, + { + "grade": 11, + "totalCount": 130, + "localMedian": 1500000, + "localAverage": 1641114.563106796, + "remoteMedian": 2000000, + "remoteAverage": 1947393.4814814816 + }, + { + "grade": 2, + "totalCount": 348, + "localMedian": 330000, + "localAverage": 356066.4576802508, + "remoteMedian": 350000, + "remoteAverage": 576788.1034482758 + }, + { + "grade": 5, + "totalCount": 551, + "localMedian": 700000, + "localAverage": 756121.1453744493, + "remoteMedian": 1100000, + "remoteAverage": 1204741.381443299 + }, + { + "grade": 8, + "totalCount": 252, + "localMedian": 1200000, + "localAverage": 1260399.7486033519, + "remoteMedian": 1862000, + "remoteAverage": 2036319.3698630137 + }, + { + "grade": 11, + "totalCount": 133, + "localMedian": 1545000, + "localAverage": 1636649.0566037735, + "remoteMedian": 2000000, + "remoteAverage": 1947393.4814814816 + }, + { + "grade": 2, + "totalCount": 349, + "localMedian": 330000, + "localAverage": 356360, + "remoteMedian": 350000, + "remoteAverage": 576788.1034482758 + }, + { + "grade": 5, + "totalCount": 559, + "localMedian": 700000, + "localAverage": 754435.064935065, + "remoteMedian": 1100000, + "remoteAverage": 1204741.381443299 + }, + { + "grade": 8, + "totalCount": 252, + "localMedian": 1200000, + "localAverage": 1260399.7486033519, + "remoteMedian": 1862000, + "remoteAverage": 2036319.3698630137 + }, + { + "grade": 11, + "totalCount": 134, + "localMedian": 1590000, + "localAverage": 1638175.7009345794, + "remoteMedian": 2000000, + "remoteAverage": 1947393.4814814816 + }, + { + "grade": 2, + "totalCount": 362, + "localMedian": 330000, + "localAverage": 357421.021021021, + "remoteMedian": 350000, + "remoteAverage": 576788.1034482758 + }, + { + "grade": 5, + "totalCount": 574, + "localMedian": 700000, + "localAverage": 757759.8739495798, + "remoteMedian": 1100000, + "remoteAverage": 1200152.1836734693 + }, + { + "grade": 8, + "totalCount": 256, + "localMedian": 1200000, + "localAverage": 1260118.434065934, + "remoteMedian": 1841000, + "remoteAverage": 2031098.8378378379 + }, + { + "grade": 11, + "totalCount": 139, + "localMedian": 1555000, + "localAverage": 1629953.5714285714, + "remoteMedian": 2000000, + "remoteAverage": 1947393.4814814816 + }, + { + "grade": 2, + "totalCount": 384, + "localMedian": 330000, + "localAverage": 360850.8474576271, + "remoteMedian": 350000, + "remoteAverage": 573561.8333333334 + }, + { + "grade": 5, + "totalCount": 613, + "localMedian": 700000, + "localAverage": 758946.3654223968, + "remoteMedian": 1100000, + "remoteAverage": 1193316.4807692308 + }, + { + "grade": 8, + "totalCount": 267, + "localMedian": 1200000, + "localAverage": 1264607.0572916667, + "remoteMedian": 1820000, + "remoteAverage": 2026350.8533333333 + }, + { + "grade": 11, + "totalCount": 149, + "localMedian": 1565000, + "localAverage": 1627456.6666666667, + "remoteMedian": 2000000, + "remoteAverage": 1993276.7586206896 + }, + { + "grade": 2, + "totalCount": 399, + "localMedian": 322500, + "localAverage": 360514.1304347826, + "remoteMedian": 350000, + "remoteAverage": 582801.7741935484 + }, + { + "grade": 5, + "totalCount": 634, + "localMedian": 700000, + "localAverage": 758683.7429111531, + "remoteMedian": 1100000, + "remoteAverage": 1188046.8 + }, + { + "grade": 8, + "totalCount": 279, + "localMedian": 1200000, + "localAverage": 1263669.4278606966, + "remoteMedian": 1810000, + "remoteAverage": 2029183.5128205128 + }, + { + "grade": 11, + "totalCount": 153, + "localMedian": 1600000, + "localAverage": 1641421.138211382, + "remoteMedian": 2000000, + "remoteAverage": 2110167.533333333 + }, + { + "grade": 2, + "totalCount": 431, + "localMedian": 330000, + "localAverage": 361275.75757575757, + "remoteMedian": 350000, + "remoteAverage": 564195.8571428572 + }, + { + "grade": 5, + "totalCount": 725, + "localMedian": 715000, + "localAverage": 768454.355848435, + "remoteMedian": 1125000, + "remoteAverage": 1202004.2542372881 + }, + { + "grade": 8, + "totalCount": 337, + "localMedian": 1200000, + "localAverage": 1266964.8125, + "remoteMedian": 1800000, + "remoteAverage": 1997724.8865979381 + }, + { + "grade": 11, + "totalCount": 182, + "localMedian": 1565000, + "localAverage": 1623816.2162162163, + "remoteMedian": 2000000, + "remoteAverage": 2114789.4411764704 + } + ] + }, + "shouldAddOwnSalary": false, + "hasAuthentication": true, + "from": "2023-06-15T05:00:10.5964449+00:00", + "to": "2024-06-15T05:00:10.5964449+00:00", + "chartFrom": "0001-01-01T00:00:00+00:00", + "chartTo": "0001-01-01T00:00:00+00:00" +} \ No newline at end of file From 38553f3a411196a2721b3f0997b9fd111c33aff8 Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sat, 15 Jun 2024 10:42:38 +0500 Subject: [PATCH 4/9] Added first chart --- .../historical-charts-page.component.html | 18 +++- .../historical-charts-page.component.scss | 12 +-- .../historical-charts-page.component.ts | 45 ++++++++++ .../historical-charts-page.component.spec.ts | 32 ++++++++ .../historical-charts-page.component.ts | 28 +++++++ .../historical-salaries-chart-object.ts | 82 +++++++++++++++++++ .../historical-salaries-chart.component.html | 3 + .../historical-salaries-chart.component.scss | 10 +++ .../salaries-chart.component.html | 2 +- src/app/modules/salaries/salaries.module.ts | 2 + 10 files changed, 225 insertions(+), 9 deletions(-) create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.spec.ts create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.html create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html index 589a05fb..5041ed00 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html @@ -4,11 +4,23 @@
- - - +
+ + +
+
+ +
diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.scss b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.scss index 996b8c75..96d0d31d 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.scss +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.scss @@ -1,8 +1,10 @@ -.progress-bar { - min-height: 30px; +#canvas-historical-chart { + min-height: 400px; } -.progress { - min-height: 30px; - cursor: pointer; +#canvas-historical-chart-container { + position: relative; + width: 100%; + height: 100%; + min-height: 400px; } \ No newline at end of file diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts index 8464256d..2159e8a6 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts @@ -11,6 +11,9 @@ import { SalariesChartActivatedRoute } from "../shared/salaries-activated-route" import { SalaryChartGlobalFiltersData } from "../shared/global-filters-form-group"; import { UserSalariesService } from "@services/user-salaries.service"; import { LabelEntityDto } from "@services/label-entity.model"; +import { DeveloperGrade } from "@models/enums"; +import { ApiBackendAbsoluteUrl, ClipboardCopier } from "@shared/value-objects/clipboard-copier"; +import { ConvertObjectToHttpParams } from "@shared/value-objects/convert-object-to-http"; @Component({ templateUrl: "./historical-charts-page.component.html", @@ -64,6 +67,47 @@ export class HistoricalChartsPageComponent implements OnInit, OnDestroy { this.titleService.resetTitle(); } + applyGlobalFilters(data: SalaryChartGlobalFiltersData): void { + if (this.filterData.equals(data)) { + return; + } + + this.filterData = data; + const selectedGrade = data.grade ? DeveloperGrade[data.grade] : "empty"; + this.gtag.event("salaries_filters_applied", "historical_data", selectedGrade); + this.load(data); + } + + resetGlobalFilters(): void { + const newFilterData = new SalaryChartGlobalFiltersData(); + if (this.filterData.equals(newFilterData)) { + return; + } + + this.filterData = newFilterData; + this.gtag.event("salaries_filters_reset", "historical_data"); + + if (this.router.url.indexOf("?") > 0) { + this.router.navigateByUrl( + this.router.url.substring(0, this.router.url.indexOf("?")) + ); + return; + } + + this.load(); + } + + share(data: SalaryChartGlobalFiltersData): void { + this.filterData = data; + this.gtag.event("salaries_share_clicked", "historical_data"); + + const currentUrl = new ApiBackendAbsoluteUrl("/chart-share").asString(); + const shareUrl = `${currentUrl}?${new ConvertObjectToHttpParams( + this.filterData + ).get()}`; + new ClipboardCopier(shareUrl).execute(); + } + load(data: SalaryChartGlobalFiltersData | null = null): void { this.data = null; @@ -105,6 +149,7 @@ export class HistoricalChartsPageComponent implements OnInit, OnDestroy { .subscribe((x) => { this.isAuthenticated = x.hasAuthentication; this.data = x; + console.log(this.data); }); } } diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.spec.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.spec.ts new file mode 100644 index 00000000..c3b80f7c --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.spec.ts @@ -0,0 +1,32 @@ +import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { + mostUsedImports, + mostUsedServices, + testUtilStubs, +} from "@shared/test-utils"; +import { HistoricalSalariesChartComponent } from "./historical-charts-page.component"; + +describe("HistoricalSalariesChartComponent", () => { + let component: HistoricalSalariesChartComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [HistoricalSalariesChartComponent], + imports: [...mostUsedImports], + providers: [...testUtilStubs, ...mostUsedServices], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HistoricalSalariesChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts new file mode 100644 index 00000000..9606cc6a --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts @@ -0,0 +1,28 @@ +import { Component, Input, OnInit } from "@angular/core"; +import { SalariesCountWeekByWeekChart } from "@services/historical-charts.service"; +import { HistoricalSalariesChartObject } from "./historical-salaries-chart-object"; + +@Component({ + selector: "app-historical-salaries-chart", + templateUrl: "./historical-salaries-chart.component.html", + styleUrls: ["./historical-salaries-chart.component.scss"], +}) +export class HistoricalSalariesChartComponent implements OnInit { + + @Input() + data: SalariesCountWeekByWeekChart | null = null; + + chart: HistoricalSalariesChartObject | null = null; + + ngOnInit(): void { + + console.log(this.data); + if (this.data == null) { + return; + } + + this.chart = new HistoricalSalariesChartObject( + "canvas-historical-chart", + this.data); + } +} diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts new file mode 100644 index 00000000..d22aa93e --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts @@ -0,0 +1,82 @@ +import { SalariesCountWeekByWeekChart } from "@services/historical-charts.service"; +import { Chart, ChartType, PointStyle } from "chart.js/auto"; +import { RandomRgbColor } from "../../random-rgb-color"; + +interface ChartDatasetType { + label: string; + data: Array; + borderWidth: number; + borderColor: string; + backgroundColor: string; + pointStyle: PointStyle; + yAxisID: 'y' | 'y1', +} + +export class HistoricalSalariesChartObject extends Chart { + private readonly datasets: Array = []; + + constructor(canvasId: string, chartData: SalariesCountWeekByWeekChart) { + const randomColor = new RandomRgbColor(); + + // По датасету на медиану и среднюю + const datasets: Array = [ + { + label: "Все анкеты", + data: [], + borderWidth: 1, + borderColor: randomColor.toString(1), + backgroundColor: randomColor.toString(0.5), + pointStyle: false as PointStyle, + yAxisID: 'y', + }, + { + label: "Количество анкет", + data: chartData.totalCountItems.map(x => x.totalCount), + borderWidth: 1, + borderColor: randomColor.toString(1), + backgroundColor: randomColor.toString(0.5), + pointStyle: false as PointStyle, + yAxisID: 'y1', + }, + ]; + + super(canvasId, { + type: "line" as ChartType, + data: { + labels: chartData + .weekEnds + .map((x) => x.toISOString().slice(0, 10)), + datasets: datasets, + }, + options: { + responsive: true, + maintainAspectRatio: false, + scales: { + y: { + beginAtZero: true, + position: 'left', + }, + y1: { + beginAtZero: true, + position: 'right', + } + }, + elements: { + line: { + tension: 0.4, + }, + }, + plugins: { + legend: { + position: "bottom", + title: { + position: "start", + }, + }, + }, + }, + }); + + this.datasets = datasets; + } +} diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.html b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.html new file mode 100644 index 00000000..6812e7c1 --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.html @@ -0,0 +1,3 @@ +
+ {{ chart }} +
diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss new file mode 100644 index 00000000..96d0d31d --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss @@ -0,0 +1,10 @@ +#canvas-historical-chart { + min-height: 400px; +} + +#canvas-historical-chart-container { + position: relative; + width: 100%; + height: 100%; + min-height: 400px; +} \ No newline at end of file diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html index 1786f8a4..c3e29477 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html +++ b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html @@ -209,7 +209,7 @@ (filtersReset)="resetGlobalFilters()" (shareClicked)="share($event)" > - > diff --git a/src/app/modules/salaries/salaries.module.ts b/src/app/modules/salaries/salaries.module.ts index 03a9ec09..73cab202 100644 --- a/src/app/modules/salaries/salaries.module.ts +++ b/src/app/modules/salaries/salaries.module.ts @@ -28,6 +28,7 @@ import { SalariesSurveyPageComponent } from "./components/salaries-survey-page/s import { SalariesAddingChartComponent } from "./components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component"; import { CurrencySelectBoxComponent } from "./components/salaries-chart/currency-select-box/currency-select-box.component"; import { HistoricalChartsPageComponent } from "./components/historical-charts-page/historical-charts-page.component"; +import { HistoricalSalariesChartComponent } from "./components/historical-charts-page/historical-salaries-chart/historical-charts-page.component"; @NgModule({ declarations: [ @@ -56,6 +57,7 @@ import { HistoricalChartsPageComponent } from "./components/historical-charts-pa SalariesAddingChartComponent, CurrencySelectBoxComponent, HistoricalChartsPageComponent, + HistoricalSalariesChartComponent ], imports: [ CommonModule, From 936ffb854f8ed29b374efb66fd9a23ed18a325a0 Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sat, 15 Jun 2024 10:52:51 +0500 Subject: [PATCH 5/9] Added datasets --- data.json | 816 ------------------ .../historical-charts-page.component.ts | 1 - .../historical-charts-page.component.ts | 1 - .../historical-salaries-chart-object.ts | 79 +- .../historical-salaries-chart.component.scss | 4 +- 5 files changed, 61 insertions(+), 840 deletions(-) delete mode 100644 data.json diff --git a/data.json b/data.json deleted file mode 100644 index 8215f9fc..00000000 --- a/data.json +++ /dev/null @@ -1,816 +0,0 @@ -{ - "salariesCountWeekByWeekChart": { - "weekEnds": [ - "2024-02-03T05:00:10.5964449", - "2024-02-10T05:00:10.5964449", - "2024-02-17T05:00:10.5964449", - "2024-02-24T05:00:10.5964449", - "2024-03-02T05:00:10.5964449", - "2024-03-09T05:00:10.5964449", - "2024-03-16T05:00:10.5964449", - "2024-03-23T05:00:10.5964449", - "2024-03-30T05:00:10.5964449", - "2024-04-06T05:00:10.5964449", - "2024-04-13T05:00:10.5964449", - "2024-04-20T05:00:10.5964449", - "2024-04-27T05:00:10.5964449", - "2024-05-04T05:00:10.5964449", - "2024-05-11T05:00:10.5964449", - "2024-05-18T05:00:10.5964449", - "2024-05-25T05:00:10.5964449", - "2024-06-01T05:00:10.5964449", - "2024-06-08T05:00:10.5964449", - "2024-06-15T05:00:10.5964449" - ], - "totalCountItems": [ - { - "totalCount": 641, - "localMedian": 700000, - "localAverage": 794265.146484375, - "remoteMedian": 1400000, - "remoteAverage": 1443414.9302325582 - }, - { - "totalCount": 701, - "localMedian": 700000, - "localAverage": 787367.8914590747, - "remoteMedian": 1470000, - "remoteAverage": 1469098.0287769784 - }, - { - "totalCount": 726, - "localMedian": 700000, - "localAverage": 788989.2881646656, - "remoteMedian": 1470000, - "remoteAverage": 1480102.2797202796 - }, - { - "totalCount": 759, - "localMedian": 700000, - "localAverage": 800337.3032786886, - "remoteMedian": 1480000, - "remoteAverage": 1485601.5167785236 - }, - { - "totalCount": 772, - "localMedian": 700000, - "localAverage": 802770.0722311396, - "remoteMedian": 1480000, - "remoteAverage": 1485601.5167785236 - }, - { - "totalCount": 782, - "localMedian": 700000, - "localAverage": 806797.7027027027, - "remoteMedian": 1500000, - "remoteAverage": 1483494.2875816994 - }, - { - "totalCount": 928, - "localMedian": 700000, - "localAverage": 803129.6485411141, - "remoteMedian": 1435000, - "remoteAverage": 1479750.7241379311 - }, - { - "totalCount": 978, - "localMedian": 700000, - "localAverage": 810782.6503759399, - "remoteMedian": 1435000, - "remoteAverage": 1480154.9333333333 - }, - { - "totalCount": 1017, - "localMedian": 700000, - "localAverage": 815091.6826347306, - "remoteMedian": 1425000, - "remoteAverage": 1472528.076923077 - }, - { - "totalCount": 1041, - "localMedian": 700000, - "localAverage": 815573.5764294049, - "remoteMedian": 1460000, - "remoteAverage": 1477533.206521739 - }, - { - "totalCount": 1085, - "localMedian": 700000, - "localAverage": 808815.762806236, - "remoteMedian": 1470000, - "remoteAverage": 1519070.1069518717 - }, - { - "totalCount": 1173, - "localMedian": 700000, - "localAverage": 810014.9742798354, - "remoteMedian": 1400000, - "remoteAverage": 1496348.8059701493 - }, - { - "totalCount": 1210, - "localMedian": 700000, - "localAverage": 809258.8138138138, - "remoteMedian": 1400000, - "remoteAverage": 1505745.0663507108 - }, - { - "totalCount": 1265, - "localMedian": 700000, - "localAverage": 802990.9443911792, - "remoteMedian": 1366306.5, - "remoteAverage": 1478410.8513513512 - }, - { - "totalCount": 1296, - "localMedian": 700000, - "localAverage": 807915.2343017807, - "remoteMedian": 1377000, - "remoteAverage": 1478810.9475982534 - }, - { - "totalCount": 1306, - "localMedian": 700000, - "localAverage": 807396.0584958218, - "remoteMedian": 1377000, - "remoteAverage": 1478810.9475982534 - }, - { - "totalCount": 1345, - "localMedian": 700000, - "localAverage": 806082.8141831239, - "remoteMedian": 1377000, - "remoteAverage": 1476418.6450216451 - }, - { - "totalCount": 1428, - "localMedian": 700000, - "localAverage": 807632.0598146588, - "remoteMedian": 1355613, - "remoteAverage": 1472709.9958506224 - }, - { - "totalCount": 1484, - "localMedian": 700000, - "localAverage": 807066.872874494, - "remoteMedian": 1355613, - "remoteAverage": 1481016.502008032 - }, - { - "totalCount": 1697, - "localMedian": 700000, - "localAverage": 825096.4335465529, - "remoteMedian": 1400000, - "remoteAverage": 1489812.1103448276 - } - ], - "gradeItems": [ - { - "grade": 2, - "totalCount": 172, - "localMedian": 350000, - "localAverage": 358982.0512820513, - "remoteMedian": 375000, - "remoteAverage": 657789.5625 - }, - { - "grade": 5, - "totalCount": 283, - "localMedian": 718500, - "localAverage": 775343.75, - "remoteMedian": 1100000, - "remoteAverage": 1187634.4237288137 - }, - { - "grade": 8, - "totalCount": 121, - "localMedian": 1300000, - "localAverage": 1268116.524390244, - "remoteMedian": 2000000, - "remoteAverage": 2006921.8461538462 - }, - { - "grade": 11, - "totalCount": 55, - "localMedian": 1600000, - "localAverage": 1559767.441860465, - "remoteMedian": 1625000, - "remoteAverage": 1958792.5 - }, - { - "grade": 2, - "totalCount": 190, - "localMedian": 345000, - "localAverage": 355524.1379310345, - "remoteMedian": 375000, - "remoteAverage": 657789.5625 - }, - { - "grade": 5, - "totalCount": 307, - "localMedian": 725000, - "localAverage": 775526.5306122449, - "remoteMedian": 1100000, - "remoteAverage": 1194684.3709677418 - }, - { - "grade": 8, - "totalCount": 127, - "localMedian": 1275000, - "localAverage": 1259351.8452380951, - "remoteMedian": 2000000, - "remoteAverage": 2010559.3488372094 - }, - { - "grade": 11, - "totalCount": 67, - "localMedian": 1500000, - "localAverage": 1517692.3076923077, - "remoteMedian": 1650000, - "remoteAverage": 1955034 - }, - { - "grade": 2, - "totalCount": 197, - "localMedian": 340000, - "localAverage": 354395.55555555556, - "remoteMedian": 400000, - "remoteAverage": 663213.7058823529 - }, - { - "grade": 5, - "totalCount": 316, - "localMedian": 745000, - "localAverage": 777644.2687747036, - "remoteMedian": 1100000, - "remoteAverage": 1193181.4444444445 - }, - { - "grade": 8, - "totalCount": 134, - "localMedian": 1225000, - "localAverage": 1249950.611111111, - "remoteMedian": 2000000, - "remoteAverage": 2019410.2727272727 - }, - { - "grade": 11, - "totalCount": 69, - "localMedian": 1500000, - "localAverage": 1528679.2452830188, - "remoteMedian": 1825000, - "remoteAverage": 2032844.375 - }, - { - "grade": 2, - "totalCount": 205, - "localMedian": 330000, - "localAverage": 353984.94623655913, - "remoteMedian": 400000, - "remoteAverage": 635507 - }, - { - "grade": 5, - "totalCount": 325, - "localMedian": 720000, - "localAverage": 777839.6946564886, - "remoteMedian": 1100000, - "remoteAverage": 1193181.4444444445 - }, - { - "grade": 8, - "totalCount": 145, - "localMedian": 1250000, - "localAverage": 1270914.696969697, - "remoteMedian": 1950000, - "remoteAverage": 2001175.043478261 - }, - { - "grade": 11, - "totalCount": 74, - "localMedian": 1625000, - "localAverage": 1550357.142857143, - "remoteMedian": 2000000, - "remoteAverage": 2123639.4444444445 - }, - { - "grade": 2, - "totalCount": 210, - "localMedian": 330000, - "localAverage": 353200, - "remoteMedian": 400000, - "remoteAverage": 635507 - }, - { - "grade": 5, - "totalCount": 330, - "localMedian": 725000, - "localAverage": 778629.213483146, - "remoteMedian": 1100000, - "remoteAverage": 1193181.4444444445 - }, - { - "grade": 8, - "totalCount": 147, - "localMedian": 1300000, - "localAverage": 1290302.5247524753, - "remoteMedian": 1950000, - "remoteAverage": 2001175.043478261 - }, - { - "grade": 11, - "totalCount": 75, - "localMedian": 1650000, - "localAverage": 1552982.4561403508, - "remoteMedian": 2000000, - "remoteAverage": 2123639.4444444445 - }, - { - "grade": 2, - "totalCount": 210, - "localMedian": 330000, - "localAverage": 353200, - "remoteMedian": 400000, - "remoteAverage": 635507 - }, - { - "grade": 5, - "totalCount": 336, - "localMedian": 750000, - "localAverage": 783372.6937269373, - "remoteMedian": 1100000, - "remoteAverage": 1202622.0153846154 - }, - { - "grade": 8, - "totalCount": 150, - "localMedian": 1300000, - "localAverage": 1293888.8834951457, - "remoteMedian": 1900000, - "remoteAverage": 1997320.255319149 - }, - { - "grade": 11, - "totalCount": 76, - "localMedian": 1650000, - "localAverage": 1552982.4561403508, - "remoteMedian": 2000000, - "remoteAverage": 2053974.2105263157 - }, - { - "grade": 2, - "totalCount": 249, - "localMedian": 320000, - "localAverage": 351537.9912663755, - "remoteMedian": 375000, - "remoteAverage": 618731.65 - }, - { - "grade": 5, - "totalCount": 401, - "localMedian": 750000, - "localAverage": 776779.8165137614, - "remoteMedian": 1100000, - "remoteAverage": 1185654.472972973 - }, - { - "grade": 8, - "totalCount": 179, - "localMedian": 1300000, - "localAverage": 1277321.5853658537, - "remoteMedian": 1900000, - "remoteAverage": 2001572.357142857 - }, - { - "grade": 11, - "totalCount": 89, - "localMedian": 1675000, - "localAverage": 1588382.3529411764, - "remoteMedian": 2000000, - "remoteAverage": 1973595.7142857143 - }, - { - "grade": 2, - "totalCount": 260, - "localMedian": 300000, - "localAverage": 349800.8333333333, - "remoteMedian": 375000, - "remoteAverage": 618731.65 - }, - { - "grade": 5, - "totalCount": 426, - "localMedian": 750000, - "localAverage": 774361.0315186246, - "remoteMedian": 1100000, - "remoteAverage": 1195953.6493506494 - }, - { - "grade": 8, - "totalCount": 187, - "localMedian": 1300000, - "localAverage": 1279345.3875968992, - "remoteMedian": 1900000, - "remoteAverage": 1996367.4827586208 - }, - { - "grade": 11, - "totalCount": 95, - "localMedian": 1600000, - "localAverage": 1668969.8630136987, - "remoteMedian": 1825000, - "remoteAverage": 1924795.9090909092 - }, - { - "grade": 2, - "totalCount": 269, - "localMedian": 300000, - "localAverage": 347428.22580645164, - "remoteMedian": 350000, - "remoteAverage": 595088.3333333334 - }, - { - "grade": 5, - "totalCount": 443, - "localMedian": 745000, - "localAverage": 773641.095890411, - "remoteMedian": 1100000, - "remoteAverage": 1199210.6538461538 - }, - { - "grade": 8, - "totalCount": 194, - "localMedian": 1300000, - "localAverage": 1286658.4926470588, - "remoteMedian": 1900000, - "remoteAverage": 1996367.4827586208 - }, - { - "grade": 11, - "totalCount": 101, - "localMedian": 1590000, - "localAverage": 1660060.759493671, - "remoteMedian": 1825000, - "remoteAverage": 1924795.9090909092 - }, - { - "grade": 2, - "totalCount": 279, - "localMedian": 310000, - "localAverage": 350570.54263565893, - "remoteMedian": 350000, - "remoteAverage": 595088.3333333334 - }, - { - "grade": 5, - "totalCount": 450, - "localMedian": 720000, - "localAverage": 774002.6881720431, - "remoteMedian": 1100000, - "remoteAverage": 1199210.6538461538 - }, - { - "grade": 8, - "totalCount": 196, - "localMedian": 1300000, - "localAverage": 1278880.8333333333, - "remoteMedian": 1900000, - "remoteAverage": 1996367.4827586208 - }, - { - "grade": 11, - "totalCount": 106, - "localMedian": 1625000, - "localAverage": 1684814.6341463414, - "remoteMedian": 1825000, - "remoteAverage": 1925479.5833333333 - }, - { - "grade": 2, - "totalCount": 291, - "localMedian": 325000, - "localAverage": 352315.55555555556, - "remoteMedian": 350000, - "remoteAverage": 595088.3333333334 - }, - { - "grade": 5, - "totalCount": 473, - "localMedian": 700000, - "localAverage": 764989.8218829517, - "remoteMedian": 1100000, - "remoteAverage": 1206730.3875 - }, - { - "grade": 8, - "totalCount": 200, - "localMedian": 1300000, - "localAverage": 1275784.0780141845, - "remoteMedian": 1900000, - "remoteAverage": 2118462.9491525423 - }, - { - "grade": 11, - "totalCount": 111, - "localMedian": 1590000, - "localAverage": 1663618.3908045976, - "remoteMedian": 1825000, - "remoteAverage": 1925479.5833333333 - }, - { - "grade": 2, - "totalCount": 317, - "localMedian": 325000, - "localAverage": 352911.6438356164, - "remoteMedian": 350000, - "remoteAverage": 591874.2 - }, - { - "grade": 5, - "totalCount": 509, - "localMedian": 700000, - "localAverage": 764011.8483412323, - "remoteMedian": 1100000, - "remoteAverage": 1206188.8620689656 - }, - { - "grade": 8, - "totalCount": 220, - "localMedian": 1200000, - "localAverage": 1277889.5886075948, - "remoteMedian": 1950000, - "remoteAverage": 2112730.870967742 - }, - { - "grade": 11, - "totalCount": 117, - "localMedian": 1590000, - "localAverage": 1656288.1720430108, - "remoteMedian": 1825000, - "remoteAverage": 1925479.5833333333 - }, - { - "grade": 2, - "totalCount": 327, - "localMedian": 335000, - "localAverage": 355960.9271523179, - "remoteMedian": 350000, - "remoteAverage": 591874.2 - }, - { - "grade": 5, - "totalCount": 523, - "localMedian": 700000, - "localAverage": 761928.2407407408, - "remoteMedian": 1100000, - "remoteAverage": 1202795.7802197803 - }, - { - "grade": 8, - "totalCount": 226, - "localMedian": 1200000, - "localAverage": 1275661.8322981365, - "remoteMedian": 1900000, - "remoteAverage": 2108481.7538461536 - }, - { - "grade": 11, - "totalCount": 124, - "localMedian": 1590000, - "localAverage": 1654482.4742268042, - "remoteMedian": 2000000, - "remoteAverage": 1947393.4814814816 - }, - { - "grade": 2, - "totalCount": 343, - "localMedian": 327500, - "localAverage": 354921.01910828025, - "remoteMedian": 350000, - "remoteAverage": 576788.1034482758 - }, - { - "grade": 5, - "totalCount": 542, - "localMedian": 700000, - "localAverage": 754671.875, - "remoteMedian": 1100000, - "remoteAverage": 1203929.9574468085 - }, - { - "grade": 8, - "totalCount": 239, - "localMedian": 1200000, - "localAverage": 1252597.3823529412, - "remoteMedian": 1900000, - "remoteAverage": 2056540.7826086956 - }, - { - "grade": 11, - "totalCount": 130, - "localMedian": 1500000, - "localAverage": 1641114.563106796, - "remoteMedian": 2000000, - "remoteAverage": 1947393.4814814816 - }, - { - "grade": 2, - "totalCount": 348, - "localMedian": 330000, - "localAverage": 356066.4576802508, - "remoteMedian": 350000, - "remoteAverage": 576788.1034482758 - }, - { - "grade": 5, - "totalCount": 551, - "localMedian": 700000, - "localAverage": 756121.1453744493, - "remoteMedian": 1100000, - "remoteAverage": 1204741.381443299 - }, - { - "grade": 8, - "totalCount": 252, - "localMedian": 1200000, - "localAverage": 1260399.7486033519, - "remoteMedian": 1862000, - "remoteAverage": 2036319.3698630137 - }, - { - "grade": 11, - "totalCount": 133, - "localMedian": 1545000, - "localAverage": 1636649.0566037735, - "remoteMedian": 2000000, - "remoteAverage": 1947393.4814814816 - }, - { - "grade": 2, - "totalCount": 349, - "localMedian": 330000, - "localAverage": 356360, - "remoteMedian": 350000, - "remoteAverage": 576788.1034482758 - }, - { - "grade": 5, - "totalCount": 559, - "localMedian": 700000, - "localAverage": 754435.064935065, - "remoteMedian": 1100000, - "remoteAverage": 1204741.381443299 - }, - { - "grade": 8, - "totalCount": 252, - "localMedian": 1200000, - "localAverage": 1260399.7486033519, - "remoteMedian": 1862000, - "remoteAverage": 2036319.3698630137 - }, - { - "grade": 11, - "totalCount": 134, - "localMedian": 1590000, - "localAverage": 1638175.7009345794, - "remoteMedian": 2000000, - "remoteAverage": 1947393.4814814816 - }, - { - "grade": 2, - "totalCount": 362, - "localMedian": 330000, - "localAverage": 357421.021021021, - "remoteMedian": 350000, - "remoteAverage": 576788.1034482758 - }, - { - "grade": 5, - "totalCount": 574, - "localMedian": 700000, - "localAverage": 757759.8739495798, - "remoteMedian": 1100000, - "remoteAverage": 1200152.1836734693 - }, - { - "grade": 8, - "totalCount": 256, - "localMedian": 1200000, - "localAverage": 1260118.434065934, - "remoteMedian": 1841000, - "remoteAverage": 2031098.8378378379 - }, - { - "grade": 11, - "totalCount": 139, - "localMedian": 1555000, - "localAverage": 1629953.5714285714, - "remoteMedian": 2000000, - "remoteAverage": 1947393.4814814816 - }, - { - "grade": 2, - "totalCount": 384, - "localMedian": 330000, - "localAverage": 360850.8474576271, - "remoteMedian": 350000, - "remoteAverage": 573561.8333333334 - }, - { - "grade": 5, - "totalCount": 613, - "localMedian": 700000, - "localAverage": 758946.3654223968, - "remoteMedian": 1100000, - "remoteAverage": 1193316.4807692308 - }, - { - "grade": 8, - "totalCount": 267, - "localMedian": 1200000, - "localAverage": 1264607.0572916667, - "remoteMedian": 1820000, - "remoteAverage": 2026350.8533333333 - }, - { - "grade": 11, - "totalCount": 149, - "localMedian": 1565000, - "localAverage": 1627456.6666666667, - "remoteMedian": 2000000, - "remoteAverage": 1993276.7586206896 - }, - { - "grade": 2, - "totalCount": 399, - "localMedian": 322500, - "localAverage": 360514.1304347826, - "remoteMedian": 350000, - "remoteAverage": 582801.7741935484 - }, - { - "grade": 5, - "totalCount": 634, - "localMedian": 700000, - "localAverage": 758683.7429111531, - "remoteMedian": 1100000, - "remoteAverage": 1188046.8 - }, - { - "grade": 8, - "totalCount": 279, - "localMedian": 1200000, - "localAverage": 1263669.4278606966, - "remoteMedian": 1810000, - "remoteAverage": 2029183.5128205128 - }, - { - "grade": 11, - "totalCount": 153, - "localMedian": 1600000, - "localAverage": 1641421.138211382, - "remoteMedian": 2000000, - "remoteAverage": 2110167.533333333 - }, - { - "grade": 2, - "totalCount": 431, - "localMedian": 330000, - "localAverage": 361275.75757575757, - "remoteMedian": 350000, - "remoteAverage": 564195.8571428572 - }, - { - "grade": 5, - "totalCount": 725, - "localMedian": 715000, - "localAverage": 768454.355848435, - "remoteMedian": 1125000, - "remoteAverage": 1202004.2542372881 - }, - { - "grade": 8, - "totalCount": 337, - "localMedian": 1200000, - "localAverage": 1266964.8125, - "remoteMedian": 1800000, - "remoteAverage": 1997724.8865979381 - }, - { - "grade": 11, - "totalCount": 182, - "localMedian": 1565000, - "localAverage": 1623816.2162162163, - "remoteMedian": 2000000, - "remoteAverage": 2114789.4411764704 - } - ] - }, - "shouldAddOwnSalary": false, - "hasAuthentication": true, - "from": "2023-06-15T05:00:10.5964449+00:00", - "to": "2024-06-15T05:00:10.5964449+00:00", - "chartFrom": "0001-01-01T00:00:00+00:00", - "chartTo": "0001-01-01T00:00:00+00:00" -} \ No newline at end of file diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts index 2159e8a6..781581f6 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts @@ -149,7 +149,6 @@ export class HistoricalChartsPageComponent implements OnInit, OnDestroy { .subscribe((x) => { this.isAuthenticated = x.hasAuthentication; this.data = x; - console.log(this.data); }); } } diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts index 9606cc6a..5d8f978a 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts @@ -16,7 +16,6 @@ export class HistoricalSalariesChartComponent implements OnInit { ngOnInit(): void { - console.log(this.data); if (this.data == null) { return; } diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts index d22aa93e..f93539a5 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts @@ -16,30 +16,51 @@ export class HistoricalSalariesChartObject extends Chart { private readonly datasets: Array = []; constructor(canvasId: string, chartData: SalariesCountWeekByWeekChart) { - const randomColor = new RandomRgbColor(); // По датасету на медиану и среднюю const datasets: Array = [ - { - label: "Все анкеты", - data: [], - borderWidth: 1, - borderColor: randomColor.toString(1), - backgroundColor: randomColor.toString(0.5), - pointStyle: false as PointStyle, - yAxisID: 'y', - }, - { - label: "Количество анкет", - data: chartData.totalCountItems.map(x => x.totalCount), - borderWidth: 1, - borderColor: randomColor.toString(1), - backgroundColor: randomColor.toString(0.5), - pointStyle: false as PointStyle, - yAxisID: 'y1', - }, + new DatasetItem( + "Количество анкет", + chartData.totalCountItems.map(x => x.totalCount), + 4, + new RandomRgbColor(), + false as PointStyle, + 'y1' + ), + new DatasetItem( + "Медиана, КЗ", + chartData.totalCountItems.map(x => x.localMedian), + 2, + new RandomRgbColor(), + false as PointStyle, + 'y' + ), + new DatasetItem( + "Средняя, КЗ", + chartData.totalCountItems.map(x => x.localAverage), + 2, + new RandomRgbColor(), + false as PointStyle, + 'y' + ), + new DatasetItem( + "Медиана, удаленка", + chartData.totalCountItems.map(x => x.remoteMedian), + 2, + new RandomRgbColor(), + false as PointStyle, + 'y' + ), + new DatasetItem( + "Средняя, удаленка", + chartData.totalCountItems.map(x => x.remoteAverage), + 2, + new RandomRgbColor(), + false as PointStyle, + 'y' + ), ]; - + super(canvasId, { type: "line" as ChartType, data: { @@ -80,3 +101,21 @@ export class HistoricalSalariesChartObject extends Chart { this.datasets = datasets; } } + +class DatasetItem implements ChartDatasetType { + + constructor( + readonly label: string, + readonly data: number[], + readonly borderWidth: number, + readonly color: RandomRgbColor, + readonly pointStyle: PointStyle, + readonly yAxisID: "y1" | "y" + ) { + this.borderColor = color.toString(1); + this.backgroundColor = color.toString(0.5); + } + + readonly borderColor: string; + readonly backgroundColor: string; +} diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss index 96d0d31d..5d84bf97 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss @@ -1,10 +1,10 @@ #canvas-historical-chart { - min-height: 400px; + min-height: 600px; } #canvas-historical-chart-container { position: relative; width: 100%; height: 100%; - min-height: 400px; + min-height: 600px; } \ No newline at end of file From af96b0ac030091c69387b47a7163d06b8e6f8f68 Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sat, 15 Jun 2024 16:37:43 +0500 Subject: [PATCH 6/9] Added additional chart --- src/app/models/enums/developer-grade.enum.ts | 4 +- .../historical-charts-page.component.html | 14 +- .../historical-charts-page.component.ts | 2 +- ...storical-salaries-by-grade-chart-object.ts | 203 ++++++++++++++++++ ...cal-salaries-by-grade-chart.component.html | 23 ++ ...cal-salaries-by-grade-chart.component.scss | 10 + ...-salaries-by-grade-chart.component.spec.ts | 32 +++ ...rical-salaries-by-grade-chart.component.ts | 56 +++++ .../historical-salaries-chart.component.html | 4 + src/app/modules/salaries/salaries.module.ts | 4 +- src/app/services/historical-charts.service.ts | 3 +- tsconfig.json | 1 - 12 files changed, 345 insertions(+), 11 deletions(-) create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart-object.ts create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.html create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.scss create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.spec.ts create mode 100644 src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts diff --git a/src/app/models/enums/developer-grade.enum.ts b/src/app/models/enums/developer-grade.enum.ts index 391a3e40..f0f7aa20 100644 --- a/src/app/models/enums/developer-grade.enum.ts +++ b/src/app/models/enums/developer-grade.enum.ts @@ -54,7 +54,7 @@ export class DeveloperGradeEnum { [DeveloperGrade.Junior, { label: "Junior", cssBackground: "bg-success", - cssText: "", + cssText: "text-light", }], [DeveloperGrade.Middle, { label: "Middle", @@ -69,7 +69,7 @@ export class DeveloperGradeEnum { [DeveloperGrade.Lead, { label: "Lead", cssBackground: "bg-primary", - cssText: "", + cssText: "text-light", }], [DeveloperGrade.Unknown, DeveloperGradeEnum.defaultColor], ]); diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html index 5041ed00..c7949d15 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html @@ -12,14 +12,18 @@ (filtersApplied)="applyGlobalFilters($event)" (filtersReset)="resetGlobalFilters()" (shareClicked)="share($event)" - > - + /> -
+
+ [data]="data.salariesCountWeekByWeekChart" + /> +
+ +
+
diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts index 781581f6..5696e9f1 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts @@ -42,7 +42,7 @@ export class HistoricalChartsPageComponent implements OnInit, OnDestroy { private readonly gtag: GoogleAnalyticsService, activatedRouteSource: ActivatedRoute ) { - titleService.setTitle("Опрос о пользе зарплатной статистики"); + titleService.setTitle("Исторические данные"); this.activatedRoute = new SalariesChartActivatedRoute(activatedRouteSource); } diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart-object.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart-object.ts new file mode 100644 index 00000000..c6586df1 --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart-object.ts @@ -0,0 +1,203 @@ +import { SalariesCountWeekByWeekChart, SalariesCountWeekByWeekChartGradeItem } from "@services/historical-charts.service"; +import { Chart, ChartType, PointStyle } from "chart.js/auto"; +import { RandomRgbColor } from "../../random-rgb-color"; +import { DeveloperGrade, DeveloperGradeEnum } from "@models/enums"; + +interface ChartDatasetType { + label: string; + data: Array; + borderWidth: number; + borderColor: string; + backgroundColor: string; + pointStyle: PointStyle; + grade: DeveloperGrade | null; + yAxisID: 'y' | 'y1', + hidden: boolean; + + toggle(): void; +} + +export class HistoricalSalariesByGradeChartObject extends Chart { + private readonly datasets: Array = []; + + constructor(canvasId: string, chartData: SalariesCountWeekByWeekChart) { + const datasets: Array = [ + new DatasetItem( + "Количество анкет", + chartData.totalCountItems.map(x => x.totalCount), + 4, + new RandomRgbColor(), + false as PointStyle, + null, + 'y1', + false, + ), + ]; + + const juniorSalaries = []; + const middleSalaries = []; + const seniorSalaries = []; + const leadSalaries = []; + + for (let index = 0; index < chartData.gradeItems.length; index++) { + const element = chartData.gradeItems[index]; + + switch (element.grade) { + case DeveloperGrade.Junior: + juniorSalaries.push(element); + break; + + case DeveloperGrade.Middle: + middleSalaries.push(element); + break; + + case DeveloperGrade.Senior: + seniorSalaries.push(element); + break; + + case DeveloperGrade.Lead: + leadSalaries.push(element); + break; + } + } + + datasets.push( + ...HistoricalSalariesByGradeChartObject.getDatasetForGrade( + DeveloperGrade.Junior, juniorSalaries, true, + ), + ...HistoricalSalariesByGradeChartObject.getDatasetForGrade( + DeveloperGrade.Middle, middleSalaries, true, + ), + ...HistoricalSalariesByGradeChartObject.getDatasetForGrade( + DeveloperGrade.Senior, seniorSalaries, true, + ), + ...HistoricalSalariesByGradeChartObject.getDatasetForGrade( + DeveloperGrade.Lead, leadSalaries, true, + ), + ); + + super(canvasId, { + type: "line" as ChartType, + data: { + labels: chartData + .weekEnds + .map((x) => x.toISOString().slice(0, 10)), + datasets: datasets, + }, + options: { + responsive: true, + maintainAspectRatio: false, + scales: { + y: { + beginAtZero: true, + position: 'left', + }, + y1: { + beginAtZero: true, + position: 'right', + } + }, + elements: { + line: { + tension: 0.4, + }, + }, + plugins: { + legend: { + position: "bottom", + title: { + position: "start", + }, + }, + }, + }, + }); + + this.datasets = datasets; + } + + toggle(grade: DeveloperGrade): void { + this.datasets + .filter((x) => x.grade === grade) + .forEach((x) => x.toggle()); + + this.update(); + } + + private static getDatasetForGrade( + grade: DeveloperGrade, + items: Array, + hidden: boolean + ): Array { + + const prefix = DeveloperGrade[grade]; + return [ + new DatasetItem( + prefix + ", медиана, КЗ", + items.map(x => x.localMedian), + 2, + new RandomRgbColor(), + false as PointStyle, + grade, + 'y', + hidden + ), + new DatasetItem( + prefix + ", средняя, КЗ", + items.map(x => x.localAverage), + 2, + new RandomRgbColor(), + false as PointStyle, + grade, + 'y', + hidden + ), + new DatasetItem( + prefix + ", медиана, удаленка", + items.map(x => x.remoteMedian), + 2, + new RandomRgbColor(), + false as PointStyle, + grade, + 'y', + hidden + ), + new DatasetItem( + prefix + ", средняя, удаленка", + items.map(x => x.remoteAverage), + 2, + new RandomRgbColor(), + false as PointStyle, + grade, + 'y', + hidden + ), + ]; + } +} + +class DatasetItem implements ChartDatasetType { + + constructor( + readonly label: string, + readonly data: number[], + readonly borderWidth: number, + readonly color: RandomRgbColor, + readonly pointStyle: PointStyle, + readonly grade: DeveloperGrade | null, + readonly yAxisID: "y1" | "y", + hidden: boolean + ) { + this.borderColor = color.toString(1); + this.backgroundColor = color.toString(0.5); + this.hidden = hidden; + } + + hidden: boolean; + readonly borderColor: string; + readonly backgroundColor: string; + + toggle(): void { + this.hidden = !this.hidden; + } +} diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.html b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.html new file mode 100644 index 00000000..c55c31ac --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.html @@ -0,0 +1,23 @@ +
+ Зарплаты по грейдам +
+ +
+
+ Ниже вы можете включить группы графиков для соответствующего грейда. + Будет показано по 4 линии на графике: медиана и средняя в Казахстане и медиана и средняя на удаленке. +
+
+ +
+
+ +
+ {{ chart }} +
diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.scss b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.scss new file mode 100644 index 00000000..9a97a4df --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.scss @@ -0,0 +1,10 @@ +#canvas-historical-chart-by-grade { + min-height: 600px; +} + +#canvas-historical-chart-by-grade-container { + position: relative; + width: 100%; + height: 100%; + min-height: 600px; +} \ No newline at end of file diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.spec.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.spec.ts new file mode 100644 index 00000000..57dc319a --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.spec.ts @@ -0,0 +1,32 @@ +import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core"; +import { ComponentFixture, TestBed } from "@angular/core/testing"; +import { + mostUsedImports, + mostUsedServices, + testUtilStubs, +} from "@shared/test-utils"; +import { HistoricalSalariesByGradeChartComponent } from "./historical-salaries-by-grade-chart.component"; + +describe("HistoricalSalariesByGradeChartComponent", () => { + let component: HistoricalSalariesByGradeChartComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [HistoricalSalariesByGradeChartComponent], + imports: [...mostUsedImports], + providers: [...testUtilStubs, ...mostUsedServices], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + }).compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(HistoricalSalariesByGradeChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it("should create", () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts new file mode 100644 index 00000000..6968e0a2 --- /dev/null +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts @@ -0,0 +1,56 @@ +import { Component, Input, OnInit } from "@angular/core"; +import { SalariesCountWeekByWeekChart } from "@services/historical-charts.service"; +import { HistoricalSalariesByGradeChartObject } from "./historical-salaries-by-grade-chart-object"; +import { DeveloperGrade, DeveloperGradeEnum } from "@models/enums"; + +interface GradeToggleButton { + label: string; + bgCss: string; + textCss: string; + toggle(): void; +} + +@Component({ + selector: "app-historical-salaries-by-grade-chart", + templateUrl: "./historical-salaries-by-grade-chart.component.html", + styleUrls: ["./historical-salaries-by-grade-chart.component.scss"], +}) +export class HistoricalSalariesByGradeChartComponent implements OnInit { + + gradesButtons: Array = []; + + @Input() + data: SalariesCountWeekByWeekChart | null = null; + + chart: HistoricalSalariesByGradeChartObject | null = null; + + ngOnInit(): void { + + if (this.data == null) { + return; + } + + this.gradesButtons = [ + this.createGradeToggleButton(DeveloperGrade.Junior), + this.createGradeToggleButton(DeveloperGrade.Middle), + this.createGradeToggleButton(DeveloperGrade.Senior), + this.createGradeToggleButton(DeveloperGrade.Lead), + ]; + + this.chart = new HistoricalSalariesByGradeChartObject( + "canvas-historical-chart-by-grade", + this.data); + } + + private createGradeToggleButton(grade: DeveloperGrade): GradeToggleButton { + const color = DeveloperGradeEnum.getColorData(grade); + return { + label: color.label, + bgCss: color.cssBackground, + textCss: color.cssText, + toggle: () => { + this.chart?.toggle(grade); + } + }; + } +} diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.html b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.html index 6812e7c1..2ee5c346 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.html +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.html @@ -1,3 +1,7 @@ +
+ Изменение медианной и средней зарплат по времени +
+
{{ chart }}
diff --git a/src/app/modules/salaries/salaries.module.ts b/src/app/modules/salaries/salaries.module.ts index 73cab202..731964e5 100644 --- a/src/app/modules/salaries/salaries.module.ts +++ b/src/app/modules/salaries/salaries.module.ts @@ -29,6 +29,7 @@ import { SalariesAddingChartComponent } from "./components/salaries-chart/salari import { CurrencySelectBoxComponent } from "./components/salaries-chart/currency-select-box/currency-select-box.component"; import { HistoricalChartsPageComponent } from "./components/historical-charts-page/historical-charts-page.component"; import { HistoricalSalariesChartComponent } from "./components/historical-charts-page/historical-salaries-chart/historical-charts-page.component"; +import { HistoricalSalariesByGradeChartComponent } from "./components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component"; @NgModule({ declarations: [ @@ -57,7 +58,8 @@ import { HistoricalSalariesChartComponent } from "./components/historical-charts SalariesAddingChartComponent, CurrencySelectBoxComponent, HistoricalChartsPageComponent, - HistoricalSalariesChartComponent + HistoricalSalariesChartComponent, + HistoricalSalariesByGradeChartComponent ], imports: [ CommonModule, diff --git a/src/app/services/historical-charts.service.ts b/src/app/services/historical-charts.service.ts index d1f01f9a..2f5928a1 100644 --- a/src/app/services/historical-charts.service.ts +++ b/src/app/services/historical-charts.service.ts @@ -20,7 +20,8 @@ export interface SalariesCountWeekByWeekChartGradeItem extends SalariesCountWeek export interface SalariesCountWeekByWeekChart { weekEnds: Array; totalCountItems: Array; - grades: Array; + gradeItems: Array; + hasGradeItems: boolean; } export interface GetSalariesHistoricalChartResponse { diff --git a/tsconfig.json b/tsconfig.json index a58ff37b..df635309 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,4 +1,3 @@ -/* To learn more about this file see: https://angular.io/config/tsconfig. */ { "compileOnSave": false, "compilerOptions": { From c7636cfcf76f83d9015078861161b897574d83a0 Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sat, 15 Jun 2024 16:38:54 +0500 Subject: [PATCH 7/9] Prettier --- src/app/models/enums/developer-grade.enum.ts | 84 ++++--- .../background-jobs.component.html | 2 +- .../background-jobs/currency-item.ts | 23 +- ...erview-templates-admin-page.component.html | 2 +- ...aries-admin-paginated-table.component.html | 10 +- ...alaries-admin-paginated-table.component.ts | 12 +- .../telegram-bot-usages.component.html | 6 +- .../users-admin-page.component.html | 2 +- .../about-us/about-us.component.html | 73 ++++-- .../home/components/home/home.component.html | 18 +- .../home/components/home/home.component.scss | 2 +- .../home/components/home/home.component.ts | 19 +- .../interview-edit-page.component.ts | 14 +- .../interview-page.component.html | 3 +- .../interview-template-edit-page.component.ts | 4 +- .../interview-template-page.component.html | 3 +- .../my-interview-templates.component.html | 2 +- .../my-interviews.component.html | 2 +- .../public-interview-templates.component.html | 2 +- .../text-with-linebreaks.component.html | 3 +- .../cities-doughnut-chart-object.ts | 3 +- .../historical-charts-page.component.html | 7 +- .../historical-charts-page.component.scss | 12 +- .../historical-charts-page.component.spec.ts | 6 +- .../historical-charts-page.component.ts | 42 ++-- ...storical-salaries-by-grade-chart-object.ts | 235 +++++++++--------- ...cal-salaries-by-grade-chart.component.html | 8 +- ...cal-salaries-by-grade-chart.component.scss | 12 +- ...rical-salaries-by-grade-chart.component.ts | 9 +- .../historical-charts-page.component.ts | 7 +- .../historical-salaries-chart-object.ts | 176 +++++++------ .../historical-salaries-chart.component.scss | 12 +- .../people-by-gender-chart.component.html | 4 +- .../people-by-grades-chart.component.ts | 1 - .../currency-select-box.component.html | 33 +-- .../currency-select-box.component.ts | 37 ++- .../salaries-adding-chart.component.ts | 10 +- .../salaries-by-grade-block.component.html | 4 +- .../salaries-by-grade-block.component.ts | 15 +- .../salaries-chart.component.html | 5 +- .../salaries-chart/salaries-chart.ts | 90 ++++--- .../salary-block-remote-value.component.ts | 9 +- .../salary-block-value.component.html | 8 +- .../salary-block-value.component.ts | 17 +- .../salaries-paginated-table.component.html | 8 +- .../salaries-skills-chart.component.html | 2 +- .../salaries-survey-block.component.html | 76 +++--- .../salaries-survey-block.component.scss | 4 +- .../salaries-survey-block.component.ts | 1 - .../salaries-survey-form.ts | 139 ++++++----- .../salaries-survey-page.component.html | 43 ++-- .../salaries-survey-page.component.scss | 8 +- .../salaries-survey-page.component.ts | 157 +++++++----- .../work-industries-chart.component.html | 2 +- .../salaries/salaries-routing.module.ts | 2 +- src/app/modules/salaries/salaries.module.ts | 2 +- src/app/services/historical-charts.service.ts | 18 +- src/app/services/meta-tags.service.ts | 42 ++-- src/app/services/salaries-survey.service.ts | 39 +-- src/app/services/user-salaries.service.ts | 5 +- .../developer-grade-label.component.scss | 10 +- .../mock-google-analytics.service.ts | 6 +- src/index.html | 27 +- src/test.ts | 2 +- 64 files changed, 897 insertions(+), 744 deletions(-) diff --git a/src/app/models/enums/developer-grade.enum.ts b/src/app/models/enums/developer-grade.enum.ts index f0f7aa20..2b710840 100644 --- a/src/app/models/enums/developer-grade.enum.ts +++ b/src/app/models/enums/developer-grade.enum.ts @@ -25,7 +25,6 @@ export interface DeveloperGradeLabel { } export class DeveloperGradeEnum { - static readonly grades: Array = [ DeveloperGrade.Trainee, DeveloperGrade.Junior, @@ -41,40 +40,55 @@ export class DeveloperGradeEnum { cssText: "text-dark", }; - static readonly colorsByGrade: Map< - DeveloperGrade, - DeveloperGradeLabel - > = new Map([ - [DeveloperGrade.Trainee, { - label: "Trainee", - cssBackground: "bg-light", - cssText: "text-dark", - } - ], - [DeveloperGrade.Junior, { - label: "Junior", - cssBackground: "bg-success", - cssText: "text-light", - }], - [DeveloperGrade.Middle, { - label: "Middle", - cssBackground: "bg-warning", - cssText: "text-dark", - }], - [DeveloperGrade.Senior, { - label: "Senior", - cssBackground: "bg-info", - cssText: "text-dark", - }], - [DeveloperGrade.Lead, { - label: "Lead", - cssBackground: "bg-primary", - cssText: "text-light", - }], - [DeveloperGrade.Unknown, DeveloperGradeEnum.defaultColor], - ]); + static readonly colorsByGrade: Map = + new Map([ + [ + DeveloperGrade.Trainee, + { + label: "Trainee", + cssBackground: "bg-light", + cssText: "text-dark", + }, + ], + [ + DeveloperGrade.Junior, + { + label: "Junior", + cssBackground: "bg-success", + cssText: "text-light", + }, + ], + [ + DeveloperGrade.Middle, + { + label: "Middle", + cssBackground: "bg-warning", + cssText: "text-dark", + }, + ], + [ + DeveloperGrade.Senior, + { + label: "Senior", + cssBackground: "bg-info", + cssText: "text-dark", + }, + ], + [ + DeveloperGrade.Lead, + { + label: "Lead", + cssBackground: "bg-primary", + cssText: "text-light", + }, + ], + [DeveloperGrade.Unknown, DeveloperGradeEnum.defaultColor], + ]); static getColorData(grade: DeveloperGrade): DeveloperGradeLabel { - return DeveloperGradeEnum.colorsByGrade.get(grade) ?? DeveloperGradeEnum.defaultColor; + return ( + DeveloperGradeEnum.colorsByGrade.get(grade) ?? + DeveloperGradeEnum.defaultColor + ); } -} \ No newline at end of file +} diff --git a/src/app/modules/admin/components/background-jobs/background-jobs.component.html b/src/app/modules/admin/components/background-jobs/background-jobs.component.html index 81724f38..99d2f385 100644 --- a/src/app/modules/admin/components/background-jobs/background-jobs.component.html +++ b/src/app/modules/admin/components/background-jobs/background-jobs.component.html @@ -23,7 +23,7 @@ {{ item.currencyString }} {{ item.value }} kzt - {{ item.pubDate | date: "yyyy-MM-dd" }} + {{ item.pubDate | date : "yyyy-MM-dd" }} diff --git a/src/app/modules/admin/components/background-jobs/currency-item.ts b/src/app/modules/admin/components/background-jobs/currency-item.ts index 39e8e403..ad99cad2 100644 --- a/src/app/modules/admin/components/background-jobs/currency-item.ts +++ b/src/app/modules/admin/components/background-jobs/currency-item.ts @@ -1,16 +1,15 @@ import { CurrencyData, CurrencyType } from "@services/admin-tools.service"; export class CurrencyItem implements CurrencyData { + constructor(private readonly item: CurrencyData) { + this.value = item.value; + this.currency = item.currency; + this.currencyString = CurrencyType[item.currency]; + this.pubDate = item.pubDate; + } - constructor(private readonly item: CurrencyData) { - this.value = item.value; - this.currency = item.currency; - this.currencyString = CurrencyType[item.currency]; - this.pubDate = item.pubDate; - } - - readonly value: number; - readonly currency: CurrencyType; - readonly currencyString: string; - readonly pubDate: Date; -} \ No newline at end of file + readonly value: number; + readonly currency: CurrencyType; + readonly currencyString: string; + readonly pubDate: Date; +} diff --git a/src/app/modules/admin/components/interviews/interview-templates-admin-page/interview-templates-admin-page.component.html b/src/app/modules/admin/components/interviews/interview-templates-admin-page/interview-templates-admin-page.component.html index 0f0cfbba..63e4f917 100644 --- a/src/app/modules/admin/components/interviews/interview-templates-admin-page/interview-templates-admin-page.component.html +++ b/src/app/modules/admin/components/interviews/interview-templates-admin-page/interview-templates-admin-page.component.html @@ -28,7 +28,7 @@ [visibility]="item.isPublic" > - {{ item.updatedAt | date: "yyyy-MM-dd HH:mm" }} + {{ item.updatedAt | date : "yyyy-MM-dd HH:mm" }} - {{ item.value | number: "1.0-0" }} + {{ item.value | number : "1.0-0" }} {{ item.quarter }}.{{ item.year }} {{ item.age }} {{ item.gender }} {{ item.yearOfStartingWork }} {{ item.profession }} - + {{ item.company }} {{ item.city }} {{ item.skill }} {{ item.industry }} - {{ item.createdAt | date: "yyyy-MM-dd HH:mm" }} - {{ item.updatedAt | date: "yyyy-MM-dd HH:mm" }} + {{ item.createdAt | date : "yyyy-MM-dd HH:mm" }} + {{ item.updatedAt | date : "yyyy-MM-dd HH:mm" }} diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.scss b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.scss index 9a97a4df..a43d2bc3 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.scss +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.scss @@ -1,10 +1,10 @@ #canvas-historical-chart-by-grade { - min-height: 600px; + min-height: 600px; } #canvas-historical-chart-by-grade-container { - position: relative; - width: 100%; - height: 100%; - min-height: 600px; -} \ No newline at end of file + position: relative; + width: 100%; + height: 100%; + min-height: 600px; +} diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts index 6968e0a2..52e3fd65 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts @@ -16,16 +16,14 @@ interface GradeToggleButton { styleUrls: ["./historical-salaries-by-grade-chart.component.scss"], }) export class HistoricalSalariesByGradeChartComponent implements OnInit { - gradesButtons: Array = []; @Input() data: SalariesCountWeekByWeekChart | null = null; chart: HistoricalSalariesByGradeChartObject | null = null; - - ngOnInit(): void { + ngOnInit(): void { if (this.data == null) { return; } @@ -39,7 +37,8 @@ export class HistoricalSalariesByGradeChartComponent implements OnInit { this.chart = new HistoricalSalariesByGradeChartObject( "canvas-historical-chart-by-grade", - this.data); + this.data + ); } private createGradeToggleButton(grade: DeveloperGrade): GradeToggleButton { @@ -50,7 +49,7 @@ export class HistoricalSalariesByGradeChartComponent implements OnInit { textCss: color.cssText, toggle: () => { this.chart?.toggle(grade); - } + }, }; } } diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts index 5d8f978a..25f99d56 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-charts-page.component.ts @@ -8,20 +8,19 @@ import { HistoricalSalariesChartObject } from "./historical-salaries-chart-objec styleUrls: ["./historical-salaries-chart.component.scss"], }) export class HistoricalSalariesChartComponent implements OnInit { - @Input() data: SalariesCountWeekByWeekChart | null = null; chart: HistoricalSalariesChartObject | null = null; - - ngOnInit(): void { + ngOnInit(): void { if (this.data == null) { return; } this.chart = new HistoricalSalariesChartObject( "canvas-historical-chart", - this.data); + this.data + ); } } diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts index f93539a5..e13b4a1a 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts @@ -3,107 +3,103 @@ import { Chart, ChartType, PointStyle } from "chart.js/auto"; import { RandomRgbColor } from "../../random-rgb-color"; interface ChartDatasetType { - label: string; - data: Array; - borderWidth: number; - borderColor: string; - backgroundColor: string; - pointStyle: PointStyle; - yAxisID: 'y' | 'y1', + label: string; + data: Array; + borderWidth: number; + borderColor: string; + backgroundColor: string; + pointStyle: PointStyle; + yAxisID: "y" | "y1"; } export class HistoricalSalariesChartObject extends Chart { - private readonly datasets: Array = []; + private readonly datasets: Array = []; - constructor(canvasId: string, chartData: SalariesCountWeekByWeekChart) { + constructor(canvasId: string, chartData: SalariesCountWeekByWeekChart) { + // По датасету на медиану и среднюю + const datasets: Array = [ + new DatasetItem( + "Количество анкет", + chartData.totalCountItems.map((x) => x.totalCount), + 4, + new RandomRgbColor(), + false as PointStyle, + "y1" + ), + new DatasetItem( + "Медиана, КЗ", + chartData.totalCountItems.map((x) => x.localMedian), + 2, + new RandomRgbColor(), + false as PointStyle, + "y" + ), + new DatasetItem( + "Средняя, КЗ", + chartData.totalCountItems.map((x) => x.localAverage), + 2, + new RandomRgbColor(), + false as PointStyle, + "y" + ), + new DatasetItem( + "Медиана, удаленка", + chartData.totalCountItems.map((x) => x.remoteMedian), + 2, + new RandomRgbColor(), + false as PointStyle, + "y" + ), + new DatasetItem( + "Средняя, удаленка", + chartData.totalCountItems.map((x) => x.remoteAverage), + 2, + new RandomRgbColor(), + false as PointStyle, + "y" + ), + ]; - // По датасету на медиану и среднюю - const datasets: Array = [ - new DatasetItem( - "Количество анкет", - chartData.totalCountItems.map(x => x.totalCount), - 4, - new RandomRgbColor(), - false as PointStyle, - 'y1' - ), - new DatasetItem( - "Медиана, КЗ", - chartData.totalCountItems.map(x => x.localMedian), - 2, - new RandomRgbColor(), - false as PointStyle, - 'y' - ), - new DatasetItem( - "Средняя, КЗ", - chartData.totalCountItems.map(x => x.localAverage), - 2, - new RandomRgbColor(), - false as PointStyle, - 'y' - ), - new DatasetItem( - "Медиана, удаленка", - chartData.totalCountItems.map(x => x.remoteMedian), - 2, - new RandomRgbColor(), - false as PointStyle, - 'y' - ), - new DatasetItem( - "Средняя, удаленка", - chartData.totalCountItems.map(x => x.remoteAverage), - 2, - new RandomRgbColor(), - false as PointStyle, - 'y' - ), - ]; - - super(canvasId, { - type: "line" as ChartType, - data: { - labels: chartData - .weekEnds - .map((x) => x.toISOString().slice(0, 10)), - datasets: datasets, + super(canvasId, { + type: "line" as ChartType, + data: { + labels: chartData.weekEnds.map((x) => x.toISOString().slice(0, 10)), + datasets: datasets, + }, + options: { + responsive: true, + maintainAspectRatio: false, + scales: { + y: { + beginAtZero: true, + position: "left", }, - options: { - responsive: true, - maintainAspectRatio: false, - scales: { - y: { - beginAtZero: true, - position: 'left', - }, - y1: { - beginAtZero: true, - position: 'right', - } - }, - elements: { - line: { - tension: 0.4, - }, - }, - plugins: { - legend: { - position: "bottom", - title: { - position: "start", - }, - }, + y1: { + beginAtZero: true, + position: "right", + }, + }, + elements: { + line: { + tension: 0.4, + }, + }, + plugins: { + legend: { + position: "bottom", + title: { + position: "start", }, }, - }); - - this.datasets = datasets; - } + }, + }, + }); + + this.datasets = datasets; + } } class DatasetItem implements ChartDatasetType { - constructor( readonly label: string, readonly data: number[], diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss index 5d84bf97..d7f25b1d 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart.component.scss @@ -1,10 +1,10 @@ #canvas-historical-chart { - min-height: 600px; + min-height: 600px; } #canvas-historical-chart-container { - position: relative; - width: 100%; - height: 100%; - min-height: 600px; -} \ No newline at end of file + position: relative; + width: 100%; + height: 100%; + min-height: 600px; +} diff --git a/src/app/modules/salaries/components/people-by-gender-chart/people-by-gender-chart.component.html b/src/app/modules/salaries/components/people-by-gender-chart/people-by-gender-chart.component.html index edea7c29..47921dc0 100644 --- a/src/app/modules/salaries/components/people-by-gender-chart/people-by-gender-chart.component.html +++ b/src/app/modules/salaries/components/people-by-gender-chart/people-by-gender-chart.component.html @@ -17,7 +17,7 @@ {{ item.label }} {{ item.value }} - {{ item.part | number: "1.3" }}% + {{ item.part | number : "1.3" }}% Всего @@ -44,7 +44,7 @@ {{ item.label }} {{ item.value }} - {{ item.part | number: "1.3" }}% + {{ item.part | number : "1.3" }}% Всего diff --git a/src/app/modules/salaries/components/people-by-grades-chart/people-by-grades-chart.component.ts b/src/app/modules/salaries/components/people-by-grades-chart/people-by-grades-chart.component.ts index af948020..1ba45779 100644 --- a/src/app/modules/salaries/components/people-by-grades-chart/people-by-grades-chart.component.ts +++ b/src/app/modules/salaries/components/people-by-grades-chart/people-by-grades-chart.component.ts @@ -19,7 +19,6 @@ interface ProgressBarData { styleUrl: "./people-by-grades-chart.component.scss", }) export class PeopleByGradesChartComponent implements OnInit { - readonly grades = DeveloperGradeEnum.grades; @Input() diff --git a/src/app/modules/salaries/components/salaries-chart/currency-select-box/currency-select-box.component.html b/src/app/modules/salaries/components/salaries-chart/currency-select-box/currency-select-box.component.html index 250c26df..fccbf314 100644 --- a/src/app/modules/salaries/components/salaries-chart/currency-select-box/currency-select-box.component.html +++ b/src/app/modules/salaries/components/salaries-chart/currency-select-box/currency-select-box.component.html @@ -1,15 +1,20 @@ -
- - - - +
+ + +
diff --git a/src/app/modules/salaries/components/salaries-chart/currency-select-box/currency-select-box.component.ts b/src/app/modules/salaries/components/salaries-chart/currency-select-box/currency-select-box.component.ts index 81330444..3215856f 100644 --- a/src/app/modules/salaries/components/salaries-chart/currency-select-box/currency-select-box.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/currency-select-box/currency-select-box.component.ts @@ -10,7 +10,6 @@ import { GoogleAnalyticsService } from "ngx-google-analytics"; styleUrl: "./currency-select-box.component.scss", }) export class CurrencySelectBoxComponent implements OnInit { - @Input() chart: SalariesChart | null = null; @@ -22,45 +21,39 @@ export class CurrencySelectBoxComponent implements OnInit { currencies: Array | null = null; currencyDate: Date | null = null; - constructor( - private readonly gtag: GoogleAnalyticsService - ) {} + constructor(private readonly gtag: GoogleAnalyticsService) {} ngOnInit(): void { - if (!this.chart) { return; } this.currencies = this.chart.currencies; if (this.currencies.length === 0) { - this.currencies.push( - { - value: 1, - currency: CurrencyType.KZT, - currencyString: "тг", - pubDate: new Date(), - } - ); + this.currencies.push({ + value: 1, + currency: CurrencyType.KZT, + currencyString: "тг", + pubDate: new Date(), + }); } - this.currenciesAsItems = this.currencies - .map((x) => { - return { - value: CurrencyType[x.currency], - label: x.currency === CurrencyType.KZT + this.currenciesAsItems = this.currencies.map((x) => { + return { + value: CurrencyType[x.currency], + label: + x.currency === CurrencyType.KZT ? CurrencyType[x.currency] : `${CurrencyType[x.currency]} (${x.value} тг.)`, - item: x.currency, - }; - }); + item: x.currency, + }; + }); this.selectedCurrency = this.currenciesAsItems[0].item; this.currencyDate = this.currencies[0].pubDate; } onSelectionChange(e: SelectItem): void { - if (e == null) { // clear selection return; diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component.ts b/src/app/modules/salaries/components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component.ts index 01e4857d..e494c323 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/salaries-adding-chart/salaries-adding-chart.component.ts @@ -13,16 +13,13 @@ import { SalaryChartGlobalFiltersData } from "../../shared/global-filters-form-g styleUrl: "./salaries-adding-chart.component.scss", }) export class SalariesAddingChartComponent implements OnInit, OnDestroy { - @Input() filter: SalaryChartGlobalFiltersData | null = null; data: SalariesAddingTrendChart | null = null; chart: SalariesAddingChart | null = null; - constructor( - private readonly service: UserSalariesService - ) {} + constructor(private readonly service: UserSalariesService) {} ngOnInit(): void { this.chart = null; @@ -35,7 +32,10 @@ export class SalariesAddingChartComponent implements OnInit, OnDestroy { .pipe(untilDestroyed(this)) .subscribe((x) => { this.data = x; - this.chart = new SalariesAddingChart("canvas-adding-trend-chart", this.data); + this.chart = new SalariesAddingChart( + "canvas-adding-trend-chart", + this.data + ); }); } diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-by-grade/salaries-by-grade-block.component.html b/src/app/modules/salaries/components/salaries-chart/salaries-by-grade/salaries-by-grade-block.component.html index ee9b88b0..302c9a52 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-by-grade/salaries-by-grade-block.component.html +++ b/src/app/modules/salaries/components/salaries-chart/salaries-by-grade/salaries-by-grade-block.component.html @@ -3,8 +3,8 @@ Грейд - Медианная, {{currentCurrencyLabel}} - Средняя, {{currentCurrencyLabel}} + Медианная, {{ currentCurrencyLabel }} + Средняя, {{ currentCurrencyLabel }} Кол-во анкет diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-by-grade/salaries-by-grade-block.component.ts b/src/app/modules/salaries/components/salaries-chart/salaries-by-grade/salaries-by-grade-block.component.ts index f6cc002d..f001c4d1 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-by-grade/salaries-by-grade-block.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/salaries-by-grade/salaries-by-grade-block.component.ts @@ -31,7 +31,6 @@ export class SalariesByGradeBlockComponent implements OnInit, OnDestroy { currentCurrencyLabel: string | null = null; ngOnInit(): void { - if (this.chart == null) { this.items = []; return; @@ -50,7 +49,9 @@ export class SalariesByGradeBlockComponent implements OnInit, OnDestroy { } private recaulculate(): void { - const source = this.showLocal ? this.chart!.localSalariesByGrade : this.chart!.remoteSalariesByGrade; + const source = this.showLocal + ? this.chart!.localSalariesByGrade + : this.chart!.remoteSalariesByGrade; if (source == null) { this.items = []; return; @@ -66,8 +67,14 @@ export class SalariesByGradeBlockComponent implements OnInit, OnDestroy { hasData: x.hasData, averageSalary: x.averageSalary, medianSalary: x.medianSalary, - medianSalaryAsString: x.medianSalary != null ? formatNumber(x.medianSalary, "en-US", "1.0-2") : "", - averageSalaryAsString: x.averageSalary != null ? formatNumber(x.averageSalary, "en-US", "1.0-2") : "", + medianSalaryAsString: + x.medianSalary != null + ? formatNumber(x.medianSalary, "en-US", "1.0-2") + : "", + averageSalaryAsString: + x.averageSalary != null + ? formatNumber(x.averageSalary, "en-US", "1.0-2") + : "", }; }); } diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html index c3e29477..4b653f60 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html +++ b/src/app/modules/salaries/components/salaries-chart/salaries-chart.component.html @@ -209,8 +209,7 @@ (filtersReset)="resetGlobalFilters()" (shareClicked)="share($event)" > - +
@@ -334,7 +333,7 @@
+ >
diff --git a/src/app/modules/salaries/components/salaries-chart/salaries-chart.ts b/src/app/modules/salaries/components/salaries-chart/salaries-chart.ts index 589d2a87..c816dd1e 100644 --- a/src/app/modules/salaries/components/salaries-chart/salaries-chart.ts +++ b/src/app/modules/salaries/components/salaries-chart/salaries-chart.ts @@ -13,7 +13,6 @@ import { CurrencyData, CurrencyType } from "@services/admin-tools.service"; import { Subject } from "rxjs"; export class SalariesChart implements SalariesChartResponse { - private _averageSalary = 0; get averageSalary(): number { return this._averageSalary; @@ -54,17 +53,20 @@ export class SalariesChart implements SalariesChartResponse { return this._salariesByMoneyBarChart; } - private _salariesByMoneyBarChartForRemote: SalariesByMoneyBarChart | null = null; + private _salariesByMoneyBarChartForRemote: SalariesByMoneyBarChart | null = + null; get salariesByMoneyBarChartForRemote(): SalariesByMoneyBarChart | null { return this._salariesByMoneyBarChartForRemote; } - private _salariesPerProfessionForLocal: Array | null = null; + private _salariesPerProfessionForLocal: Array | null = + null; get salariesPerProfessionForLocal(): Array | null { return this._salariesPerProfessionForLocal; } - private _salariesPerProfessionForRemote: Array | null = null; + private _salariesPerProfessionForRemote: Array | null = + null; get salariesPerProfessionForRemote(): Array | null { return this._salariesPerProfessionForRemote; } @@ -83,7 +85,10 @@ export class SalariesChart implements SalariesChartResponse { readonly developersByExperienceYearsChartData: DevelopersByCategoryChartData | null; get hasRemoteSalaries(): boolean { - return this._salariesPerProfessionForRemote != null && this._salariesPerProfessionForRemote.length > 0 + return ( + this._salariesPerProfessionForRemote != null && + this._salariesPerProfessionForRemote.length > 0 + ); } readonly hasAuthentication: boolean; @@ -97,13 +102,13 @@ export class SalariesChart implements SalariesChartResponse { readonly rangeStart: Date; readonly rangeEnd: Date; - public readonly currentCurrencyChanged$: Subject = new Subject(); + public readonly currentCurrencyChanged$: Subject = + new Subject(); constructor( readonly data: SalariesChartResponse, readonly allProfessions: Array ) { - this.hasAuthentication = data.hasAuthentication; this.currencies = data.currencies; this.currentCurrency = this.getDefaultCurrency(); @@ -116,15 +121,19 @@ export class SalariesChart implements SalariesChartResponse { this.countOfRecords = data.totalCountInStats; this.developersByAgeChartData = data.developersByAgeChartData; - this.developersByExperienceYearsChartData = data.developersByExperienceYearsChartData; + this.developersByExperienceYearsChartData = + data.developersByExperienceYearsChartData; this.peopleByGradesChartDataForLocal = data.peopleByGradesChartDataForLocal; - this.peopleByGradesChartDataForRemote = data.peopleByGradesChartDataForRemote; + this.peopleByGradesChartDataForRemote = + data.peopleByGradesChartDataForRemote; this.recalculateData(data, allProfessions, this.currentCurrency); } public setCurrentCurrency(currencyType: CurrencyType): void { - this.currentCurrency = this.currencies.find((x) => x.currency === currencyType) ?? this.getDefaultCurrency(); + this.currentCurrency = + this.currencies.find((x) => x.currency === currencyType) ?? + this.getDefaultCurrency(); this.recalculateData(this.data, this.allProfessions, this.currentCurrency); this.currentCurrencyChanged$.next(this.currentCurrency); } @@ -142,13 +151,14 @@ export class SalariesChart implements SalariesChartResponse { } private getDefaultCurrency(): CurrencyData { - return this.currencies.find((x) => x.currency === CurrencyType.KZT) - ?? { - value: 1, - currency: CurrencyType.KZT, - currencyString: "тг", - pubDate: new Date(), - }; + return ( + this.currencies.find((x) => x.currency === CurrencyType.KZT) ?? { + value: 1, + currency: CurrencyType.KZT, + currencyString: "тг", + pubDate: new Date(), + } + ); } private recalculateData( @@ -156,7 +166,6 @@ export class SalariesChart implements SalariesChartResponse { allProfessions: Array, currentCurrency: CurrencyData ): void { - this._salaries = data.salaries.map((x) => { x.value = x.value / currentCurrency.value; return x; @@ -165,7 +174,8 @@ export class SalariesChart implements SalariesChartResponse { this._currentUserSalary = data.currentUserSalary; if (data.currentUserSalary != null) { this._currentUserSalary = { ...data.currentUserSalary }; - this._currentUserSalary!.value = data.currentUserSalary.value / currentCurrency.value; + this._currentUserSalary!.value = + data.currentUserSalary.value / currentCurrency.value; } this._averageSalary = data.averageSalary / currentCurrency.value; @@ -174,8 +184,14 @@ export class SalariesChart implements SalariesChartResponse { if (data.localSalariesByGrade != null) { this._localSalariesByGrade = data.localSalariesByGrade.map((x) => { const result = { ...x }; - result.averageSalary = x.averageSalary != null ? x.averageSalary / currentCurrency.value : null; - result.medianSalary = x.medianSalary != null ? x.medianSalary / currentCurrency.value : null; + result.averageSalary = + x.averageSalary != null + ? x.averageSalary / currentCurrency.value + : null; + result.medianSalary = + x.medianSalary != null + ? x.medianSalary / currentCurrency.value + : null; return result; }); } else { @@ -185,26 +201,38 @@ export class SalariesChart implements SalariesChartResponse { if (data.remoteSalariesByGrade != null) { this._remoteSalariesByGrade = data.remoteSalariesByGrade.map((x) => { const result = { ...x }; - result.averageSalary = x.averageSalary != null ? x.averageSalary / currentCurrency.value : null; - result.medianSalary = x.medianSalary != null ? x.medianSalary / currentCurrency.value : null; + result.averageSalary = + x.averageSalary != null + ? x.averageSalary / currentCurrency.value + : null; + result.medianSalary = + x.medianSalary != null + ? x.medianSalary / currentCurrency.value + : null; return result; }); } else { this._remoteSalariesByGrade = []; } - this._averageRemoteSalary = data.averageRemoteSalary != null - ? data.averageRemoteSalary / currentCurrency.value - : null; + this._averageRemoteSalary = + data.averageRemoteSalary != null + ? data.averageRemoteSalary / currentCurrency.value + : null; - this._medianRemoteSalary = data.medianRemoteSalary != null - ? data.medianRemoteSalary / currentCurrency.value - : null; + this._medianRemoteSalary = + data.medianRemoteSalary != null + ? data.medianRemoteSalary / currentCurrency.value + : null; this._salariesByMoneyBarChart = data.salariesByMoneyBarChart; - this._salariesByMoneyBarChartForRemote = data.salariesByMoneyBarChartForRemote; + this._salariesByMoneyBarChartForRemote = + data.salariesByMoneyBarChartForRemote; - const salariesPerProfession = SalariesPerProfession.from(this._salaries, allProfessions); + const salariesPerProfession = SalariesPerProfession.from( + this._salaries, + allProfessions + ); this._salariesPerProfessionForLocal = salariesPerProfession.local; this._salariesPerProfessionForRemote = salariesPerProfession.remote; diff --git a/src/app/modules/salaries/components/salaries-chart/salary-block-remote-value/salary-block-remote-value.component.ts b/src/app/modules/salaries/components/salaries-chart/salary-block-remote-value/salary-block-remote-value.component.ts index d992ed33..1f5af376 100644 --- a/src/app/modules/salaries/components/salaries-chart/salary-block-remote-value/salary-block-remote-value.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/salary-block-remote-value/salary-block-remote-value.component.ts @@ -12,15 +12,18 @@ export class SalaryBlockRemoteValueComponent { source: SalariesChart | null = null; get median(): string { - return SalaryBlockRemoteValueComponent.formatNumber(this.source?.medianRemoteSalary); + return SalaryBlockRemoteValueComponent.formatNumber( + this.source?.medianRemoteSalary + ); } get average(): string { - return SalaryBlockRemoteValueComponent.formatNumber(this.source?.averageRemoteSalary); + return SalaryBlockRemoteValueComponent.formatNumber( + this.source?.averageRemoteSalary + ); } private static formatNumber(value: number | null | undefined): string { - if (value == null) { return ""; } diff --git a/src/app/modules/salaries/components/salaries-chart/salary-block-value/salary-block-value.component.html b/src/app/modules/salaries/components/salaries-chart/salary-block-value/salary-block-value.component.html index cb3496b8..edd4cf70 100644 --- a/src/app/modules/salaries/components/salaries-chart/salary-block-value/salary-block-value.component.html +++ b/src/app/modules/salaries/components/salaries-chart/salary-block-value/salary-block-value.component.html @@ -3,7 +3,7 @@
Медианная зарплата в местных компаниях
{{ median }} - {{currentCurrencyLabel}} + {{ currentCurrencyLabel }}
@@ -11,7 +11,7 @@
Средняя зарплата
{{ average }} - {{currentCurrencyLabel}} + {{ currentCurrencyLabel }}
@@ -19,7 +19,7 @@
Медианная на удаленке
{{ medianRemote }} - {{currentCurrencyLabel}} + {{ currentCurrencyLabel }}
@@ -27,7 +27,7 @@
Средняя на удаленке
{{ averageRemote }} - {{currentCurrencyLabel}} + {{ currentCurrencyLabel }}
diff --git a/src/app/modules/salaries/components/salaries-chart/salary-block-value/salary-block-value.component.ts b/src/app/modules/salaries/components/salaries-chart/salary-block-value/salary-block-value.component.ts index b27af83e..2b05ccab 100644 --- a/src/app/modules/salaries/components/salaries-chart/salary-block-value/salary-block-value.component.ts +++ b/src/app/modules/salaries/components/salaries-chart/salary-block-value/salary-block-value.component.ts @@ -37,15 +37,22 @@ export class SalaryBlockValueComponent implements OnInit, OnDestroy { return; } - this.median = SalaryBlockValueComponent.formatNumber(this.source.medianSalary); - this.average = SalaryBlockValueComponent.formatNumber(this.source.averageSalary); - this.medianRemote = SalaryBlockValueComponent.formatNumber(this.source.medianRemoteSalary); - this.averageRemote = SalaryBlockValueComponent.formatNumber(this.source.averageRemoteSalary); + this.median = SalaryBlockValueComponent.formatNumber( + this.source.medianSalary + ); + this.average = SalaryBlockValueComponent.formatNumber( + this.source.averageSalary + ); + this.medianRemote = SalaryBlockValueComponent.formatNumber( + this.source.medianRemoteSalary + ); + this.averageRemote = SalaryBlockValueComponent.formatNumber( + this.source.averageRemoteSalary + ); this.currentCurrencyLabel = this.source.getCurrentCurrencyLabel(); } private static formatNumber(value: number | null | undefined): string { - if (value == null) { return ""; } diff --git a/src/app/modules/salaries/components/salaries-paginated-table/salaries-paginated-table.component.html b/src/app/modules/salaries/components/salaries-paginated-table/salaries-paginated-table.component.html index a354b085..27319019 100644 --- a/src/app/modules/salaries/components/salaries-paginated-table/salaries-paginated-table.component.html +++ b/src/app/modules/salaries/components/salaries-paginated-table/salaries-paginated-table.component.html @@ -20,20 +20,22 @@ - {{ item.value | number: "1.0-0" }} + {{ item.value | number : "1.0-0" }} {{ item.quarter }}.{{ item.year }} {{ item.age }} {{ item.gender }} {{ item.yearOfStartingWork }} {{ item.profession }} - + {{ item.company }} {{ item.city }} {{ item.skill }} {{ item.industry }} - {{ item.createdAt | date: "yyyy-MM-dd HH:mm" }} + {{ item.createdAt | date : "yyyy-MM-dd HH:mm" }} diff --git a/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart.component.html b/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart.component.html index 32cfd60b..6fa8e17b 100644 --- a/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart.component.html +++ b/src/app/modules/salaries/components/salaries-skills-chart/salaries-skills-chart.component.html @@ -57,7 +57,7 @@ {{ item.title }} {{ item.value }} - {{ item.part | number: "1.3" }}% + {{ item.part | number : "1.3" }}% Всего анкет с данными diff --git a/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.html b/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.html index 50eff731..2f4f438b 100644 --- a/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.html +++ b/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.html @@ -1,21 +1,14 @@ - - \ No newline at end of file + diff --git a/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.scss b/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.scss index a1b36caa..7259cf35 100644 --- a/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.scss +++ b/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.scss @@ -1,7 +1,7 @@ .radiobutton-group { - cursor: pointer; + cursor: pointer; } .form-check-label { - cursor: pointer; + cursor: pointer; } diff --git a/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.ts b/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.ts index 0af805e0..8a264af1 100644 --- a/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.ts +++ b/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-block.component.ts @@ -10,7 +10,6 @@ import { GoogleAnalyticsService } from "ngx-google-analytics"; styleUrl: "./salaries-survey-block.component.scss", }) export class SalariesSurveyBlockComponent implements OnInit { - showThankYouBlock = false; formGroup: SalariesSurveyForm | null = null; diff --git a/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-form.ts b/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-form.ts index a1196645..fa2d7db7 100644 --- a/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-form.ts +++ b/src/app/modules/salaries/components/salaries-survey-block/salaries-survey-form.ts @@ -1,81 +1,90 @@ import { FormControl, FormGroup, Validators } from "@angular/forms"; -import { ExpectationReplyType, SalariesStatSurveyData, UsefulnessReplyType } from "@services/salaries-survey.service"; +import { + ExpectationReplyType, + SalariesStatSurveyData, + UsefulnessReplyType, +} from "@services/salaries-survey.service"; export interface CheckboxRadioOption { - value: TEnum; - label: string; + value: TEnum; + label: string; } export class SalariesSurveyForm extends FormGroup { + readonly usefullnessReplyOptions: Array< + CheckboxRadioOption + > = [ + { + label: "Да", + value: UsefulnessReplyType.Yes, + }, + { + label: "Нет", + value: UsefulnessReplyType.No, + }, + { + label: "Не знаю", + value: UsefulnessReplyType.NotSure, + }, + ]; - readonly usefullnessReplyOptions: Array> = [ - { - label: "Да", - value: UsefulnessReplyType.Yes, - }, - { - label: "Нет", - value: UsefulnessReplyType.No, - }, - { - label: "Не знаю", - value: UsefulnessReplyType.NotSure, - }, - ]; + readonly expectationReplyOptions: Array< + CheckboxRadioOption + > = [ + { + label: "Зарплаты такие, как и предполагал(а)", + value: ExpectationReplyType.Expected, + }, + { + label: "Я думал(а), что зарплаты меньше", + value: ExpectationReplyType.MoreThanExpected, + }, + { + label: "Я думал(а), что зарплаты выше", + value: ExpectationReplyType.LessThanExpected, + }, + ]; - readonly expectationReplyOptions: Array> = [ - { - label: "Зарплаты такие, как и предполагал(а)", - value: ExpectationReplyType.Expected, - }, - { - label: "Я думал(а), что зарплаты меньше", - value: ExpectationReplyType.MoreThanExpected, - }, - { - label: "Я думал(а), что зарплаты выше", - value: ExpectationReplyType.LessThanExpected, - }, - ]; + constructor() { + super({ + usefulnessReply: new FormControl(null, [Validators.required]), + expectationReply: new FormControl(null, [Validators.required]), + }); + } - constructor() { - super({ - usefulnessReply: new FormControl(null, [Validators.required]), - expectationReply: new FormControl(null, [Validators.required]), - }); - } + onCheckUsefulnessReply(data: any): void { + const value = data.target.value as UsefulnessReplyType; + this.get("usefulnessReply")?.setValue(value); + } - onCheckUsefulnessReply(data: any): void { - const value = data.target.value as UsefulnessReplyType; - this.get("usefulnessReply")?.setValue(value); - } + onCheckExpectationReply(data: any): void { + const value = data.target.value as ExpectationReplyType; + this.get("expectationReply")?.setValue(value); + } - onCheckExpectationReply(data: any): void { - const value = data.target.value as ExpectationReplyType; - this.get("expectationReply")?.setValue(value); + requestOrNull(): SalariesStatSurveyData | null { + if (!this.valid) { + this.markAllAsTouched(); + return null; } - requestOrNull(): SalariesStatSurveyData | null { - - if (!this.valid) { - this.markAllAsTouched(); - return null; - } - - const usefulnessReply = this.get("usefulnessReply")?.value; - const expectationReply = this.get("expectationReply")?.value; + const usefulnessReply = this.get("usefulnessReply")?.value; + const expectationReply = this.get("expectationReply")?.value; - if (usefulnessReply == null || - expectationReply == null) { - return null; - } + if (usefulnessReply == null || expectationReply == null) { + return null; + } - const usefulnessReplyAsEnum = Number(usefulnessReply) as UsefulnessReplyType; - const expectationReplyAsEnum = Number(expectationReply) as ExpectationReplyType; + const usefulnessReplyAsEnum = Number( + usefulnessReply + ) as UsefulnessReplyType; + const expectationReplyAsEnum = Number( + expectationReply + ) as ExpectationReplyType; - return { - usefulnessReply: usefulnessReplyAsEnum, - expectationReply: expectationReplyAsEnum, - }; - } -} \ No newline at end of file + return { + usefulnessReply: usefulnessReplyAsEnum, + expectationReply: expectationReplyAsEnum, + }; + } +} diff --git a/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.html b/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.html index b7f9e16d..897a0f8e 100644 --- a/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.html +++ b/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.html @@ -1,13 +1,10 @@ Опрос о пользе зарплатной статистики
-
-
-
Спасибо за обратную связь!
@@ -15,7 +12,8 @@ Вы уже оставили когда-то свое мнение о предоставленной статистике.
- Ниже представлена общая статистика по результатам опроса. Посмотрите, как много людей думают так же, как вы. + Ниже представлена общая статистика по результатам опроса. + Посмотрите, как много людей думают так же, как вы.
@@ -23,7 +21,7 @@ Кол-во ответов: {{ data.countOfRecords }}
- +
Полезность статистики
@@ -45,15 +43,17 @@
- - Значения: - + Значения: {{ item.label }} + class="ms-2 badge rounded-pill {{ item.cssBackground }} {{ + item.cssText + }}" + >{{ item.label }}
- +
Ожидания респондентов от статистики
@@ -75,33 +75,32 @@
- - Значения: - + Значения: {{ item.label }} + class="ms-2 px-3 badge rounded-pill {{ item.cssBackground }} {{ + item.cssText + }}" + >{{ item.label }}
-
- Нам важно мнение пользователей о предоставленной статистике. - Интересно взглянуть на то, как респонденты оценивают свою зарплату и какие ожидания у них относительно рынка труда в Казахстане. -
-
- Пожалуйста, примите участие в опросе. + Нам важно мнение пользователей о предоставленной статистике. Интересно + взглянуть на то, как респонденты оценивают свою зарплату и какие + ожидания у них относительно рынка труда в Казахстане.
+
Пожалуйста, примите участие в опросе.
+ >
- diff --git a/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.scss b/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.scss index 996b8c75..2c7e5c12 100644 --- a/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.scss +++ b/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.scss @@ -1,8 +1,8 @@ .progress-bar { - min-height: 30px; + min-height: 30px; } .progress { - min-height: 30px; - cursor: pointer; -} \ No newline at end of file + min-height: 30px; + cursor: pointer; +} diff --git a/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.ts b/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.ts index 18eabb6d..0b3cbcbf 100644 --- a/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.ts +++ b/src/app/modules/salaries/components/salaries-survey-page/salaries-survey-page.component.ts @@ -1,6 +1,13 @@ import { Component, OnDestroy, OnInit } from "@angular/core"; import { Router } from "@angular/router"; -import { ExpectationReplyType, GetUserSalariesSurveyDataResponse, SalariesSurveyReplyDataItem, SalariesSurveyStatData, SurveyService, UsefulnessReplyType } from "@services/salaries-survey.service"; +import { + ExpectationReplyType, + GetUserSalariesSurveyDataResponse, + SalariesSurveyReplyDataItem, + SalariesSurveyStatData, + SurveyService, + UsefulnessReplyType, +} from "@services/salaries-survey.service"; import { TitleService } from "@services/title.service"; import { AuthService } from "@shared/services/auth/auth.service"; import { CookieService } from "ngx-cookie-service"; @@ -29,7 +36,6 @@ interface ProgressBarColorData { styleUrls: ["./salaries-survey-page.component.scss"], }) export class SalariesSurveyPageComponent implements OnInit, OnDestroy { - static readonly defaultColor: ProgressBarColorData = { label: "Нет данных", cssBackground: "bg-light", @@ -43,44 +49,60 @@ export class SalariesSurveyPageComponent implements OnInit, OnDestroy { UsefulnessReplyType, ProgressBarColorData > = new Map([ - [UsefulnessReplyType.Yes, { + [ + UsefulnessReplyType.Yes, + { label: "Да", cssBackground: "bg-success", cssText: "", - } + }, + ], + [ + UsefulnessReplyType.No, + { + label: "Нет", + cssBackground: "bg-warning", + cssText: "text-dark", + }, + ], + [ + UsefulnessReplyType.NotSure, + { + label: "Не уверен", + cssBackground: "bg-light border border-2", + cssText: "text-dark", + }, ], - [UsefulnessReplyType.No, { - label: "Нет", - cssBackground: "bg-warning", - cssText: "text-dark", - }], - [UsefulnessReplyType.NotSure, { - label: "Не уверен", - cssBackground: "bg-light border border-2", - cssText: "text-dark", - }], ]); static readonly colorsByExpectation: Map< ExpectationReplyType, ProgressBarColorData - > = new Map([ - [ExpectationReplyType.Expected, { + > = new Map([ + [ + ExpectationReplyType.Expected, + { label: "Ожидаемо", cssBackground: "bg-info", cssText: "text-dark", - } + }, + ], + [ + ExpectationReplyType.MoreThanExpected, + { + label: "Выше ожидаемого", + cssBackground: "bg-success", + cssText: "", + }, + ], + [ + ExpectationReplyType.LessThanExpected, + { + label: "Ниже ожидаемого", + cssBackground: "bg-warning", + cssText: "text-dark", + }, ], - [ExpectationReplyType.MoreThanExpected, { - label: "Выше ожидаемого", - cssBackground: "bg-success", - cssText: "", - }], - [ExpectationReplyType.LessThanExpected, { - label: "Ниже ожидаемого", - cssBackground: "bg-warning", - cssText: "text-dark", - }], ]); data: SalariesSurveyStatData | null = null; @@ -103,27 +125,41 @@ export class SalariesSurveyPageComponent implements OnInit, OnDestroy { titleService.setTitle("Опрос о пользе зарплатной статистики"); this.usefullnesLegendItems = [ - SalariesSurveyPageComponent.colorsByUsefulness.get(UsefulnessReplyType.Yes) ?? SalariesSurveyPageComponent.defaultColor, - SalariesSurveyPageComponent.colorsByUsefulness.get(UsefulnessReplyType.No) ?? SalariesSurveyPageComponent.defaultColor, - SalariesSurveyPageComponent.colorsByUsefulness.get(UsefulnessReplyType.NotSure) ?? SalariesSurveyPageComponent.defaultColor, + SalariesSurveyPageComponent.colorsByUsefulness.get( + UsefulnessReplyType.Yes + ) ?? SalariesSurveyPageComponent.defaultColor, + SalariesSurveyPageComponent.colorsByUsefulness.get( + UsefulnessReplyType.No + ) ?? SalariesSurveyPageComponent.defaultColor, + SalariesSurveyPageComponent.colorsByUsefulness.get( + UsefulnessReplyType.NotSure + ) ?? SalariesSurveyPageComponent.defaultColor, ]; this.expectationLegendItems = [ - SalariesSurveyPageComponent.colorsByExpectation.get(ExpectationReplyType.Expected) ?? SalariesSurveyPageComponent.defaultColor, - SalariesSurveyPageComponent.colorsByExpectation.get(ExpectationReplyType.MoreThanExpected) ?? SalariesSurveyPageComponent.defaultColor, - SalariesSurveyPageComponent.colorsByExpectation.get(ExpectationReplyType.LessThanExpected) ?? SalariesSurveyPageComponent.defaultColor, + SalariesSurveyPageComponent.colorsByExpectation.get( + ExpectationReplyType.Expected + ) ?? SalariesSurveyPageComponent.defaultColor, + SalariesSurveyPageComponent.colorsByExpectation.get( + ExpectationReplyType.MoreThanExpected + ) ?? SalariesSurveyPageComponent.defaultColor, + SalariesSurveyPageComponent.colorsByExpectation.get( + ExpectationReplyType.LessThanExpected + ) ?? SalariesSurveyPageComponent.defaultColor, ]; } - + ngOnInit(): void { - if (this.authService.isAuthenticated()) { - this.service.getUserSalariesSurveyDataResponse() + if (this.authService.isAuthenticated()) { + this.service + .getUserSalariesSurveyDataResponse() .pipe(untilDestroyed(this)) .subscribe((data) => { this.userData = data; if (data.hasRecentSurveyReply) { - this.service.getSalariesStatSurveyData() + this.service + .getSalariesStatSurveyData() .pipe(untilDestroyed(this)) .subscribe((x) => { this.data = x; @@ -134,7 +170,7 @@ export class SalariesSurveyPageComponent implements OnInit, OnDestroy { } }); - return; + return; } this.cookieService.set("url", this.router.url); @@ -162,7 +198,8 @@ export class SalariesSurveyPageComponent implements OnInit, OnDestroy { this.data.countOfRecords, this.showPercents, (replyType) => { - const colorData = SalariesSurveyPageComponent.colorsByUsefulness.get(replyType); + const colorData = + SalariesSurveyPageComponent.colorsByUsefulness.get(replyType); return colorData ?? SalariesSurveyPageComponent.defaultColor; } ); @@ -172,7 +209,8 @@ export class SalariesSurveyPageComponent implements OnInit, OnDestroy { this.data.countOfRecords, this.showPercents, (replyType) => { - const colorData = SalariesSurveyPageComponent.colorsByExpectation.get(replyType); + const colorData = + SalariesSurveyPageComponent.colorsByExpectation.get(replyType); return colorData ?? SalariesSurveyPageComponent.defaultColor; } ); @@ -184,29 +222,26 @@ export class SalariesSurveyPageComponent implements OnInit, OnDestroy { showPercents: boolean, giveColorData: (replyType: TEnum) => ProgressBarColorData ): Array { - var result: Array = []; - data - .forEach((item, index) => { - - const colorData = giveColorData(item.replyType); - const value = showPercents - ? formatNumber(item.data.partitionInPercent, "en-US", "1.0-2") + "%" - : formatNumber(item.data.countOfReplies, "en-US", "1.0-0"); - - const maxValue = showPercents - ? "100" - : formatNumber(totalCount, "en-US", "1.0-0"); - - result.push({ - color: colorData.cssBackground, - textColor: colorData.cssText, - value: value, - maxValue: maxValue, - width: item.data.partitionInPercent, - label: colorData.label, - }); + data.forEach((item, index) => { + const colorData = giveColorData(item.replyType); + const value = showPercents + ? formatNumber(item.data.partitionInPercent, "en-US", "1.0-2") + "%" + : formatNumber(item.data.countOfReplies, "en-US", "1.0-0"); + + const maxValue = showPercents + ? "100" + : formatNumber(totalCount, "en-US", "1.0-0"); + + result.push({ + color: colorData.cssBackground, + textColor: colorData.cssText, + value: value, + maxValue: maxValue, + width: item.data.partitionInPercent, + label: colorData.label, }); + }); return result; } diff --git a/src/app/modules/salaries/components/work-industries-chart/work-industries-chart.component.html b/src/app/modules/salaries/components/work-industries-chart/work-industries-chart.component.html index b1223176..22eb35a7 100644 --- a/src/app/modules/salaries/components/work-industries-chart/work-industries-chart.component.html +++ b/src/app/modules/salaries/components/work-industries-chart/work-industries-chart.component.html @@ -56,7 +56,7 @@ {{ item.title }} {{ item.value }} - {{ item.part | number: "1.3" }}% + {{ item.part | number : "1.3" }}% Всего анкет с данными diff --git a/src/app/modules/salaries/salaries-routing.module.ts b/src/app/modules/salaries/salaries-routing.module.ts index 3a9aa315..dc7ee2b4 100644 --- a/src/app/modules/salaries/salaries-routing.module.ts +++ b/src/app/modules/salaries/salaries-routing.module.ts @@ -14,7 +14,7 @@ const routes: Routes = [ component: SalariesSurveyPageComponent, }, { - path: 'historical-data', + path: "historical-data", component: HistoricalChartsPageComponent, }, ]; diff --git a/src/app/modules/salaries/salaries.module.ts b/src/app/modules/salaries/salaries.module.ts index 731964e5..70c5f964 100644 --- a/src/app/modules/salaries/salaries.module.ts +++ b/src/app/modules/salaries/salaries.module.ts @@ -59,7 +59,7 @@ import { HistoricalSalariesByGradeChartComponent } from "./components/historical CurrencySelectBoxComponent, HistoricalChartsPageComponent, HistoricalSalariesChartComponent, - HistoricalSalariesByGradeChartComponent + HistoricalSalariesByGradeChartComponent, ], imports: [ CommonModule, diff --git a/src/app/services/historical-charts.service.ts b/src/app/services/historical-charts.service.ts index 2f5928a1..7ae852b9 100644 --- a/src/app/services/historical-charts.service.ts +++ b/src/app/services/historical-charts.service.ts @@ -7,13 +7,14 @@ import { KazakhstanCity } from "@models/salaries/kazakhstan-city"; export interface SalariesCountWeekByWeekChartItem { totalCount: number; - localMedian: number, - localAverage: number, - remoteMedian: number, - remoteAverage: number, + localMedian: number; + localAverage: number; + remoteMedian: number; + remoteAverage: number; } -export interface SalariesCountWeekByWeekChartGradeItem extends SalariesCountWeekByWeekChartItem { +export interface SalariesCountWeekByWeekChartGradeItem + extends SalariesCountWeekByWeekChartItem { grade: DeveloperGrade; } @@ -50,8 +51,11 @@ export class HistoricalChartsService { this.apiUrl = `/api/historical-charts/`; } - salariesChart(params: SalariesChartFilterData): Observable { + salariesChart( + params: SalariesChartFilterData + ): Observable { return this.api.get( - this.apiUrl + 'salaries?' + new ConvertObjectToHttpParams(params).get()); + this.apiUrl + "salaries?" + new ConvertObjectToHttpParams(params).get() + ); } } diff --git a/src/app/services/meta-tags.service.ts b/src/app/services/meta-tags.service.ts index ce2dc3d9..60d85e01 100644 --- a/src/app/services/meta-tags.service.ts +++ b/src/app/services/meta-tags.service.ts @@ -4,49 +4,47 @@ import { environment } from "@environments/environment"; import { TitleService } from "@services/title.service"; @Injectable({ - providedIn: 'root' + providedIn: "root", }) export class MetaTagService { constructor( private readonly title: TitleService, - private readonly meta: Meta) {} - - updateChartMetaTags( - title: string, - description: string, - url: string): void { + private readonly meta: Meta + ) {} + updateChartMetaTags(title: string, description: string, url: string): void { this.title.setTitle(title); - url = url.startsWith('/') ? url : `/${url}`; + url = url.startsWith("/") ? url : `/${url}`; this.removeTags(); this.meta.addTags([ - { property: 'og:title', content: title }, - { name: 'twitter:title', content: title }, + { property: "og:title", content: title }, + { name: "twitter:title", content: title }, - { name: 'description', content: description }, - { property: 'og:description', content: description }, - { name: 'twitter:description', content: description }, + { name: "description", content: description }, + { property: "og:description", content: description }, + { name: "twitter:description", content: description }, - { property: 'og:url', content: environment.baseUrl + url }, + { property: "og:url", content: environment.baseUrl + url }, ]); } returnDefaultMetaTags(): void { this.removeTags(); - const title = 'Techinterview.space'; - const description = 'Зарплаты в IT в Казахстане. Цифры, графики, фильтр. Всё как все мы любим'; + const title = "Techinterview.space"; + const description = + "Зарплаты в IT в Казахстане. Цифры, графики, фильтр. Всё как все мы любим"; this.meta.addTags([ - { property: 'og:title', content: title }, - { name: 'twitter:title', content: title }, + { property: "og:title", content: title }, + { name: "twitter:title", content: title }, - { name: 'description', content: description }, - { property: 'og:description', content: description }, - { name: 'twitter:description', content: description }, + { name: "description", content: description }, + { property: "og:description", content: description }, + { name: "twitter:description", content: description }, - { property: 'og:url', content: environment.baseUrl }, + { property: "og:url", content: environment.baseUrl }, ]); } diff --git a/src/app/services/salaries-survey.service.ts b/src/app/services/salaries-survey.service.ts index 2acdadf5..a5c11e64 100644 --- a/src/app/services/salaries-survey.service.ts +++ b/src/app/services/salaries-survey.service.ts @@ -4,27 +4,27 @@ import { Observable } from "rxjs"; import { ApiService } from "./api.service"; export enum UsefulnessReplyType { - Undefined = 0, - Yes = 1, - No = 2, - NotSure = 3, + Undefined = 0, + Yes = 1, + No = 2, + NotSure = 3, } export enum ExpectationReplyType { - Undefined = 0, - Expected = 1, - MoreThanExpected = 2, - LessThanExpected = 3, + Undefined = 0, + Expected = 1, + MoreThanExpected = 2, + LessThanExpected = 3, } export interface SalariesStatSurveyData { - usefulnessReply: UsefulnessReplyType; - expectationReply: ExpectationReplyType; + usefulnessReply: UsefulnessReplyType; + expectationReply: ExpectationReplyType; } export interface SalariesStatSurveyReply extends SalariesStatSurveyData { - id: string; - createdAt: Date; + id: string; + createdAt: Date; } export interface SalariesSurveyStatDataItem { @@ -57,14 +57,21 @@ export class SurveyService { } getUserSalariesSurveyDataResponse(): Observable { - return this.api.get(this.apiUrl + 'salaries-user-stat-data'); + return this.api.get( + this.apiUrl + "salaries-user-stat-data" + ); } - salariesSatGapeReply(data: SalariesStatSurveyData): Observable { - return this.api.post(this.apiUrl + 'salaries-stat-page-reply', data); + salariesSatGapeReply( + data: SalariesStatSurveyData + ): Observable { + return this.api.post( + this.apiUrl + "salaries-stat-page-reply", + data + ); } getSalariesStatSurveyData(): Observable { - return this.api.get(this.apiUrl + 'salaries-stats'); + return this.api.get(this.apiUrl + "salaries-stats"); } } diff --git a/src/app/services/user-salaries.service.ts b/src/app/services/user-salaries.service.ts index 9ad4407d..6c3f5ed8 100644 --- a/src/app/services/user-salaries.service.ts +++ b/src/app/services/user-salaries.service.ts @@ -188,8 +188,9 @@ export class UserSalariesService { params: SalariesAddingTrendChartParams ): Observable { return this.api.get( - this.root + "salaries-adding-trend-chart?" + - new ConvertObjectToHttpParams(params).get() + this.root + + "salaries-adding-trend-chart?" + + new ConvertObjectToHttpParams(params).get() ); } diff --git a/src/app/shared/components/developer-grade-label/developer-grade-label.component.scss b/src/app/shared/components/developer-grade-label/developer-grade-label.component.scss index 5e020ca2..4663a802 100644 --- a/src/app/shared/components/developer-grade-label/developer-grade-label.component.scss +++ b/src/app/shared/components/developer-grade-label/developer-grade-label.component.scss @@ -1,7 +1,7 @@ .badge { - cursor: pointer; + cursor: pointer; - &:hover { - filter: brightness(85%); - } -} \ No newline at end of file + &:hover { + filter: brightness(85%); + } +} diff --git a/src/app/shared/test-utils/mock-google-analytics.service.ts b/src/app/shared/test-utils/mock-google-analytics.service.ts index 2a25e04d..af7252ad 100644 --- a/src/app/shared/test-utils/mock-google-analytics.service.ts +++ b/src/app/shared/test-utils/mock-google-analytics.service.ts @@ -3,7 +3,7 @@ import { GoogleAnalyticsService } from "ngx-google-analytics"; @Injectable() export class MockGoogleAnalyticsService extends GoogleAnalyticsService { - override gtag(...args: any[]): void { - return; - } + override gtag(...args: any[]): void { + return; + } } diff --git a/src/index.html b/src/index.html index f5cd23a9..d103b96e 100644 --- a/src/index.html +++ b/src/index.html @@ -10,36 +10,44 @@ + content="Зарплаты в IT в Казахстане. Цифры, графики, фильтр. Всё как все мы любим" + /> + content="Зарплаты в IT в Казахстане. Цифры, графики, фильтр. Всё как все мы любим" + /> + content="salaries, statistic, technical interview, interview, coding" + /> + content="Зарплаты в IT в Казахстане. Цифры, графики, фильтр. Всё как все мы любим" + /> + content="https://techinterview.fra1.cdn.digitaloceanspaces.com/images/main_charts_500.png" + /> + content="https://techinterview.fra1.cdn.digitaloceanspaces.com/images/main_charts_500.png" + /> + content="https://techinterview.fra1.cdn.digitaloceanspaces.com/images/main_charts_500.png" + /> + content="Зарплаты в IT в Казахстане. Цифры, графики, фильтр. Всё как все мы любим" + /> @@ -86,7 +94,8 @@ href="https://techhunter.kz" target="_blank" title="Портал вакансий в IT в Казахстане" - rel="noopener noreferrer"> + rel="noopener noreferrer" + > Вакансии на techhunter.kz
diff --git a/src/test.ts b/src/test.ts index 93f0f52c..2bc904d3 100644 --- a/src/test.ts +++ b/src/test.ts @@ -25,7 +25,7 @@ getTestBed().initTestEnvironment( ); beforeAll(() => { - window.onbeforeunload = () => 'Oh no!'; + window.onbeforeunload = () => "Oh no!"; }); // Then we find all the tests. From 36c486e268503bf3da7b666fae3abd02e5231c7c Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sat, 15 Jun 2024 18:00:42 +0500 Subject: [PATCH 8/9] Added labels --- .../historical-charts-page.component.html | 32 ++++++++++++++++++- .../historical-charts-page.component.ts | 3 +- ...rical-salaries-by-grade-chart.component.ts | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html index 73bdfbfd..46dc6847 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html @@ -1,8 +1,21 @@ Исторические данные
-
+
+
Тенденция изменения зарплат
+ +
+

+ Графики отображают тенденцию измнения зарплат за определенный отрезок + времени. График покажет 4 линии по оси Y слева на зарплатные значения: + медианная и средняя для компаний в Казахстане и на удаленке. Еще одна + линия по оси Y справа покажет, сколько было релевантных анкет на + определенный момент времени. +

+

Фильтр позволит ограничить выборку анкет по желаемым критериям.

+
+
+ + +
+
+
+ Доступ к статистике открыватся только после того, как пользователь + добавляет актуальную зарплату. Пожалуйста, перейдите по ссылке ниже, + чтобы перейти к форме заполнния анкеты. +
+ +
+
+
diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts index 2a1829a9..5b075cd0 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.ts @@ -4,7 +4,6 @@ import { TitleService } from "@services/title.service"; import { AuthService } from "@shared/services/auth/auth.service"; import { CookieService } from "ngx-cookie-service"; import { untilDestroyed } from "@shared/subscriptions/until-destroyed"; -import { formatNumber } from "@angular/common"; import { GoogleAnalyticsService } from "ngx-google-analytics"; import { GetSalariesHistoricalChartResponse, @@ -31,6 +30,7 @@ export class HistoricalChartsPageComponent implements OnInit, OnDestroy { data: GetSalariesHistoricalChartResponse | null = null; filterData = new SalaryChartGlobalFiltersData(); isAuthenticated = false; + shouldAddOwnSalary = false; skills: Array = []; industries: Array = []; @@ -155,6 +155,7 @@ export class HistoricalChartsPageComponent implements OnInit, OnDestroy { .subscribe((x) => { this.isAuthenticated = x.hasAuthentication; this.data = x; + this.shouldAddOwnSalary = x.shouldAddOwnSalary; }); } } diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts index 52e3fd65..0edc02d9 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart.component.ts @@ -24,7 +24,7 @@ export class HistoricalSalariesByGradeChartComponent implements OnInit { chart: HistoricalSalariesByGradeChartObject | null = null; ngOnInit(): void { - if (this.data == null) { + if (this.data == null || !this.data.hasGradeItems) { return; } From 88d0cb1f527b0fbdb9daae983a91e330fc898086 Mon Sep 17 00:00:00 2001 From: "maxim.gorbatyuk" Date: Sun, 16 Jun 2024 00:20:04 +0500 Subject: [PATCH 9/9] fix --- .../historical-charts-page.component.html | 2 +- .../historical-salaries-by-grade-chart-object.ts | 8 ++++---- .../historical-salaries-chart-object.ts | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html index 46dc6847..16cb7243 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html +++ b/src/app/modules/salaries/components/historical-charts-page/historical-charts-page.component.html @@ -32,7 +32,7 @@ />
-
+
diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart-object.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart-object.ts index cc68579a..e4b25302 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart-object.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-by-grade-chart/historical-salaries-by-grade-chart-object.ts @@ -143,7 +143,7 @@ export class HistoricalSalariesByGradeChartObject extends Chart { items.map((x) => x.localMedian), 2, new RandomRgbColor(), - false as PointStyle, + true as PointStyle, grade, "y", hidden @@ -153,7 +153,7 @@ export class HistoricalSalariesByGradeChartObject extends Chart { items.map((x) => x.localAverage), 2, new RandomRgbColor(), - false as PointStyle, + true as PointStyle, grade, "y", hidden @@ -163,7 +163,7 @@ export class HistoricalSalariesByGradeChartObject extends Chart { items.map((x) => x.remoteMedian), 2, new RandomRgbColor(), - false as PointStyle, + true as PointStyle, grade, "y", hidden @@ -173,7 +173,7 @@ export class HistoricalSalariesByGradeChartObject extends Chart { items.map((x) => x.remoteAverage), 2, new RandomRgbColor(), - false as PointStyle, + true as PointStyle, grade, "y", hidden diff --git a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts index e13b4a1a..a205bba4 100644 --- a/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts +++ b/src/app/modules/salaries/components/historical-charts-page/historical-salaries-chart/historical-salaries-chart-object.ts @@ -31,7 +31,7 @@ export class HistoricalSalariesChartObject extends Chart { chartData.totalCountItems.map((x) => x.localMedian), 2, new RandomRgbColor(), - false as PointStyle, + true as PointStyle, "y" ), new DatasetItem( @@ -39,7 +39,7 @@ export class HistoricalSalariesChartObject extends Chart { chartData.totalCountItems.map((x) => x.localAverage), 2, new RandomRgbColor(), - false as PointStyle, + true as PointStyle, "y" ), new DatasetItem( @@ -47,7 +47,7 @@ export class HistoricalSalariesChartObject extends Chart { chartData.totalCountItems.map((x) => x.remoteMedian), 2, new RandomRgbColor(), - false as PointStyle, + true as PointStyle, "y" ), new DatasetItem( @@ -55,7 +55,7 @@ export class HistoricalSalariesChartObject extends Chart { chartData.totalCountItems.map((x) => x.remoteAverage), 2, new RandomRgbColor(), - false as PointStyle, + true as PointStyle, "y" ), ];