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; namespace LeafWeb.Web.Charter { public static class LeafWebCharter { // cntrlcomparison public static IEnumerable ProduceCharts(CurveData curve) { var curveId = curve.CurveId; var paramTitles = new[] { new {param = curve.FixedCndFixedCmp, title = "Internal conductance fixed, compensation point and M-M constants fixed" }, new {param = curve.FixedCndEstimatedCmp, title = "Internal conductance fixed, compensation point and M-M constants estimated" }, new {param = curve.EstimatedCndFixedCmp, title = "Internal conductance estimated, compensation point and M-M constants fixed" }, new {param = curve.EstimatedCndEstimatedCmp,title = "Internal conductance estimated, compensation point and M-M constants estimated" }, }; return paramTitles.SelectMany(item => CurveSeries(curveId, item.param, item.title)); } private static IEnumerable CurveSeries(string curveId, CurveParamSet paramSet, string chartTitle) { var chloroChart = GetChart("Chloroplastic CO2 partial pressure (Pa)"); var interChart = GetChart("Intercellular CO2 partial pressure (Pa)"); // Set the points for the symbol series for paramater set 1, chloroplastic SetAnetMeasPoints(paramSet.AnetMeasChloro1Data, chloroChart.Series["Rubisco-limited"]); SetAnetMeasPoints(paramSet.AnetMeasChloro2Data, chloroChart.Series["RuBP regeneration-limited"]); var tpuSeries = NewTpuSeries(paramSet.AnetMeasChloro3Data); SetAnetMeasPoints(paramSet.AnetMeasChloro3Data, tpuSeries); chloroChart.Series.Add(tpuSeries); // Set the points for the symbol series for paramater set 1, intercellular SetAnetMeasPoints(paramSet.AnetMeasInter1Data, interChart.Series["Rubisco-limited"]); SetAnetMeasPoints(paramSet.AnetMeasInter2Data, interChart.Series["RuBP regeneration-limited"]); tpuSeries = NewTpuSeries(paramSet.AnetMeasInter3Data); SetAnetMeasPoints(paramSet.AnetMeasInter3Data, tpuSeries); interChart.Series.Add(tpuSeries); // Set the points on the asymptote curve for parameter set 1, chloroplast SetAsymptotePoints(paramSet.AcChloroData, chloroChart.Series["acCurve"]); SetAsymptotePoints(paramSet.AjChloroData, chloroChart.Series["ajCurve"]); SetAsymptotePoints(paramSet.AtChloroData, chloroChart.Series["atCurve"]); // Set the points on the asymptote curve for parameter set 1, intercellular SetAsymptotePoints(paramSet.AcInterData, interChart.Series["acCurve"]); SetAsymptotePoints(paramSet.AjInterData, interChart.Series["ajCurve"]); SetAsymptotePoints(paramSet.AtInterData, interChart.Series["atCurve"]); var axisFont = new Font("Times New Roman", 12, FontStyle.Bold); var titleFont = new Font("Times New Roman", 12, FontStyle.Bold); var title = new Title($"LeafWeb curveID = {curveId}\n{chartTitle}"){Font = titleFont}; chloroChart.Titles.Add(title); interChart.Titles.Add(title); chloroChart.ChartAreas["ChartArea1"].AxisX.TitleFont = axisFont; chloroChart.ChartAreas["ChartArea1"].AxisY.TitleFont = axisFont; interChart.ChartAreas["ChartArea1"].AxisX.TitleFont = axisFont; interChart.ChartAreas["ChartArea1"].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 SetAnetMeasPoints(List 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 SetAsymptotePoints(List data, Series series) { // Set the points for the series from the ArrayList foreach (var xy in data) { if ((xy.X != -9999) && (xy.Y != -9999)) { series.Points.AddXY(xy.X, xy.Y); } } } private static Chart GetChart(string axisXTitle, int width=700, int height=500) { var font = new Font(new FontFamily("Trebuchet MS"), 12, FontStyle.Bold); 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.Emboss}, BorderColor = borderColor }; 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 = "ChartArea1", BorderColor = Color.FromArgb(64, 64, 64, 64), BorderDashStyle = ChartDashStyle.Solid, BackSecondaryColor = Color.White, BackColor = Color.OldLace, ShadowColor = Color.Transparent, BackGradientStyle = GradientStyle.TopBottom, Area3DStyle = new ChartArea3DStyle { Rotation = 25, Perspective = 9, LightStyle = LightStyle.Realistic, Inclination = 40, IsRightAngleAxes = false, WallWidth = 3, IsClustered = false }, 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; } } }