namespace AIStudio.Assistants.ModelComparison;
///
/// What the charts of the results of the Model Comparison assistant have in common.
///
///
/// The colors are fixed rather than taken from the theme, because MudBlazor paints the bars with the colors of the
/// palette as they are. Blue for wins, gray for ties, and red for losses read on the light and on the dark theme alike,
/// and stay apart for readers with a color vision deficiency; the axes and the legend follow the theme on their own. On
/// the dark theme, blue and red stay slightly below a contrast of 3:1, so every chart comes with a table of the same
/// numbers, which reads without any color.
///
public static class ModelComparisonCharts
{
///
/// The colors of wins, ties, and losses, in the order of the series.
///
public static readonly string[] OUTCOME_PALETTE = ["#2a78d6", "#898781", "#e34948"];
///
/// The colors of the time until the first token and until the complete answer.
///
public static readonly string[] SPEED_PALETTE = ["#2a78d6", "#d95926"];
///
/// The colors of the first model of a pair, of a tie, and of the second model. Not the red of a loss: a win of
/// the second model is a loss of the first one, and red would favor one side.
///
public static readonly string[] PAIR_PALETTE = ["#2a78d6", "#898781", "#d95926"];
///
/// The color of a chart with a single series, e.g., the effort with each model.
///
public static readonly string[] SINGLE_PALETTE = ["#2a78d6"];
///
/// Above this many models, the names below the bars are tilted, so that long names do not run into each other.
///
private const int MAX_UPRIGHT_LABELS = 4;
///
/// About how many steps the vertical axis of a chart shows.
///
private const int AXIS_STEP_COUNT = 5;
///
/// Gets the names of the models below the bars of a chart.
///
/// The models, in the order of the bars.
/// The names.
public static string[] ModelLabels(IEnumerable models) => [.. models.Select(model => model.Label)];
///
/// Gets by how many degrees the names below the bars are tilted.
///
/// How many models the chart shows.
/// The angle, 0 for upright names.
public static int LabelRotation(int modelCount) => modelCount > MAX_UPRIGHT_LABELS ? 30 : 0;
///
/// Gets a step for the vertical axis: a whole 1, 2, or 5 times a power of ten, so that the axis shows about
/// AXIS_STEP_COUNT steps up to the largest value. Counts have no fractions, and seconds need none on an axis.
///
/// The values of the chart.
/// The step.
public static int AxisStep(IEnumerable values)
{
var maximum = values.DefaultIfEmpty(0).Max();
for (var magnitude = 1; ; magnitude *= 10)
foreach (var factor in (int[])[1, 2, 5])
if (maximum / (factor * magnitude) <= AXIS_STEP_COUNT)
return factor * magnitude;
}
}