using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Web.UI.DataVisualization.Charting; using System.Web.UI.WebControls; using LeafWeb.Core.Charter; using LeafWeb.Core.Utility; namespace LeafWeb.WebCms.Services { public static class LeafGasCharter { private static readonly Font TitleFont = new Font(new FontFamily("Times New Roman"), 10, FontStyle.Bold); private static readonly Font AxisFont = new Font(new FontFamily("Times New Roman"), 10, FontStyle.Bold); private static readonly Font Font = new Font(new FontFamily("Trebuchet MS"), 9, FontStyle.Bold); public const int ChartWidth = 550; public const int ChartHeight = 400; // cntrlcomparison public static IEnumerable ProduceCharts(CurveData curve) { var curveId = curve.CurveId; return curve.ParamSets.SelectMany(item => CurveSeries(curveId, item, item.CurveType.GetDescription())); } private static IEnumerable CurveSeries(string curveId, CurveParamSet paramSet, string chartTitle) { var chloroChart = CreateEmptyChart("Chloroplastic CO2 partial pressure (Pa)", ChartWidth, ChartHeight); var interChart = CreateEmptyChart("Intercellular CO2 partial pressure (Pa)", ChartWidth, ChartHeight); // Set the points for the symbol series for paramater set 1, chloroplastic AddAnetMeasPoints(paramSet.AnetMeasChloro1Data, chloroChart.Series["Rubisco-limited"]); AddAnetMeasPoints(paramSet.AnetMeasChloro2Data, chloroChart.Series["RuBP regeneration-limited"]); var tpuSeries = NewTpuSeries(paramSet.AnetMeasChloro3Data); AddAnetMeasPoints(paramSet.AnetMeasChloro3Data, tpuSeries); chloroChart.Series.Add(tpuSeries); // Set the points for the symbol series for paramater set 1, intercellular AddAnetMeasPoints(paramSet.AnetMeasInter1Data, interChart.Series["Rubisco-limited"]); AddAnetMeasPoints(paramSet.AnetMeasInter2Data, interChart.Series["RuBP regeneration-limited"]); tpuSeries = NewTpuSeries(paramSet.AnetMeasInter3Data); AddAnetMeasPoints(paramSet.AnetMeasInter3Data, tpuSeries); interChart.Series.Add(tpuSeries); // Set the points on the asymptote curve for parameter set 1, chloroplast AddAsymptotePoints(paramSet.AcChloroData, chloroChart.Series["acCurve"]); AddAsymptotePoints(paramSet.AjChloroData, chloroChart.Series["ajCurve"]); AddAsymptotePoints(paramSet.AtChloroData, chloroChart.Series["atCurve"]); // Set the points on the asymptote curve for parameter set 1, intercellular AddAsymptotePoints(paramSet.AcInterData, interChart.Series["acCurve"]); AddAsymptotePoints(paramSet.AjInterData, interChart.Series["ajCurve"]); AddAsymptotePoints(paramSet.AtInterData, interChart.Series["atCurve"]); var title = new Title($"LeafWeb curveID = {curveId}\n{chartTitle}"){Font = TitleFont}; chloroChart.Titles.Add(title); interChart.Titles.Add(title); chloroChart.ChartAreas["ChartArea"].AxisX.TitleFont = AxisFont; chloroChart.ChartAreas["ChartArea"].AxisY.TitleFont = AxisFont; interChart.ChartAreas["ChartArea"].AxisX.TitleFont = AxisFont; interChart.ChartAreas["ChartArea"].AxisY.TitleFont = AxisFont; yield return chloroChart; yield return interChart; } private static Series NewTpuSeries(IReadOnlyCollection data) { var seriesName = "TPU-limited"; if (data.Count == 0) seriesName = "Curve Asymptote"; var series3 = new Series(seriesName) { MarkerSize = 9, BorderWidth = 3, XValueType = ChartValueType.Double, ChartType = SeriesChartType.Point, MarkerStyle = MarkerStyle.Square, ShadowColor = Color.Black, BorderColor = Color.Black, Color = Color.Orange, ShadowOffset = 0, YValueType = ChartValueType.Double }; return series3; } private static void AddAnetMeasPoints(IEnumerable data, Series series) { // Set the points for the series from the ArrayList foreach (var xy in data) { series.Points.AddXY(xy.X, xy.Y); } } private static void AddAsymptotePoints(IEnumerable data, Series series) { // Set the points for the series from the ArrayList foreach (var xy in data.Where(xy => (xy.X != -9999) && (xy.Y != -9999))) { series.Points.AddXY(xy.X, xy.Y); } } private static Chart CreateEmptyChart(string axisXTitle, int width=700, int height=500) { var borderColor = Color.FromArgb(180, 26, 59, 105); var chart = new Chart { BackColor = Color.White, Width = Unit.Pixel(width), Height = Unit.Pixel(height), //BorderSkin = {SkinStyle = BorderSkinStyle.None}, BorderColor = borderColor, BorderlineColor = borderColor, BorderlineWidth = 1, BorderlineDashStyle = ChartDashStyle.Solid }; chart.Legends.Add(new Legend { Enabled = true, IsTextAutoFit = false, Name = "Default", Docking = Docking.Bottom, BackColor = Color.Transparent, Font = Font }); chart.ChartAreas.Add(new ChartArea { Name = "ChartArea", BorderColor = Color.FromArgb(64, 64, 64, 64), BorderDashStyle = ChartDashStyle.Solid, BackSecondaryColor = Color.White, BackColor = Color.OldLace, ShadowColor = Color.Transparent, BackGradientStyle = GradientStyle.TopBottom, AxisY = new Axis { LineColor = Color.FromArgb(64, 64, 64, 64), Title = "Net assimilation rate (umol/m2/s)", LabelStyle = { Font = Font }, MajorGrid = new Grid { LineColor = Color.FromArgb(64, 64, 64, 64)} }, AxisX = new Axis { LineColor = Color.FromArgb(64, 64, 64, 64), Minimum = 0, Title = axisXTitle, LabelStyle = { Font = Font }, MajorGrid = new Grid { LineColor = Color.FromArgb(64, 64, 64, 64)} } }); chart.Series.Add(new Series { MarkerSize = 8, BorderWidth = 3, XValueType = ChartValueType.Double, Name = "Rubisco-limited", ChartType = SeriesChartType.Point, MarkerStyle = MarkerStyle.Diamond, ShadowColor = Color.Black, BorderColor = borderColor, Color = Color.Red, ShadowOffset = 0, YValueType = ChartValueType.Double }); chart.Series.Add(new Series { MarkerSize = 9, BorderWidth = 3, XValueType = ChartValueType.Double, Name = "RuBP regeneration-limited", ChartType = SeriesChartType.Point, MarkerStyle = MarkerStyle.Circle, ShadowColor = Color.Black, BorderColor = borderColor, Color = Color.Blue, ShadowOffset = 0, YValueType = ChartValueType.Double }); chart.Series.Add(new Series { MarkerSize = 2, BorderWidth = 1, XValueType = ChartValueType.Double, Name = "acCurve", ChartType = SeriesChartType.Line, MarkerStyle = MarkerStyle.None, ShadowColor = Color.Black, BorderColor = borderColor, Color = Color.Red, ShadowOffset = 0, YValueType = ChartValueType.Double, IsVisibleInLegend = false }); chart.Series.Add(new Series { MarkerSize = 2, BorderWidth = 1, XValueType = ChartValueType.Double, Name = "ajCurve", ChartType = SeriesChartType.Line, MarkerStyle = MarkerStyle.None, ShadowColor = Color.Black, BorderColor = borderColor, Color = Color.Blue, ShadowOffset = 0, YValueType = ChartValueType.Double, IsVisibleInLegend = false }); chart.Series.Add(new Series { MarkerSize = 2, BorderWidth = 1, XValueType = ChartValueType.Double, Name = "atCurve", ChartType = SeriesChartType.Line, MarkerStyle = MarkerStyle.None, ShadowColor = Color.Black, BorderColor = borderColor, Color = Color.Orange, ShadowOffset = 0, YValueType = ChartValueType.Double, IsVisibleInLegend = false }); return chart; } } }