Добавьте файлы проекта.

This commit is contained in:
FrigaT
2026-01-05 00:29:19 +03:00
committed by FrigaT
parent 76a09d80d4
commit d0653c2098
105 changed files with 6729 additions and 0 deletions

View 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;
}