using System.Text.Json; namespace AIStudio.Assistants.VisualBriefing; /// /// Turns a validated chart specification into a branded chart-library option object. /// internal static class VisualBriefingChartCompiler { /// /// Compiles one validated chart specification into an Apache ECharts option object. /// /// The validated chart specification. /// The branded chart option. internal static JsonElement Compile(VisualBriefingChartSpec chart) { object series = chart.Kind switch { VisualBriefingChartKind.PIE or VisualBriefingChartKind.DONUT => chart.Categories.Select((category, index) => new { name = category, value = chart.Series[0].Values[index], }).ToArray(), VisualBriefingChartKind.RADAR => chart.Series.Select(item => new { name = item.Name, type = "radar", data = new[] { new { value = item.Values, name = item.Name, }, }, }).ToArray(), _ => chart.Series.Select(item => new { name = item.Name, type = SeriesType(chart.Kind), stack = chart.Kind is VisualBriefingChartKind.STACKED_BAR ? "total" : null, areaStyle = chart.Kind is VisualBriefingChartKind.AREA ? new { opacity = 0.18 } : null, smooth = chart.Kind is VisualBriefingChartKind.LINE or VisualBriefingChartKind.AREA, showSymbol = chart.Kind is VisualBriefingChartKind.SCATTER, symbolSize = chart.Kind is VisualBriefingChartKind.SCATTER ? 10 : 6, itemStyle = chart.Kind is VisualBriefingChartKind.BAR or VisualBriefingChartKind.STACKED_BAR ? new { borderRadius = new[] { 6, 6, 0, 0 } } : null, data = item.Values, }).ToArray(), }; var option = new { color = new[] { "#236A50", "#F2D264", "#79AE90", "#C97857", "#4E7894", "#9B6B8F" }, backgroundColor = "transparent", textStyle = new { color = "#172A24", fontFamily = "system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, sans-serif", }, tooltip = new { trigger = chart.Kind is VisualBriefingChartKind.PIE or VisualBriefingChartKind.DONUT ? "item" : "axis", borderColor = "#D6E2DC", backgroundColor = "#FFFEFA", textStyle = new { color = "#172A24" }, }, legend = new { show = true, top = 0, textStyle = new { color = "#4F635B" } }, grid = chart.Kind is VisualBriefingChartKind.PIE or VisualBriefingChartKind.DONUT or VisualBriefingChartKind.RADAR ? null : new { left = 8, right = 16, top = 48, bottom = 8, containLabel = true }, xAxis = chart.Kind is VisualBriefingChartKind.PIE or VisualBriefingChartKind.DONUT or VisualBriefingChartKind.RADAR ? null : new { type = "category", data = chart.Categories, axisLine = new { lineStyle = new { color = "#B8C9C0" } }, axisTick = new { show = false }, axisLabel = new { color = "#5E7169" }, }, yAxis = chart.Kind is VisualBriefingChartKind.PIE or VisualBriefingChartKind.DONUT or VisualBriefingChartKind.RADAR ? null : new { type = "value", axisLine = new { show = false }, axisTick = new { show = false }, axisLabel = new { color = "#5E7169" }, splitLine = new { lineStyle = new { color = "#E1EAE5" } }, }, radar = chart.Kind is VisualBriefingChartKind.RADAR ? new { indicator = chart.Categories.Select(name => new { name }).ToArray(), splitArea = new { areaStyle = new { color = new[] { "#FFFEFA", "#EAF1EC" } } }, axisName = new { color = "#5E7169" }, splitLine = new { lineStyle = new { color = "#B8C9C0" } }, } : null, series = chart.Kind is VisualBriefingChartKind.PIE or VisualBriefingChartKind.DONUT ? new[] { new { type = "pie", radius = chart.Kind is VisualBriefingChartKind.DONUT ? new[] { "45%", "70%" } : new[] { "0%", "70%" }, padAngle = 2, itemStyle = new { borderColor = "#FFFEFA", borderWidth = 2, borderRadius = 5 }, label = new { color = "#4F635B" }, data = series, }, } : series, }; return JsonSerializer.SerializeToElement(option, VisualBriefingJson.Canonical); } /// /// Maps a semantic chart kind to its Apache ECharts series type. /// /// The semantic chart kind. /// The Apache ECharts series type. private static string SeriesType(VisualBriefingChartKind kind) => kind switch { VisualBriefingChartKind.LINE or VisualBriefingChartKind.AREA => "line", VisualBriefingChartKind.BAR or VisualBriefingChartKind.STACKED_BAR => "bar", VisualBriefingChartKind.SCATTER => "scatter", VisualBriefingChartKind.RADAR => "radar", _ => "line", }; }