Добавьте файлы проекта.
This commit is contained in:
184
SQLVision.Visualizers/Visualizers/ChartVisualizer.cs
Normal file
184
SQLVision.Visualizers/Visualizers/ChartVisualizer.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using SQLVision.Core.Enums;
|
||||
using SQLVision.Core.Models;
|
||||
using SQLVision.Visualizers.Interfaces;
|
||||
using System.Data;
|
||||
|
||||
namespace SQLVision.Visualizers.Visualizers;
|
||||
|
||||
public class ChartVisualizer : IVisualizer
|
||||
{
|
||||
public FrameworkElement Visualize(DataTable data, OutputDefinition definition)
|
||||
{
|
||||
if (data.Rows.Count == 0)
|
||||
{
|
||||
return CreateEmptyChartMessage("Нет данных для построения графика");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var chartType = definition.ChartType;
|
||||
var cartesianChart = new CartesianChart
|
||||
{
|
||||
Series = CreateSeries(data, definition),
|
||||
XAxes = CreateXAxes(data, definition),
|
||||
YAxes = CreateYAxes(definition),
|
||||
LegendPosition = LegendPosition.Right,
|
||||
TooltipPosition = LiveChartsCore.Measure.TooltipPosition.Hidden
|
||||
};
|
||||
|
||||
return cartesianChart;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return CreateEmptyChartMessage("Ошибка при построении графика");
|
||||
}
|
||||
}
|
||||
|
||||
private ISeries[] CreateSeries(DataTable data, OutputDefinition definition)
|
||||
{
|
||||
var series = new List<ISeries>();
|
||||
|
||||
if (!string.IsNullOrEmpty(definition.SeriesColumn))
|
||||
{
|
||||
// Разделение по сериям
|
||||
var seriesGroups = data.AsEnumerable()
|
||||
.GroupBy(row => row[definition.SeriesColumn])
|
||||
.ToList();
|
||||
|
||||
foreach (var group in seriesGroups)
|
||||
{
|
||||
var seriesName = group.Key.ToString();
|
||||
var values = group.Select(row =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(definition.YAxisColumn))
|
||||
return Convert.ToDouble(row[1]);
|
||||
return Convert.ToDouble(row[definition.YAxisColumn]);
|
||||
}).ToArray();
|
||||
|
||||
series.Add(CreateSeriesByType(definition.ChartType, values, seriesName));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Одна серия
|
||||
var values = data.AsEnumerable()
|
||||
.Select(row =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(definition.YAxisColumn))
|
||||
return Convert.ToDouble(row[1]);
|
||||
return Convert.ToDouble(row[definition.YAxisColumn]);
|
||||
}).ToArray();
|
||||
|
||||
series.Add(CreateSeriesByType(definition.ChartType, values, definition.Description));
|
||||
}
|
||||
|
||||
return series.ToArray();
|
||||
}
|
||||
|
||||
private ISeries CreateSeriesByType(ChartType chartType, double[] values, string name)
|
||||
{
|
||||
return chartType switch
|
||||
{
|
||||
ChartType.Line => new LineSeries<double>
|
||||
{
|
||||
Values = values,
|
||||
Name = name,
|
||||
Fill = null,
|
||||
GeometrySize = 8,
|
||||
LineSmoothness = 0
|
||||
},
|
||||
ChartType.Bar => new ColumnSeries<double>
|
||||
{
|
||||
Values = values,
|
||||
Name = name
|
||||
},
|
||||
ChartType.Area => new LineSeries<double>
|
||||
{
|
||||
Values = values,
|
||||
Name = name,
|
||||
Fill = new SolidColorPaint(SKColors.Blue.WithAlpha(50))
|
||||
},
|
||||
ChartType.Scatter => new ScatterSeries<ObservablePoint>
|
||||
{
|
||||
Values = values.Select((v, i) => new ObservablePoint(i, v)),
|
||||
Name = name,
|
||||
GeometrySize = 10
|
||||
},
|
||||
_ => new LineSeries<double>
|
||||
{
|
||||
Values = values,
|
||||
Name = name
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Axis[] CreateXAxes(DataTable data, OutputDefinition definition)
|
||||
{
|
||||
var labels = new List<string>();
|
||||
|
||||
if (!string.IsNullOrEmpty(definition.XAxisColumn))
|
||||
{
|
||||
labels = data.AsEnumerable()
|
||||
.Select(row => row[definition.XAxisColumn].ToString())
|
||||
.ToList();
|
||||
}
|
||||
else if (data.Columns.Count > 0)
|
||||
{
|
||||
// Берем первый столбец для оси X
|
||||
labels = data.AsEnumerable()
|
||||
.Select(row => row[0].ToString())
|
||||
.ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
labels = Enumerable.Range(0, data.Rows.Count)
|
||||
.Select(i => i.ToString())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
return new[]
|
||||
{
|
||||
new Axis
|
||||
{
|
||||
Labels = labels.ToArray(),
|
||||
LabelsRotation = labels.Count > 10 ? 45 : 0,
|
||||
TextSize = 12
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private Axis[] CreateYAxes(OutputDefinition definition)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
new Axis
|
||||
{
|
||||
Name = string.IsNullOrEmpty(definition.YAxisColumn) ? "Значения" : definition.YAxisColumn,
|
||||
TextSize = 12
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private FrameworkElement CreateEmptyChartMessage(string message)
|
||||
{
|
||||
var textBlock = new TextBlock
|
||||
{
|
||||
Text = message,
|
||||
HorizontalAlignment = HorizontalAlignment.Center,
|
||||
VerticalAlignment = VerticalAlignment.Center,
|
||||
FontSize = 16,
|
||||
Foreground = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Gray)
|
||||
};
|
||||
|
||||
var border = new Border
|
||||
{
|
||||
Child = textBlock,
|
||||
Background = new Microsoft.UI.Xaml.Media.SolidColorBrush(Microsoft.UI.Colors.Transparent),
|
||||
Padding = new Thickness(20)
|
||||
};
|
||||
|
||||
return border;
|
||||
}
|
||||
|
||||
public bool CanVisualize(OutputType type) => type == OutputType.Chart;
|
||||
}
|
||||
Reference in New Issue
Block a user