【问题标题】:Overlap series in ASP.NET Column/Bar ChartASP.NET 柱形图/条形图中的重叠系列
【发布时间】:2018-04-10 09:57:49
【问题描述】:

这是我试图实现的图表/效果(来自 Excel),其中彩色条/列显示实际值,虚线边框的第二条/列显示基准值:

这是我从代码中得到的(如下):

如何让基准条/列落后于实际(学校)值?

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Web.UI.DataVisualization.Charting;

namespace ChartTest
{
    class Program
    {
        private static Color _benchmarkColour = Color.LightGray;
        private static System.Drawing.Font _graphFont = new System.Drawing.Font("Arial", 16f, FontStyle.Regular);
        private static int chartWidth = 1600;
        private static int chartHeight = 800;
        private static ChartColorPalette chartPalette = ChartColorPalette.BrightPastel;

        public class TimeSeriesDataPoint
        {
            public DateTime Date { get; set; }
            public double? SchoolValue { get; set; }
            public double? BenchmarkValue { get; set; }
        }

        public class BenchmarkDataPoint
        {
            public string Category { get; set; }
            public double? SchoolValue { get; set; }
            public double? BenchmarkValue { get; set; }
        }

        public class BenchmarkSeries
        {
            public string Name { get; set; }
            public Color Color { get; set; }
            public List<BenchmarkDataPoint> DataPoints { get; set; }
        }

        public class BenchmarkData
        {
            public List<BenchmarkSeries> Series { get; set; }
        }

        static void Main(string[] args)
        {
            var benchmarkData = new BenchmarkData { Series = new List<BenchmarkSeries>() };

            var series1 = new BenchmarkSeries { Name = "2018H1", Color = Color.FromArgb(200, 64, 118, 196), DataPoints = new List<BenchmarkDataPoint>() };
            series1.DataPoints.Add(new BenchmarkDataPoint { Category = "Grade 4", SchoolValue = 0.49d, BenchmarkValue = .65d });
            series1.DataPoints.Add(new BenchmarkDataPoint { Category = "Grade 5", SchoolValue = 0.55d, BenchmarkValue = .68d });
            series1.DataPoints.Add(new BenchmarkDataPoint { Category = "Grade 6", SchoolValue = 0.40d, BenchmarkValue = .55d });
            series1.DataPoints.Add(new BenchmarkDataPoint { Category = "Grade 7", SchoolValue = 0.52d, BenchmarkValue = .56d });
            benchmarkData.Series.Add(series1);

            var series2 = new BenchmarkSeries { Name = "2018H2", Color = Color.FromArgb(200, 255, 192, 0), DataPoints = new List<BenchmarkDataPoint>() };
            series2.DataPoints.Add(new BenchmarkDataPoint { Category = "Grade 4", SchoolValue = 0.35d, BenchmarkValue = .65d });
            series2.DataPoints.Add(new BenchmarkDataPoint { Category = "Grade 5", SchoolValue = 0.53d, BenchmarkValue = .71d });
            series2.DataPoints.Add(new BenchmarkDataPoint { Category = "Grade 6", SchoolValue = 0.43d, BenchmarkValue = .60d });
            series2.DataPoints.Add(new BenchmarkDataPoint { Category = "Grade 7", SchoolValue = 0.52d, BenchmarkValue = .56d });
            benchmarkData.Series.Add(series2);

            var chart = GetBenchmarkChart(benchmarkData);
            chart.SaveImage(@"C:\chart.jpg");
        }

        private static Chart GetBenchmarkChart(BenchmarkData benchmarkData)
        {
            var chart = new Chart();
            chart.Width = chartWidth;
            chart.Height = chartHeight;
            chart.Palette = chartPalette;

            foreach (var benchmarkSeries in benchmarkData.Series)
            {
                var series = new Series();
                series.Name = benchmarkSeries.Name;
                series.Color = benchmarkSeries.Color;
                series.BorderColor = Color.FromArgb(255, benchmarkSeries.Color);
                series.BorderWidth = 2;
                var counter = 0;
                foreach (var point in benchmarkSeries.DataPoints)
                {
                    if (point.SchoolValue.HasValue) series.Points.Add(new DataPoint { YValues = new[] { point.SchoolValue.Value }, XValue = counter });
                    else series.Points.Add(new DataPoint { IsEmpty = true, XValue = counter });
                    series.Points[counter].AxisLabel = point.Category;
                    counter++;
                }
                chart.Series.Add(series);

                var bmSeries = new Series();
                bmSeries.YAxisType = AxisType.Secondary;
                bmSeries.Name = benchmarkSeries.Name + ": Benchmark";
                bmSeries.Color = Color.FromArgb(0, Color.Black);
                bmSeries.BorderColor = Color.Gray;
                bmSeries.BorderWidth = 2;
                counter = 0;
                foreach (var point in benchmarkSeries.DataPoints)
                {
                    if (point.BenchmarkValue.HasValue) bmSeries.Points.Add(new DataPoint { YValues = new[] { point.BenchmarkValue.Value }, XValue = counter });
                    else bmSeries.Points.Add(new DataPoint { IsEmpty = true });
                    bmSeries.Points[counter].AxisLabel = point.Category;
                    counter++;
                }
                bmSeries.IsVisibleInLegend = false;
                chart.Series.Add(bmSeries);
            }

            var legend = new Legend("Legend");
            legend.Docking = Docking.Bottom;
            legend.Alignment = StringAlignment.Center;
            legend.Font = _graphFont;
            chart.Legends.Add(legend);

            var chartArea = new ChartArea();

            chartArea.AxisX.MajorGrid.Enabled = false;
            chartArea.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.None;
            chartArea.AxisX.LabelStyle.Font = _graphFont;
            chartArea.AxisX.Interval = 1;

            chartArea.AxisY.Minimum = 0;
            chartArea.AxisY.Maximum = 1;
            chartArea.AxisY.LabelStyle.Format = "{0:P0}";
            chartArea.AxisY.MajorGrid.LineColor = Color.LightGray;
            chartArea.AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dash;
            chartArea.AxisY.MinorGrid.Enabled = false;
            chartArea.AxisY.MinorTickMark.Enabled = false;

            chartArea.AxisY2.Minimum = 0;
            chartArea.AxisY2.Maximum = 1;
            chartArea.AxisY2.Enabled = AxisEnabled.False;

            chart.ChartAreas.Add(chartArea);

            return chart;
        }

    }
}

【问题讨论】:

    标签: c# asp.net asp.net-charts


    【解决方案1】:

    我有一个使用 StackedColumn 图表类型并计算 4 个分量的解决方法。这并不理想,我宁愿只移动基准的 x 轴位置,但我还没有发现这是否可能。

    这是堆叠列代码(尚不处理空/空点):

        private static Chart GetBenchmarkChartStacked(BenchmarkData benchmarkData)
        {
            var chart = new Chart();
            chart.Width = chartWidth;
            chart.Height = chartHeight;
            chart.Palette = chartPalette;
    
            var seriescounter = 0;
            foreach(var series in benchmarkData.Series)
            {
                seriescounter++;
    
                var exceededBenchmark = new Series()
                {
                    ChartType = SeriesChartType.StackedColumn,
                    Color = series.Color,
                    BorderColor = series.Color,
                    BorderWidth = 2,
                    CustomProperties = "StackedGroupName=" + series.Name,
                    IsVisibleInLegend = false
                };
                var school = new Series()
                {
                    ChartType = SeriesChartType.StackedColumn,
                    Color = series.Color,
                    BorderColor = series.Color,
                    BorderWidth = 2,
                    CustomProperties = "StackedGroupName=" + series.Name,
                    IsVisibleInLegend = true,
                    Name = series.Name
                };
                var schoolAndBenchmark = new Series()
                {
                    ChartType = SeriesChartType.StackedColumn,
                    Color = series.Color,
                    BorderColor = Color.Gray,
                    BorderWidth = 2,
                    BorderDashStyle = ChartDashStyle.Dash,
                    CustomProperties = "StackedGroupName=" + series.Name,
                    IsVisibleInLegend = false
                };
                var toReachBenchmark = new Series()
                {
                    ChartType = SeriesChartType.StackedColumn,
                    Color = Color.FromArgb(0, Color.Black),
                    BorderColor = Color.Gray,
                    BorderWidth = 2,
                    BorderDashStyle = ChartDashStyle.Dash,
                    CustomProperties = "StackedGroupName=" + series.Name,
                    IsVisibleInLegend = false
                };
                if (seriescounter == 1)
                {
                    toReachBenchmark.IsVisibleInLegend = true;
                    toReachBenchmark.Name = "Benchmark";
                }
                for (var i = 0; i < series.DataPoints.Count; i++)
                {
                    var schoolValue = series.DataPoints[i].SchoolValue;
                    var benchmarkValue = series.DataPoints[i].BenchmarkValue;
    
                    if (schoolValue <= benchmarkValue)
                    {
                        exceededBenchmark.Points.Add(new DataPoint { IsEmpty = true });
                        schoolAndBenchmark.Points.Add(new DataPoint { IsEmpty = true });
                        school.Points.AddY(schoolValue);
                        toReachBenchmark.Points.AddY(benchmarkValue - schoolValue);
                    }
                    else
                    {
                        exceededBenchmark.Points.AddY(schoolValue - benchmarkValue);
                        schoolAndBenchmark.Points.AddY(benchmarkValue);
                        toReachBenchmark.Points.Add(new DataPoint { IsEmpty = true });
                        school.Points.Add(new DataPoint { IsEmpty = true });
                    }
                    exceededBenchmark.Points[i].AxisLabel = series.DataPoints[i].Category;
                    schoolAndBenchmark.Points[i].AxisLabel = series.DataPoints[i].Category;
                    toReachBenchmark.Points[i].AxisLabel = series.DataPoints[i].Category;
                    school.Points[i].AxisLabel = series.DataPoints[i].Category;
                }
    
                chart.Series.Add(school);
                chart.Series.Add(schoolAndBenchmark);
                chart.Series.Add(exceededBenchmark);
                chart.Series.Add(toReachBenchmark);
            }
    
            var legend = new Legend("Legend");
            legend.Docking = Docking.Bottom;
            legend.Alignment = StringAlignment.Center;
            legend.Font = _graphFont;
            chart.Legends.Add(legend);
    
            var chartArea = new ChartArea();
    
            chartArea.AxisX.MajorGrid.Enabled = false;
            chartArea.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.None;
            chartArea.AxisX.LabelStyle.Font = _graphFont;
            //chartArea.AxisX.Interval = 1;
    
            chartArea.AxisY.Minimum = 0;
            chartArea.AxisY.Maximum = 1;
            chartArea.AxisY.LabelStyle.Format = "{0:P0}";
            chartArea.AxisY.MajorGrid.LineColor = Color.LightGray;
            chartArea.AxisY.MajorGrid.LineDashStyle = ChartDashStyle.Dash;
            chartArea.AxisY.MinorGrid.Enabled = false;
            chartArea.AxisY.MinorTickMark.Enabled = false;
    
            chart.ChartAreas.Add(chartArea);
    
            return chart;
        }
    

    这是结果图:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-20
      • 2014-09-10
      • 2015-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多