From 93687dd17915782f995019d4422fded0e24774f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D0=B0=D1=83=D1=84=20=D0=9B=D0=B0=D1=82=D1=8B=D0=BF?= =?UTF-8?q?=D0=BE=D0=B2?= Date: Thu, 20 Feb 2025 14:06:08 +0300 Subject: [PATCH] =?UTF-8?q?SUPPORT-8904:=20=D0=B2=D1=81=D0=B5=20=D0=B4?= =?UTF-8?q?=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D0=B8=20=D0=BF=D0=BE?= =?UTF-8?q?=20=D0=B7=D0=B0=D0=B4=D0=B0=D1=87=D0=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chart/ErvuMultiChartDataSetService.java | 25 ++++++ .../model/chart/ColumnAggregationDataSet.java | 4 +- .../model/chart/ErvuChartDataSetDto.java | 26 +------ .../model/chart/round/RoundChartDataDto.java | 9 --- .../chart/round/RoundChartDataSetDto.java | 36 --------- .../round/RoundChartDataSetDtoWrapper.java | 12 +-- .../component/chart/ChartUtils.ts | 64 ++++++++++++++- .../component/chart/ErvuChartV2.ts | 39 ++++++---- .../component/chart/model/AxisGridSettings.ts | 15 +++- .../component/chart/model/AxisSettings.ts | 5 +- .../chart/model/AxisTicksSettings.ts | 9 ++- .../component/chart/model/Options.ts | 16 ++++ .../plugin/BackgroundColorChartPlugin.ts | 38 +++++++++ ...BarStackMiddleBorderRoundingChartPlugin.ts | 12 ++- .../component/chart/plugin/ChartPlugin.ts | 6 +- .../plugin/DarkBackgroundColorChartPlugin.ts | 77 +++++++++++++++++++ 16 files changed, 283 insertions(+), 110 deletions(-) create mode 100644 frontend/src/ts/ervu-dashboard/component/chart/model/Options.ts create mode 100644 frontend/src/ts/ervu-dashboard/component/chart/plugin/BackgroundColorChartPlugin.ts create mode 100644 frontend/src/ts/ervu-dashboard/component/chart/plugin/DarkBackgroundColorChartPlugin.ts diff --git a/backend/src/main/java/ru/micord/ervu_dashboard/component/chart/ErvuMultiChartDataSetService.java b/backend/src/main/java/ru/micord/ervu_dashboard/component/chart/ErvuMultiChartDataSetService.java index d99c114c..80376d0d 100644 --- a/backend/src/main/java/ru/micord/ervu_dashboard/component/chart/ErvuMultiChartDataSetService.java +++ b/backend/src/main/java/ru/micord/ervu_dashboard/component/chart/ErvuMultiChartDataSetService.java @@ -128,6 +128,18 @@ public class ErvuMultiChartDataSetService extends AbstractChartDatasetService im chartDataSetDto.setyAxisID(aggFuncData.yAxesId); chartDataSetDto.setTension(aggFuncData.tension); chartDataSetDto.setOrder(aggFuncData.drawOrder); + chartDataSetDto.setStack(aggFuncData.stack); + + chartDataSetDto.setBorderRadius(aggFuncData.borderRadius); + chartDataSetDto.setBorderWidth(aggFuncData.borderWidth); + chartDataSetDto.setBarPercentage(aggFuncData.barPercentage); + chartDataSetDto.setBarThickness(aggFuncData.barThickness); + chartDataSetDto.setCategoryPercentage(aggFuncData.categoryPercentage); + chartDataSetDto.setBorderDash(aggFuncData.borderDash); + chartDataSetDto.setBorderDashOffset(aggFuncData.borderDashOffset); + chartDataSetDto.setPointBorderWidth(aggFuncData.pointBorderWidth); + chartDataSetDto.setPointRadius(aggFuncData.pointRadius); + return chartDataSetDto; }).collect(Collectors.toList())).flatMap(Collection::stream).collect(Collectors.toList()); } @@ -165,6 +177,18 @@ public class ErvuMultiChartDataSetService extends AbstractChartDatasetService im chartDataSetDto.setyAxisID(staticChartData.yAxesId); chartDataSetDto.setTension(staticChartData.tension); chartDataSetDto.setOrder(staticChartData.drawOrder); + chartDataSetDto.setStack(staticChartData.stack); + + chartDataSetDto.setBorderRadius(staticChartData.borderRadius); + chartDataSetDto.setBorderWidth(staticChartData.borderWidth); + chartDataSetDto.setBarPercentage(staticChartData.barPercentage); + chartDataSetDto.setBarThickness(staticChartData.barThickness); + chartDataSetDto.setCategoryPercentage(staticChartData.categoryPercentage); + chartDataSetDto.setBorderDash(staticChartData.borderDash); + chartDataSetDto.setBorderDashOffset(staticChartData.borderDashOffset); + chartDataSetDto.setPointBorderWidth(staticChartData.pointBorderWidth); + chartDataSetDto.setPointRadius(staticChartData.pointRadius); + return chartDataSetDto; }).collect(Collectors.toList()); } @@ -205,6 +229,7 @@ public class ErvuMultiChartDataSetService extends AbstractChartDatasetService im chartDataSetDto.setyAxisID(dataSet.yAxesId); chartDataSetDto.setTension(dataSet.tension); chartDataSetDto.setOrder(dataSet.drawOrder); + chartDataSetDto.setStack(dataSet.stack); chartDataSetDto.setBorderRadius(dataSet.borderRadius); chartDataSetDto.setBarPercentage(dataSet.barPercentage); diff --git a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/ColumnAggregationDataSet.java b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/ColumnAggregationDataSet.java index 9526ed7f..a1f9635f 100644 --- a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/ColumnAggregationDataSet.java +++ b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/ColumnAggregationDataSet.java @@ -30,7 +30,9 @@ public class ColumnAggregationDataSet { public String yAxesId; - public Float tension; + public String tension; public Integer drawOrder; + + public String stack; } diff --git a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/ErvuChartDataSetDto.java b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/ErvuChartDataSetDto.java index eeb590d7..eb26e626 100644 --- a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/ErvuChartDataSetDto.java +++ b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/ErvuChartDataSetDto.java @@ -10,36 +10,12 @@ import component.chart.dto.ChartPointDto; */ public class ErvuChartDataSetDto extends ChartDataSetDto { - public Integer borderRadius; - public String barPercentage; - public String[] backgroundColors; - public ErvuChartDataSetDto(String label, String type, - List data) { + public ErvuChartDataSetDto(String label, String type, List data) { super(label, type, data); } - public Integer getBorderRadius() { - return borderRadius; - } - - public void setBorderRadius(Integer borderRadius) { - this.borderRadius = borderRadius; - } - - public String getBarPercentage() { - return barPercentage; - } - - public void setBarPercentage(String barPercentage) { - this.barPercentage = barPercentage; - } - - public String[] getBackgroundColors() { - return backgroundColors; - } - public void setBackgroundColors(String[] backgroundColors) { this.backgroundColors = backgroundColors; } diff --git a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataDto.java b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataDto.java index 5a475948..9d8307ef 100644 --- a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataDto.java +++ b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataDto.java @@ -21,13 +21,4 @@ public class RoundChartDataDto extends SingleChartDataDto { super(datasets, labels); this.centerLabels = centerLabels; } - - public List getCenterLabels() { - return centerLabels; - } - - public void setCenterLabels( - List centerLabels) { - this.centerLabels = centerLabels; - } } diff --git a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataSetDto.java b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataSetDto.java index 531b3c6d..aea42dbd 100644 --- a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataSetDto.java +++ b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataSetDto.java @@ -18,10 +18,6 @@ public class RoundChartDataSetDto extends SingleChartDataSetDto { @JsonInclude public Integer hoverOffset; - public RoundChartDataSetDto() { - super(null, null, null); - } - public RoundChartDataSetDto(String label, List data, String[] backgroundColor, Integer borderWidth, String radius, String cutout, Integer hoverOffset) { super(label, data, backgroundColor); @@ -30,36 +26,4 @@ public class RoundChartDataSetDto extends SingleChartDataSetDto { this.cutout = cutout; this.hoverOffset = hoverOffset; } - - public String getRadius() { - return radius; - } - - public void setRadius(String radius) { - this.radius = radius; - } - - public String getCutout() { - return cutout; - } - - public void setCutout(String cutout) { - this.cutout = cutout; - } - - public Integer getBorderWidth() { - return borderWidth; - } - - public void setBorderWidth(Integer borderWidth) { - this.borderWidth = borderWidth; - } - - public Integer getHoverOffset() { - return hoverOffset; - } - - public void setHoverOffset(Integer hoverOffset) { - this.hoverOffset = hoverOffset; - } } diff --git a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataSetDtoWrapper.java b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataSetDtoWrapper.java index a17821c1..ce875e89 100644 --- a/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataSetDtoWrapper.java +++ b/backend/src/main/java/ru/micord/ervu_dashboard/model/chart/round/RoundChartDataSetDtoWrapper.java @@ -6,8 +6,8 @@ import java.util.List; * @author Vitaly Chekushkin */ public class RoundChartDataSetDtoWrapper { - private RoundChartDataSetDto roundChartDataSetDto; - private List labels; + private final RoundChartDataSetDto roundChartDataSetDto; + private final List labels; public RoundChartDataSetDtoWrapper(RoundChartDataSetDto roundChartDataSetDto, List labels) { @@ -19,15 +19,7 @@ public class RoundChartDataSetDtoWrapper { return roundChartDataSetDto; } - public void setRoundChartDataSetDto(RoundChartDataSetDto roundChartDataSetDto) { - this.roundChartDataSetDto = roundChartDataSetDto; - } - public List getLabels() { return labels; } - - public void setLabels(List labels) { - this.labels = labels; - } } diff --git a/frontend/src/ts/ervu-dashboard/component/chart/ChartUtils.ts b/frontend/src/ts/ervu-dashboard/component/chart/ChartUtils.ts index 16deca11..34527653 100644 --- a/frontend/src/ts/ervu-dashboard/component/chart/ChartUtils.ts +++ b/frontend/src/ts/ervu-dashboard/component/chart/ChartUtils.ts @@ -35,4 +35,66 @@ export class ChartUtils { public static clone(source: T): T { return JSON.parse(JSON.stringify(source)); } -} \ No newline at end of file + + public static hexToHsl(colorHex: string, lightness?: number): string { + if (!colorHex) { + return colorHex; + } + let result: string[] = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(colorHex); + if (!result) { + result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(colorHex); + } + if (!result || (result.length != 4 && result.length != 5)) { + return undefined; + } + + let r = parseInt(result[1], 16); + let g = parseInt(result[2], 16); + let b = parseInt(result[3], 16); + r /= 255; + g /= 255; + b /= 255; + + const max = Math.max(r, g, b), min = Math.min(r, g, b); + let h, s, l = (max + min) / 2; + + if (max == min) { + h = s = 0; // achromatic + } + else { + const d = max - min; + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + + h = Math.round(h * 360); + s = Math.round(s * 100); + l = Math.round(l * 100); + + if (lightness) { + l *= lightness / 100; + l = Math.round(Math.max(0, Math.min(100, l))); + } + + let a: number; + if (result.length == 5) { + a = parseInt(result[4], 16) + a = Math.round(a / 255 * 10) / 10; + } + + return result.length == 5 + ? 'hsla(' + h + ', ' + s + '%, ' + l + '%, ' + a + ')' + : 'hsl(' + h + ', ' + s + '%, ' + l + '%)'; + } +} diff --git a/frontend/src/ts/ervu-dashboard/component/chart/ErvuChartV2.ts b/frontend/src/ts/ervu-dashboard/component/chart/ErvuChartV2.ts index 246af4d3..715944f5 100644 --- a/frontend/src/ts/ervu-dashboard/component/chart/ErvuChartV2.ts +++ b/frontend/src/ts/ervu-dashboard/component/chart/ErvuChartV2.ts @@ -25,8 +25,9 @@ import { UnsupportedOperationError, Visible } from "@webbpm/base-package"; -import {ChartLegendSettings} from "./model/ChartLegendSettings"; import {ChartBarSettings} from "./model/ChartBarSettings"; +import {ChartLegendSettings} from "./model/ChartLegendSettings"; +import {Options} from "./model/Options"; import {ChartPlugin} from "./plugin/ChartPlugin"; import {ChartUtils} from "./ChartUtils"; @@ -52,6 +53,7 @@ export class ErvuChartV2 extends Control implements Filterable { public scales: ChartScaleSettings[]; public bars: ChartBarSettings; + public options: Options; @NotNull() public loadOnStart: boolean = true; @@ -223,14 +225,19 @@ export class ErvuChartV2 extends Control implements Filterable { chartOptions.plugins.title = this.title; } - if (this.addDataSetsVisibilityToggleDataset && chartConfig.data.datasets && - chartConfig.data.datasets.length > 0) { - let datasetLength = chartConfig.data.datasets.length; - chartConfig.data.datasets.push({ - label: this.hideAllDatasetsLabel, - xAxisID: {display: false}, - yAxisID: {display: false} - }); + let datasets; + let datasetsLength: number = 0; + if (chartConfig.data && chartConfig.data.datasets && chartConfig.data.datasets.length > 0) { + datasets = chartConfig.data.datasets; + datasetsLength = datasets.length; + } + + if (this.addDataSetsVisibilityToggleDataset && datasetsLength > 0) { + datasets.push({ + label: this.hideAllDatasetsLabel, + xAxisID: {display: false}, + yAxisID: {display: false} + }); chartOptions.plugins.legend.onClick = (e, legendItem, legend) => { const index = legendItem.datasetIndex; @@ -238,12 +245,12 @@ export class ErvuChartV2 extends Control implements Filterable { let datasetMeta = chartObj.getDatasetMeta(index); - if (datasetLength == index) { + if (datasetsLength == index) { let showAll = datasetMeta.label == this.showAllDatasetsLabel; chartObj.data.datasets[index].label = showAll ? this.hideAllDatasetsLabel : this.showAllDatasetsLabel; - for (let i = 0; i < datasetLength; i++) { + for (let i = 0; i < datasetsLength; i++) { chartObj.setDatasetVisibility(i, showAll); } chartObj.update(); @@ -261,8 +268,8 @@ export class ErvuChartV2 extends Control implements Filterable { }; } - if (chartConfig.data.datasets) { // remove it after change type of ChartDataSetDto.backgroundColor - chartConfig.data.datasets.forEach(dataset => { + if (datasetsLength > 0) { // remove it after change type of ChartDataSetDto.backgroundColor + datasets.forEach(dataset => { if (dataset.backgroundColors) dataset.backgroundColor = dataset.backgroundColors; }); } @@ -282,7 +289,11 @@ export class ErvuChartV2 extends Control implements Filterable { if (this.bars) { chartOptions.scales = chartOptions.scales ? chartOptions.scales : {}; chartOptions.scales.x = this.bars.x; - chartOptions.scales.y = this.bars.y + chartOptions.scales.y = this.bars.y; + } + + if (this.options) { + Object.assign(chartOptions, this.options); } chartConfig.tooltips = { diff --git a/frontend/src/ts/ervu-dashboard/component/chart/model/AxisGridSettings.ts b/frontend/src/ts/ervu-dashboard/component/chart/model/AxisGridSettings.ts index 48b72583..fd980b2f 100644 --- a/frontend/src/ts/ervu-dashboard/component/chart/model/AxisGridSettings.ts +++ b/frontend/src/ts/ervu-dashboard/component/chart/model/AxisGridSettings.ts @@ -1,4 +1,13 @@ +import {AdvancedProperty, ColorEditor} from "@webbpm/base-package"; + export class AxisGridSettings { - public display: boolean = true; - public drawBorder: boolean = true; -} \ No newline at end of file + public display: boolean; + @AdvancedProperty() + public drawBorder: boolean; + @AdvancedProperty() + @ColorEditor() + public borderColor: string; + @AdvancedProperty() + @ColorEditor() + public color: string; +} diff --git a/frontend/src/ts/ervu-dashboard/component/chart/model/AxisSettings.ts b/frontend/src/ts/ervu-dashboard/component/chart/model/AxisSettings.ts index 86a3937e..e6302495 100644 --- a/frontend/src/ts/ervu-dashboard/component/chart/model/AxisSettings.ts +++ b/frontend/src/ts/ervu-dashboard/component/chart/model/AxisSettings.ts @@ -1,8 +1,11 @@ import {AxisGridSettings} from "./AxisGridSettings"; import {AxisTicksSettings} from "./AxisTicksSettings"; +import {AdvancedProperty} from "@webbpm/base-package"; export class AxisSettings { + public stacked: boolean; public grid: AxisGridSettings; public ticks: AxisTicksSettings; + @AdvancedProperty() public grace: string; -} \ No newline at end of file +} diff --git a/frontend/src/ts/ervu-dashboard/component/chart/model/AxisTicksSettings.ts b/frontend/src/ts/ervu-dashboard/component/chart/model/AxisTicksSettings.ts index cd5e97ad..1cc0d7f0 100644 --- a/frontend/src/ts/ervu-dashboard/component/chart/model/AxisTicksSettings.ts +++ b/frontend/src/ts/ervu-dashboard/component/chart/model/AxisTicksSettings.ts @@ -1,3 +1,8 @@ +import {AdvancedProperty, ColorEditor} from "@webbpm/base-package"; + export class AxisTicksSettings { - public display: boolean = true; -} \ No newline at end of file + public display: boolean; + @AdvancedProperty() + @ColorEditor() + public color: string; +} diff --git a/frontend/src/ts/ervu-dashboard/component/chart/model/Options.ts b/frontend/src/ts/ervu-dashboard/component/chart/model/Options.ts new file mode 100644 index 00000000..432667ee --- /dev/null +++ b/frontend/src/ts/ervu-dashboard/component/chart/model/Options.ts @@ -0,0 +1,16 @@ +export class Options { + // bar, doughnut + public borderRadius: number; + // bar, line + public borderWidth: number; + // bar + public barPercentage: number; + public barThickness: number; + public categoryPercentage: number; + // line + public borderDash: number[]; + public borderDashOffset: number; + public pointBorderWidth: number; + public pointRadius: number; + public tension: number; +} diff --git a/frontend/src/ts/ervu-dashboard/component/chart/plugin/BackgroundColorChartPlugin.ts b/frontend/src/ts/ervu-dashboard/component/chart/plugin/BackgroundColorChartPlugin.ts new file mode 100644 index 00000000..69527a7a --- /dev/null +++ b/frontend/src/ts/ervu-dashboard/component/chart/plugin/BackgroundColorChartPlugin.ts @@ -0,0 +1,38 @@ +import { + AdvancedProperty, + AnalyticalScope, + Behavior, + ColorEditor, + Visible +} from "@webbpm/base-package"; +import {Chart} from "chart.js"; +import {ChartPlugin} from "./ChartPlugin"; +import {ErvuChartV2} from "../ErvuChartV2"; + +@AnalyticalScope(ErvuChartV2) +export class BackgroundColorChartPlugin extends Behavior implements ChartPlugin { + @Visible('false') + id: string = 'background-color'; + @ColorEditor() + public color: string; + @AdvancedProperty() + public onlyChartArea: boolean; + + /** + * Настройка цвета фона + */ + beforeDraw(chart: Chart): void { + const {ctx, chartArea: {left, top, width, height}} = chart; + ctx.save(); + ctx.globalCompositeOperation = 'destination-over'; + ctx.fillStyle = this.color ? this.color : 'lightGreen'; + + if (this.onlyChartArea) { + ctx.fillRect(left, top, width, height); + } + else { + ctx.fillRect(0, 0, chart.width, chart.height); + } + ctx.restore(); + } +} diff --git a/frontend/src/ts/ervu-dashboard/component/chart/plugin/BarStackMiddleBorderRoundingChartPlugin.ts b/frontend/src/ts/ervu-dashboard/component/chart/plugin/BarStackMiddleBorderRoundingChartPlugin.ts index 2833ae4f..a05f3957 100644 --- a/frontend/src/ts/ervu-dashboard/component/chart/plugin/BarStackMiddleBorderRoundingChartPlugin.ts +++ b/frontend/src/ts/ervu-dashboard/component/chart/plugin/BarStackMiddleBorderRoundingChartPlugin.ts @@ -1,5 +1,5 @@ import {AnalyticalScope, Behavior, Visible} from "@webbpm/base-package"; -import {Chart, ChartMeta} from "chart.js"; +import {BarElement, Chart, ChartMeta} from "chart.js"; import {ChartPlugin} from "./ChartPlugin"; import {ErvuChartV2} from "../ErvuChartV2"; @@ -12,14 +12,12 @@ export class BarStackMiddleBorderRoundingChartPlugin extends Behavior implements * Закругление внутренних стыков в стеке */ beforeDatasetDraw(chart: Chart, args: { index: number; meta: ChartMeta }): void { - const indexAxis = chart.config.options.indexAxis; - const base = indexAxis == undefined || indexAxis === 'x' - ? chart.chartArea.bottom - : chart.chartArea.left; + const indexAxis = chart.config.options.indexAxis || 'x'; + const base = indexAxis === 'x' ? chart.chartArea.bottom : chart.chartArea.left; const meta = args.meta; if (meta.type === 'bar') { - meta.data.forEach(value => { - Object.assign(value, {base: base, enableBorderRadius: true}); + meta.data.forEach((barElement: BarElement) => { + Object.assign(barElement, {base: base, enableBorderRadius: true}); }) } } diff --git a/frontend/src/ts/ervu-dashboard/component/chart/plugin/ChartPlugin.ts b/frontend/src/ts/ervu-dashboard/component/chart/plugin/ChartPlugin.ts index 18f35cbc..c008b42c 100644 --- a/frontend/src/ts/ervu-dashboard/component/chart/plugin/ChartPlugin.ts +++ b/frontend/src/ts/ervu-dashboard/component/chart/plugin/ChartPlugin.ts @@ -3,6 +3,10 @@ import {Chart, ChartMeta} from "chart.js"; export interface ChartPlugin { id: string; + beforeUpdate?(chart: Chart, args?, options?): void; + beforeElementsUpdate?(chart: Chart, args?, options?): void; + beforeDatasetsUpdate?(chart: Chart, args?, options?): void; + beforeDraw?(chart: Chart): void; beforeDatasetsDraw?(chart: Chart, args?: { cancellable: true }, options?: any): void; beforeDatasetDraw?(chart: Chart, args: { index: number; meta: ChartMeta }): void; @@ -10,4 +14,4 @@ export interface ChartPlugin { afterDatasetDraw?(chart: Chart, args: { index: number; meta: ChartMeta }): void; afterDatasetsDraw?(chart: Chart, args?: unknown, options?: any): void; afterDraw?(chart: Chart): void; -} \ No newline at end of file +} diff --git a/frontend/src/ts/ervu-dashboard/component/chart/plugin/DarkBackgroundColorChartPlugin.ts b/frontend/src/ts/ervu-dashboard/component/chart/plugin/DarkBackgroundColorChartPlugin.ts new file mode 100644 index 00000000..a53d79ec --- /dev/null +++ b/frontend/src/ts/ervu-dashboard/component/chart/plugin/DarkBackgroundColorChartPlugin.ts @@ -0,0 +1,77 @@ +import { + AdvancedProperty, + AnalyticalScope, + Behavior, + DateTimeUtil, + NotNull, + Visible +} from "@webbpm/base-package"; +import {Chart} from "chart.js"; +import {ChartPlugin} from "./ChartPlugin"; +import {ChartUtils} from "../ChartUtils"; +import {ErvuChartV2} from "../ErvuChartV2"; + +@AnalyticalScope(ErvuChartV2) +export class DarkBackgroundColorChartPlugin extends Behavior implements ChartPlugin { + @Visible('false') + id: string = 'dark-background-color'; + @NotNull() + public dateFormat: string; + public lightness: number; // 0 - 100 для затемнения, для осветления > 100 + public dash: number; + public space: number; + @AdvancedProperty() + public date: Date; + + /** + * Затемнение цвета столбцов и добавление пунктира в линию для графика после текущей или заданной + * даты + */ + beforeDatasetsUpdate(chart: Chart, args?, options?): void { + const doLightness: boolean = !!this.lightness || this.lightness === 0; + const doDash: boolean = !!this.dash && !!this.space; + const date: Date = this.date == null ? new Date() : this.date; + const indexAxis = chart.config.options.indexAxis || 'x'; + const datasets = chart.config.data.datasets; + + if (doLightness) { + datasets.forEach(dataset => { + if (dataset.type === 'bar') { + const backgroundColor = dataset.backgroundColor; + if (typeof backgroundColor === 'string' && backgroundColor.length >= 7 + && backgroundColor.substr(0, 1) == '#') { + const colorHsl: string = ChartUtils.hexToHsl(backgroundColor, this.lightness); + if (colorHsl) { + const dateFormat = this.dateFormat; + dataset.backgroundColor = function (context) { + const scaleIndex = context.raw[indexAxis]; + const parsedDate = DateTimeUtil.parseDateWithFormat(scaleIndex, dateFormat); + const scaleDate = parsedDate ? parsedDate.toDate() : undefined; + return scaleDate > date ? colorHsl : backgroundColor; + } + } + } + } + }) + } + + if (doDash) { + datasets.forEach(dataset => { + if (dataset.type === 'line') { + const borderDash: number[] = [this.dash, this.space]; + const dateFormat = this.dateFormat; + Object.assign(dataset, { + segment: { + borderDash: function (context) { + const scaleIndex = context.p1.raw[indexAxis]; + const parsedDate = DateTimeUtil.parseDateWithFormat(scaleIndex, dateFormat); + const scaleDate = parsedDate ? parsedDate.toDate() : undefined; + return scaleDate > date ? borderDash : undefined; + } + } + }) + } + }) + } + } +}