/*
* dbMango
*
* Copyright 2025 Deutsche Bank AG
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System.Collections;
using ChartJs.Blazor.Common.Axes;
using ChartJs.Blazor.Common.Enums;
using ChartJs.Blazor.LineChart;
using Rms.Risk.Mango.Pivot.Core;
using Rms.Risk.Mango.Pivot.UI.Controls;
using Rms.Risk.Mango.Pivot.UI.Services;
namespace Rms.Risk.Mango.Pivot.UI.Pivot;
///
/// Prepare LineChard config for the given Pivot definition and data.
///
public class ChartHelperForPivot
{
public bool IsLineChart(PivotDefinition pivotDef, IPivotedData pivotData )
=> GetLineChartColumns(pivotDef, pivotData, out _, out _, out _);
public LineConfig ChartConfig { get; } = new()
{
Options = new()
{
Title = new()
{
Display = false,
Text = "Data graph"
},
Scales = new()
{
XAxes =
[
new CategoryAxis
{
ScaleLabel = new()
{
LabelString = "Date"
}
}
],
YAxes =
[
new LinearCartesianAxis
{
ScaleLabel = new()
{
LabelString = "Amount"
}
}
]
},
Tooltips = new()
{
Mode = InteractionMode.Nearest,
Intersect = true
},
Hover = new()
{
Mode = InteractionMode.Nearest,
Intersect = true
},
Responsive = true,
Legend = new()
{
Display = false,
Position = Position.Right,
Labels = new()
{
FontColor = Night.light
}
}
}
};
public void UpdateLineChart(
string name,
IReadOnlyCollection labels,
IReadOnlyCollection data
)
{
if ( name == null || labels == null || data == null )
return;
ChartConfig.Data.Labels.Clear();
ChartConfig.Data.Labels.Add( name );
ChartConfig.Data.Datasets.Clear();
var color = Night.RandomColorString();
var currentDataSet = new LineDataset
{
Label = name,
BackgroundColor = color,
BorderColor = color,
PointBackgroundColor = color,
PointRadius = 3,
PointBorderWidth = 1,
ShowLine = true,
Fill = false,
PointHitRadius = 5,
SteppedLine = SteppedLine.False
};
currentDataSet.AddRange( data );
ChartConfig.Data.XLabels.Clear();
foreach (var label in labels)
ChartConfig.Data.XLabels.Add(label);
ChartConfig.Data.Datasets.Add( currentDataSet );
ChartConfig.Options.Legend ??= new();
ChartConfig.Options.Legend.Display = true;
ChartConfig.Options.Legend.Position = Position.Bottom;
ChartConfig.Options.Scales ??= new();
ChartConfig.Options.Scales?.YAxes.Clear();
if ( data.Count == 0 )
return;
var dataMin = data.Min();
var dataMax = data.Max();
ChartConfig.Options.Scales?.YAxes.Add( new LinearCartesianAxis
{
Ticks = new()
{
Min = dataMin - Math.Abs(dataMin)*0.01, // -1%
Max = dataMax + Math.Abs(dataMax)*0.01 // +1%
}
});
}
public void UpdateLineChart(
PivotDefinition pivotDef,
IPivotedData pivotData,
Func getFormat
)
{
if (!GetLineChartColumns(pivotDef, pivotData, out var xCol, out var yCol, out var dataSetColumns))
return;
var comparer = new RowComparer(pivotData, xCol, dataSetColumns!);
// sort row indexes by data set key ( all yCol ), then by X-axis label (xCol)
var orderedRows = Enumerable
.Range(0, pivotData.Count)
.OrderBy(x => x, comparer)
.ToArray()
;
var labelObjects = orderedRows
.Select(x => pivotData.Get(xCol, x))
.Where(x => x != null)
.Distinct()
.OrderBy(x => x)
.ToArray()
;
var labels =labelObjects
.Select( x => TableControl.ConvertToString(x, getFormat(pivotDef.LineChartXAxis!)))
.ToList()
;
if (labels.Count == 0) // impossible
return;
var labelPos = labelObjects
.Select((x, i) => new KeyValuePair