#region Setup using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using ChartForgeX.Core; using ChartForgeX.Primitives; using ChartForgeX.Rendering; using ChartForgeX.Themes; using ChartForgeX.Topology; using ChartForgeX.Typography; using ChartForgeX.VisualArtifacts; using ChartForgeX.VisualBlocks; var mode = VisualThemeMode.Dark; var theme = VisualTheme.Graphite(); var model = ChordRecipe.Create("color-dimension", mode); var context = new VisualRenderContext( new VisualLayoutOptions(new VisualSize(800, 440)), theme, mode, new VisualFrame("Transfer volume and latency", "Illustrative latency colors flows; transfer counts retain their weights", showLegend: null, showSurface: false)); var prepared = model.Prepare(context); File.WriteAllText("visual.svg", prepared.ToSvg()); File.WriteAllBytes("visual.png", prepared.ToPng()); File.WriteAllText("visual.html", prepared.ToArtifact("example", VisualArtifactKind.Chart).ToHtmlPage()); #endregion /// Directed team transfers retain parallel, reciprocal, self and zero-valued flow identities. public static class ChordRecipe { public static Chart Create(string variant = "wide", VisualThemeMode mode = VisualThemeMode.Light) { var configured = variant == "options"; var transfers = ChartSeries.CreateChord(new ChartSeriesId("transfer-source"), "Transfers", new[] { new ChartNode("north", "North"), new ChartNode("south", "South"), new ChartNode("north-support", configured ? "Support" : "Services"), new ChartNode("south-support", "Support") }, new[] { new ChartFlowLink("north-south", "north", "south", 18), new ChartFlowLink("south-north", "south", "north", 7), new ChartFlowLink("north-standard", "north", "north-support", 12), new ChartFlowLink("north-priority", "north", "north-support", 5), new ChartFlowLink("support-south", "north-support", "south", 9), new ChartFlowLink("south-support", "south", "south-support", 14), new ChartFlowLink("support-return", "south-support", "north", 4), new ChartFlowLink("support-internal", "south-support", "south-support", 3), new ChartFlowLink("zero-transfer", "north-support", "south-support", 0) }); var chart = Chart.Create().AddSeries(transfers); if (configured) { chart.ConfigureChord(options => { options.StartAngleDegrees = -120; options.SweepAngleDegrees = 300; options.NodeGapDegrees = 5; options.NodeThicknessRatio = .09; options.RibbonOpacity = .45; options.LabelContent = ChartChordLabelContent.LabelAndTotals; }); transfers.WithNodeState("north-support", ChartSeriesState.Warning) .WithFlowStyle("north-priority", new ChartFlowStyle(fill: ChartColor.FromHex("#AF6B24"), fillOpacity: .7, fillPattern: ChartFillPattern.DiagonalForward, stroke: ChartColor.FromHex("#764415"), strokeWidth: 1)) .WithFlowState("north-priority", ChartSeriesState.Warning).WithFlowStyle("support-internal", new ChartFlowStyle(strokeWidth: 1)); } if (variant is "color-dimension" or "compact-color-dimension") { // Illustrative measurements color the existing transfers; they are not additional flow weights. var latency = new double?[] { 180, 95, 125, 40, 0, null, 65, 110, 210 }; transfers.ReplaceFlowData(transfers.Nodes, transfers.FlowLinks.Select((flow, index) => new ChartFlowLink(flow.Id, flow.SourceId, flow.TargetId, flow.Value, latency[index]))); transfers.ShowInLegend = false; chart.WithLegend(true).ConfigureLabels(labels => labels.NoData = "Not sampled").ConfigureChord(options => { options.ColorScale = ChartColorScale.Sequential(new[] { new ChartColorStop(0, ChartColor.FromHex("#2166AC")), new ChartColorStop(50, ChartColor.FromHex("#67A9CF")), new ChartColorStop(150, ChartColor.FromHex("#D9A441")), new ChartColorStop(240, ChartColor.FromHex("#B2182B")) }).WithCaptions(new[] { new ChartColorScaleCaption(50, "Prompt"), new ChartColorScaleCaption(100, "Expected"), new ChartColorScaleCaption(200, "Delayed") }); options.ColorDimension.Name = "Illustrative latency"; options.ColorDimension.ValueFormat = ChartValueFormat.Number("0 'ms'", CultureInfo.InvariantCulture); options.ColorDimension.LegendStyle = ChartColorLegendStyle.Gradient; }); } return chart; } }