diff --git a/Core.Tests/Charter/CurveDataConverterTests.cs b/Core.Tests/Charter/CurveDataConverterTests.cs new file mode 100644 index 0000000..7da86b4 --- /dev/null +++ b/Core.Tests/Charter/CurveDataConverterTests.cs @@ -0,0 +1,25 @@ +using System.Linq; +using LeafWeb.Core.Charter; +using LeafWeb.Core.Models; +using LeafWeb.Core.Parsers; +using NUnit.Framework; + +namespace LeafWeb.Core.Tests.Charter +{ + public class CurveDataConverterTests + { + private const string ContentDirectory = @"Parsers\LeafOutputData\"; + + [Test] + public void Convert_Valid() + { + var fileInfo = FileUtility.GetContentFile(ContentDirectory, "cntrlcomparison_Wild Capsicum.csv"); + CntrlComparison[] cntrlComparison; + using (var parser = new CntrlComparisonParser(fileInfo)) + cntrlComparison = parser.Parse(); + + var curves = CurveDataConverter.Convert(cntrlComparison); + Assert.That(curves.Count(),Is.EqualTo(7)); + } + } +} \ No newline at end of file diff --git a/Core.Tests/Core.Tests.csproj b/Core.Tests/Core.Tests.csproj index 2b39d64..79fa9a0 100644 --- a/Core.Tests/Core.Tests.csproj +++ b/Core.Tests/Core.Tests.csproj @@ -43,7 +43,9 @@ + + diff --git a/Core.Tests/FileUtility.cs b/Core.Tests/FileUtility.cs new file mode 100644 index 0000000..66b2af2 --- /dev/null +++ b/Core.Tests/FileUtility.cs @@ -0,0 +1,14 @@ +using System; +using System.IO; + +namespace LeafWeb.Core.Tests +{ + public static class FileUtility + { + public static FileInfo GetContentFile(string contentDirectory, string fileName) + { + var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, contentDirectory); + return new FileInfo(path + fileName); + } + } +} \ No newline at end of file diff --git a/Core.Tests/Parsers/CntrlComparisonParserTests.cs b/Core.Tests/Parsers/CntrlComparisonParserTests.cs index 6277361..4a4d98c 100644 --- a/Core.Tests/Parsers/CntrlComparisonParserTests.cs +++ b/Core.Tests/Parsers/CntrlComparisonParserTests.cs @@ -11,18 +11,12 @@ namespace LeafWeb.Core.Tests.Parsers [TestFixture] public class CntrlComparisonParserTests { - protected const string ContentDirectory = @"Parsers\LeafOutputData\"; - - private static FileInfo GetContentFile(string fileName) - { - var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ContentDirectory); - return new FileInfo(path + fileName); - } + private const string ContentDirectory = @"Parsers\LeafOutputData\"; [Test] public void Parse_Valid() { - var fileInfo = GetContentFile("cntrlcomparison_Wild Capsicum.csv"); + var fileInfo = FileUtility.GetContentFile(ContentDirectory, "cntrlcomparison_Wild Capsicum.csv"); CntrlComparison[] cntrlComparison; using (var parser = new CntrlComparisonParser(fileInfo)) diff --git a/Core.Tests/Parsers/CurveDataListTests.cs b/Core.Tests/Parsers/CurveDataListTests.cs index 0955333..dcac827 100644 --- a/Core.Tests/Parsers/CurveDataListTests.cs +++ b/Core.Tests/Parsers/CurveDataListTests.cs @@ -1,6 +1,4 @@ -using System; -using System.IO; -using LeafWeb.Core.Charter; +using LeafWeb.Core.CharterOld; using NUnit.Framework; namespace LeafWeb.Core.Tests.Parsers @@ -8,18 +6,12 @@ namespace LeafWeb.Core.Tests.Parsers [TestFixture] public class CurveDataListTests { - protected const string ContentDirectory = @"Services\LeafOutputData\"; - - private static FileInfo GetContentFile(string fileName) - { - var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ContentDirectory); - return new FileInfo(path + fileName); - } + private const string ContentDirectory = @"Parsers\LeafOutputData\"; [Test] public void Parse_Valid() { - var fileInfo = GetContentFile("cntrlcomparison_Wild Capsicum.csv"); + var fileInfo = FileUtility.GetContentFile(ContentDirectory, "cntrlcomparison_Wild Capsicum.csv"); var cntrlComparison = new CurveDataList(); using (var reader = fileInfo.OpenText()) { diff --git a/Core.Tests/Parsers/LeafInputCsvParserTests.cs b/Core.Tests/Parsers/LeafInputCsvParserTests.cs index 003668f..5b30bf5 100644 --- a/Core.Tests/Parsers/LeafInputCsvParserTests.cs +++ b/Core.Tests/Parsers/LeafInputCsvParserTests.cs @@ -12,18 +12,13 @@ namespace LeafWeb.Core.Tests.Parsers [TestFixture] public class LeafInputCsvParserTests { - protected const string ContentDirectory = @"Parsers\LeafInputData\"; - - private static FileInfo GetContentFile(string fileName) - { - var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, ContentDirectory); - return new FileInfo(path + fileName); - } - + private const string ContentDirectory = @"Parsers\LeafInputData\"; + [Test] public void Parse_Valid() { - var fileInfo = GetContentFile("LeafInput-valid.csv"); + FileUtility.GetContentFile(ContentDirectory, "LeafInput-valid.csv"); + var fileInfo = FileUtility.GetContentFile(ContentDirectory, "LeafInput-valid.csv"); var leafInput = new LeafInputCsvParser(fileInfo); var input = leafInput.Parse(); @@ -109,7 +104,7 @@ namespace LeafWeb.Core.Tests.Parsers [Test] public void Parse_TitlesRemoved() { - var fileInfo = GetContentFile("LeafInput-titlesRemoved.csv"); + var fileInfo = FileUtility.GetContentFile(ContentDirectory, "LeafInput-titlesRemoved.csv"); var leafInput = new LeafInputCsvParser(fileInfo); var input = leafInput.Parse(); @@ -128,7 +123,7 @@ namespace LeafWeb.Core.Tests.Parsers [Test] public void Parse_IncompleteRows() { - var fileInfo = GetContentFile("LeafInput-incompleteRows.csv"); + var fileInfo = FileUtility.GetContentFile(ContentDirectory, "LeafInput-incompleteRows.csv"); var parser = new LeafInputCsvParser(fileInfo); Assert.That(() => parser.Parse(), Throws.TypeOf()); } @@ -136,7 +131,7 @@ namespace LeafWeb.Core.Tests.Parsers [Test] public void Parse_NoData() { - var fileInfo = GetContentFile("LeafInput-noData.csv"); + var fileInfo = FileUtility.GetContentFile(ContentDirectory, "LeafInput-noData.csv"); var parser = new LeafInputCsvParser(fileInfo); var input = parser.Parse(); } diff --git a/Core/Charter/CurveData.cs b/Core/Charter/CurveData.cs index 9c47287..d3fcee7 100644 --- a/Core/Charter/CurveData.cs +++ b/Core/Charter/CurveData.cs @@ -1,37 +1,21 @@ -using System.IO; +using System.ComponentModel; namespace LeafWeb.Core.Charter { public class CurveData { - private readonly string _curveId; + public string CurveId { get; set; } - public string CurveId => _curveId; + [DisplayName("Internal conductance fixed, compensation point and M-M constants fixed")] + public CurveParamSet FixedCndFixedCmp { get; set; } - // 1 - public CurveParamSet FixedCndFixedCmp { get; } - - // 2 - public CurveParamSet FixedCndEstimatedCmp { get; } + [DisplayName("Internal conductance fixed, compensation point and M-M constants estimated")] + public CurveParamSet FixedCndEstimatedCmp { get; set; } - // 3 - public CurveParamSet EstimatedCndFixedCmp { get; } + [DisplayName("Internal conductance estimated, compensation point and M-M constants fixed")] + public CurveParamSet EstimatedCndFixedCmp { get; set; } - // 4 - public CurveParamSet EstimatedCndEstimatedCmp { get; } - - - public CurveData(TextReader sr, ref int lineNbr) - { - // For each curve in the output file there are four sets of data. - - FixedCndFixedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId); - - FixedCndEstimatedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId); - - EstimatedCndFixedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId); - - EstimatedCndEstimatedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId); - } + [DisplayName("Internal conductance estimated, compensation point and M-M constants estimated")] + public CurveParamSet EstimatedCndEstimatedCmp { get; set; } } } \ No newline at end of file diff --git a/Core/Charter/CurveDataConverter.cs b/Core/Charter/CurveDataConverter.cs new file mode 100644 index 0000000..05d6591 --- /dev/null +++ b/Core/Charter/CurveDataConverter.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using LeafWeb.Core.Models; +using LeafWeb.Core.Utility; + +namespace LeafWeb.Core.Charter +{ + public class CurveDataConverter + { + public static IEnumerable Convert(IEnumerable cntrlComparison) + { + var comparisonGroups = + from comparison in cntrlComparison + group comparison by comparison.CurveID into curves + select new + { + CurveID = curves.Key, + FitType = from curve in curves + group curve by new {curve.FitGi, curve.FitGammaStar} into grp + select new + { + grp.Key.FitGi, + grp.Key.FitGammaStar, + Comparison = grp.SingleOrDefault() + } + }; + + foreach (var comparisonGroup in comparisonGroups) + { + if (comparisonGroup.FitType.Count() != 4) + throw new ArgumentException( + $"{comparisonGroup.CurveID} should have 4 data sets, only has {comparisonGroup.FitType.Count()}"); + + var curveData = new CurveData {CurveId = comparisonGroup.CurveID}; + + foreach (var fitType in comparisonGroup.FitType) + { + var paramSet = ConvertParamSet(fitType.Comparison); + + // fixed = not fitted + // estimated = fitted + // gi = internal conductance = "Cnd" + // gammastar = chloroplastic CO2 partial pressure photocompensation point = "Cmp" + + // put each comparison into the correct curve location + if (!fitType.FitGi && !fitType.FitGammaStar) + curveData.FixedCndFixedCmp = paramSet; + else if (!fitType.FitGi && fitType.FitGammaStar) + curveData.FixedCndEstimatedCmp = paramSet; + else if (fitType.FitGi && !fitType.FitGammaStar) + curveData.EstimatedCndFixedCmp = paramSet; + else if (fitType.FitGi && fitType.FitGammaStar) + curveData.EstimatedCndEstimatedCmp = paramSet; + } + + // Check all data is present + if (curveData.FixedCndFixedCmp == null) + throw new ArgumentException( + $"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName(c=>c.FixedCndFixedCmp)}"); + if (curveData.FixedCndEstimatedCmp == null) + throw new ArgumentException( + $"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName(c=>c.FixedCndEstimatedCmp)}"); + if (curveData.EstimatedCndFixedCmp == null) + throw new ArgumentException( + $"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName(c=>c.EstimatedCndFixedCmp)}"); + if (curveData.EstimatedCndEstimatedCmp == null) + throw new ArgumentException( + $"{comparisonGroup.CurveID} missing data for {ReflectionExtensions.GetPropertyDisplayName(c=>c.EstimatedCndEstimatedCmp)}"); + yield return curveData; + } + } + + private static CurveParamSet ConvertParamSet(CntrlComparison comparison) + { + var curveParamSet = new CurveParamSet(); + foreach (var fittingInfo in comparison.FittingInfo) + { + Set(curveParamSet, fittingInfo); + } + foreach (var photosyntheticInfo in comparison.PhotosyntheticInfo) + { + Set(curveParamSet, photosyntheticInfo); + } + return curveParamSet; + } + + private static void Set(CurveParamSet paramSet, CntrlComparisonPhotosyntheticInfo item) + { + AddXyIfInRange(item.CO2cc, item.Ac, paramSet.AcChloroData.Add); // Ac(y),CO2cc(x) + AddXyIfInRange(item.CO2cj, item.Aj, paramSet.AjChloroData.Add); // Aj(y),CO2cj(x) + AddXyIfInRange(item.CO2ct, item.At, paramSet.AtChloroData.Add); // At(y),CO2ct(x) + + AddXyIfInRange(item.CO2i, item.Ac, paramSet.AcInterData.Add); // Ac(y),CO2i(x) + AddXyIfInRange(item.CO2i, item.Aj, paramSet.AcInterData.Add); // Aj(y),CO2i(x) + AddXyIfInRange(item.CO2i, item.At, paramSet.AtInterData.Add); // Aj(y),CO2i(x) + } + + private static void AddXyIfInRange(double x, double y, Action set) + { + var xyPoint = new XyPoint(x, y); + if (xyPoint.YIsInRange(-20.0, 50.0)) + set(xyPoint); + } + + private static void Set(CurveParamSet paramSet, CntrlComparisonFittingInfo fittingInfo) + { + var xyPoint1 = new XyPoint(fittingInfo.PCO2c, fittingInfo.AnetMeas); // AnetMeas(y), PCO2c(x) + var xyPoint2 = new XyPoint(fittingInfo.PCO2i, fittingInfo.AnetMeas); + + switch (fittingInfo.PointLimitType) + { + case 1: + paramSet.AnetMeasChloro1Data.Add(xyPoint1); + paramSet.AnetMeasInter1Data.Add(xyPoint2); + break; + case 2: + paramSet.AnetMeasChloro2Data.Add(xyPoint1); + paramSet.AnetMeasInter2Data.Add(xyPoint2); + break; + case 3: + paramSet.AnetMeasChloro3Data.Add(xyPoint1); + paramSet.AnetMeasInter3Data.Add(xyPoint2); + break; + } + } + } +} \ No newline at end of file diff --git a/Core/Charter/CurveParamSet.cs b/Core/Charter/CurveParamSet.cs index 2c00a04..d70a163 100644 --- a/Core/Charter/CurveParamSet.cs +++ b/Core/Charter/CurveParamSet.cs @@ -1,6 +1,4 @@ using System.Collections.Generic; -using System.IO; -using LeafWeb.Core.Utility; namespace LeafWeb.Core.Charter { @@ -19,148 +17,5 @@ namespace LeafWeb.Core.Charter public List AcInterData { get; } = new List(); public List AjInterData { get; } = new List(); public List AtInterData { get; } = new List(); - - public CurveParamSet(TextReader sr, ref int lineNbr, ref string curveId) - { - bool curveIdSet = false, doneWithAnet = false; - string line; - List phrases; - - while (!doneWithAnet) - { - lineNbr++; - line = sr.ReadLine(); - if (line == null) - { - throw new ParseException("Unexpected end-of-file at line " + lineNbr); - } - - phrases = SplitCsvLine(line); - - var firstField = phrases[0]; - if (firstField.Equals("CO2i")) - { - doneWithAnet = true; - } - else - { - // The fields on the line: - // Column Name - // 0 CurveID - // 1 ChlFlUse - // 2 FitGi - // 3 FitGamma - // 4 FitKco - // 5 FitRd - // 6 FitAlpha - // 7 LimitCombina - // 8 PCO2i - // 9 PCO2c - // 10 AnetMeas - // 11 AnetCal - // 12 weitedrms - // 13 PointLimitType - - if (!curveIdSet) - { - curveId = firstField; - curveIdSet = true; - } - var xyPoint1 = new XyPoint(phrases[9], phrases[10]); // AnetMeas(y), PCO2c(x) - var xyPoint2 = new XyPoint(phrases[8], phrases[10]); - var pointLimitType = int.Parse(phrases[13]); - switch (pointLimitType) - { - case 1: - AnetMeasChloro1Data.Add(xyPoint1); - AnetMeasInter1Data.Add(xyPoint2); - break; - case 2: - AnetMeasChloro2Data.Add(xyPoint1); - AnetMeasInter2Data.Add(xyPoint2); - break; - case 3: - AnetMeasChloro3Data.Add(xyPoint1); - AnetMeasInter3Data.Add(xyPoint2); - break; - } - } - } - - // The next set of lines will have three pairs of x,y-coordinates to save. - // A blank line signals the end of the data. - - var moreData = true; - while (moreData) - { - // The fields on the line: - // Column Name - // 0 CO2i - // 1 CO2cc - // 2 Ac - // 3 CO2cj - // 4 Aj - // 5 CO2ct - // 6 At - - lineNbr++; - line = sr.ReadLine(); - if (line == null) - { - throw new ParseException("Unexpected end-of-file at line " + lineNbr); - } - - if (line.Length == 0) - moreData = false; - else - { - phrases = SplitCsvLine(line); - var xyPoint1 = new XyPoint(phrases[1],phrases[2]); // Ac(y),CO2cc(x) - if (xyPoint1.YIsInRange(-20.0, 50.0)) - AcChloroData.Add(xyPoint1); - xyPoint1 = new XyPoint(phrases[3], phrases[4]); // Aj(y),CO2cj(x) - if (xyPoint1.YIsInRange(-20.0, 50.0)) - AjChloroData.Add(xyPoint1); - xyPoint1 = new XyPoint(phrases[5], phrases[6]); // At(y),CO2ct(x) - if (xyPoint1.YIsInRange(-20.0, 50.0)) - AtChloroData.Add(xyPoint1); - - xyPoint1 = new XyPoint(phrases[0], phrases[2]); // Ac(y),CO2i(x) - if (xyPoint1.YIsInRange(-20.0, 50.0)) - AcInterData.Add(xyPoint1); - xyPoint1 = new XyPoint(phrases[0], phrases[4]); // Aj(y),CO2i(x) - if (xyPoint1.YIsInRange(-20.0, 50.0)) - AjInterData.Add(xyPoint1); - xyPoint1 = new XyPoint(phrases[0], phrases[6]); // At(y),CO2i(x) - if (xyPoint1.YIsInRange(-20.0, 50.0)) - AtInterData.Add(xyPoint1); - } - } - } - - /// - /// This method assumes that the argument is a comma-, blank-, or - /// tab-separated set of strings. It returns an ArrayList of those - /// quantities. Consecutive commas will be returned as an empty string, - /// but all empty strings at the end of the line will be thrown away. - /// - /// - /// - private static List SplitCsvLine(string line) - { - int i; - var separator = new [] {',', ' ', '\t'}; - var phrases = line.Split(separator); - - var retPhrases = new List(); - for (i = 0; i < phrases.Length; i++) - { - var phrase = phrases[i].Trim(); - if (phrase.Length > 0) - retPhrases.Add(phrase); - } - - return retPhrases; - } } } \ No newline at end of file diff --git a/Core/Charter/XYPoint.cs b/Core/Charter/XYPoint.cs index b562267..b75c947 100644 --- a/Core/Charter/XYPoint.cs +++ b/Core/Charter/XYPoint.cs @@ -2,16 +2,16 @@ { public class XyPoint { - public XyPoint(string x, string y) - { - X = double.Parse(x); - Y = double.Parse(y); - } - public double X { get; private set; } public double Y { get; private set; } + public XyPoint(double x, double y) + { + X = x; + Y = y; + } + public bool YIsInRange(double lowEnd, double highEnd) { return (Y >= lowEnd) && (Y <= highEnd); diff --git a/Core/CharterOld/CurveData.cs b/Core/CharterOld/CurveData.cs new file mode 100644 index 0000000..64a2233 --- /dev/null +++ b/Core/CharterOld/CurveData.cs @@ -0,0 +1,37 @@ +using System.IO; + +namespace LeafWeb.Core.CharterOld +{ + public class CurveData + { + private readonly string _curveId; + + public string CurveId => _curveId; + + // 1 + public CurveParamSet FixedCndFixedCmp { get; } + + // 2 + public CurveParamSet FixedCndEstimatedCmp { get; } + + // 3 + public CurveParamSet EstimatedCndFixedCmp { get; } + + // 4 + public CurveParamSet EstimatedCndEstimatedCmp { get; } + + + public CurveData(TextReader sr, ref int lineNbr) + { + // For each curve in the output file there are four sets of data. + + FixedCndFixedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId); + + FixedCndEstimatedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId); + + EstimatedCndFixedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId); + + EstimatedCndEstimatedCmp = new CurveParamSet(sr, ref lineNbr, ref _curveId); + } + } +} \ No newline at end of file diff --git a/Core/Charter/CurveDataList.cs b/Core/CharterOld/CurveDataList.cs similarity index 96% rename from Core/Charter/CurveDataList.cs rename to Core/CharterOld/CurveDataList.cs index 3852d31..1421a4e 100644 --- a/Core/Charter/CurveDataList.cs +++ b/Core/CharterOld/CurveDataList.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.IO; -namespace LeafWeb.Core.Charter +namespace LeafWeb.Core.CharterOld { public class CurveDataList { diff --git a/Core/CharterOld/CurveParamSet.cs b/Core/CharterOld/CurveParamSet.cs new file mode 100644 index 0000000..a94d6fd --- /dev/null +++ b/Core/CharterOld/CurveParamSet.cs @@ -0,0 +1,166 @@ +using System.Collections.Generic; +using System.IO; +using LeafWeb.Core.Utility; + +namespace LeafWeb.Core.CharterOld +{ + public class CurveParamSet + { + public List AnetMeasChloro1Data { get; } = new List(); // y=AnetMeas column, x=PCO2c, for PointLimitType=1 + public List AnetMeasChloro2Data { get; } = new List(); // y=AnetMeas column, x=PCO2c, for PointLimitType=2 + public List AnetMeasChloro3Data { get; } = new List(); // y=AnetMeas column, x=PCO2c, for PointLimitType=3 + public List AnetMeasInter1Data { get; } = new List(); // y=AnetMeas column, x=PCO2i, for PointLimitType=1 + public List AnetMeasInter2Data { get; } = new List(); // y=AnetMeas column, x=PCO2i, for PointLimitType=2 + public List AnetMeasInter3Data { get; } = new List(); // y=AnetMeas column, x=PCO2i, for PointLimitType=3 + + public List AcChloroData { get; } = new List(); + public List AjChloroData { get; } = new List(); + public List AtChloroData { get; } = new List(); + public List AcInterData { get; } = new List(); + public List AjInterData { get; } = new List(); + public List AtInterData { get; } = new List(); + + public CurveParamSet(TextReader sr, ref int lineNbr, ref string curveId) + { + bool curveIdSet = false, doneWithAnet = false; + string line; + List phrases; + + while (!doneWithAnet) + { + lineNbr++; + line = sr.ReadLine(); + if (line == null) + { + throw new ParseException("Unexpected end-of-file at line " + lineNbr); + } + + phrases = SplitCsvLine(line); + + var firstField = phrases[0]; + if (firstField.Equals("CO2i")) + { + doneWithAnet = true; + } + else + { + // The fields on the line: + // Column Name + // 0 CurveID + // 1 ChlFlUse + // 2 FitGi + // 3 FitGamma + // 4 FitKco + // 5 FitRd + // 6 FitAlpha + // 7 LimitCombina + // 8 PCO2i + // 9 PCO2c + // 10 AnetMeas + // 11 AnetCal + // 12 weitedrms + // 13 PointLimitType + + if (!curveIdSet) + { + curveId = firstField; + curveIdSet = true; + } + var xyPoint1 = new XyPoint(phrases[9], phrases[10]); // AnetMeas(y), PCO2c(x) + var xyPoint2 = new XyPoint(phrases[8], phrases[10]); + var pointLimitType = int.Parse(phrases[13]); + switch (pointLimitType) + { + case 1: + AnetMeasChloro1Data.Add(xyPoint1); + AnetMeasInter1Data.Add(xyPoint2); + break; + case 2: + AnetMeasChloro2Data.Add(xyPoint1); + AnetMeasInter2Data.Add(xyPoint2); + break; + case 3: + AnetMeasChloro3Data.Add(xyPoint1); + AnetMeasInter3Data.Add(xyPoint2); + break; + } + } + } + + // The next set of lines will have three pairs of x,y-coordinates to save. + // A blank line signals the end of the data. + + var moreData = true; + while (moreData) + { + // The fields on the line: + // Column Name + // 0 CO2i + // 1 CO2cc + // 2 Ac + // 3 CO2cj + // 4 Aj + // 5 CO2ct + // 6 At + + lineNbr++; + line = sr.ReadLine(); + if (line == null) + { + throw new ParseException("Unexpected end-of-file at line " + lineNbr); + } + + if (line.Length == 0) + moreData = false; + else + { + phrases = SplitCsvLine(line); + var xyPoint1 = new XyPoint(phrases[1],phrases[2]); // Ac(y),CO2cc(x) + if (xyPoint1.YIsInRange(-20.0, 50.0)) + AcChloroData.Add(xyPoint1); + xyPoint1 = new XyPoint(phrases[3], phrases[4]); // Aj(y),CO2cj(x) + if (xyPoint1.YIsInRange(-20.0, 50.0)) + AjChloroData.Add(xyPoint1); + xyPoint1 = new XyPoint(phrases[5], phrases[6]); // At(y),CO2ct(x) + if (xyPoint1.YIsInRange(-20.0, 50.0)) + AtChloroData.Add(xyPoint1); + + xyPoint1 = new XyPoint(phrases[0], phrases[2]); // Ac(y),CO2i(x) + if (xyPoint1.YIsInRange(-20.0, 50.0)) + AcInterData.Add(xyPoint1); + xyPoint1 = new XyPoint(phrases[0], phrases[4]); // Aj(y),CO2i(x) + if (xyPoint1.YIsInRange(-20.0, 50.0)) + AjInterData.Add(xyPoint1); + xyPoint1 = new XyPoint(phrases[0], phrases[6]); // At(y),CO2i(x) + if (xyPoint1.YIsInRange(-20.0, 50.0)) + AtInterData.Add(xyPoint1); + } + } + } + + /// + /// This method assumes that the argument is a comma-, blank-, or + /// tab-separated set of strings. It returns an ArrayList of those + /// quantities. Consecutive commas will be returned as an empty string, + /// but all empty strings at the end of the line will be thrown away. + /// + /// + /// + private static List SplitCsvLine(string line) + { + int i; + var separator = new [] {',', ' ', '\t'}; + var phrases = line.Split(separator); + + var retPhrases = new List(); + for (i = 0; i < phrases.Length; i++) + { + var phrase = phrases[i].Trim(); + if (phrase.Length > 0) + retPhrases.Add(phrase); + } + + return retPhrases; + } + } +} \ No newline at end of file diff --git a/Core/CharterOld/XYPoint.cs b/Core/CharterOld/XYPoint.cs new file mode 100644 index 0000000..265add8 --- /dev/null +++ b/Core/CharterOld/XYPoint.cs @@ -0,0 +1,20 @@ +namespace LeafWeb.Core.CharterOld +{ + public class XyPoint + { + public XyPoint(string x, string y) + { + X = double.Parse(x); + Y = double.Parse(y); + } + + public double X { get; private set; } + + public double Y { get; private set; } + + public bool YIsInRange(double lowEnd, double highEnd) + { + return (Y >= lowEnd) && (Y <= highEnd); + } + } +} \ No newline at end of file diff --git a/Core/Core.csproj b/Core/Core.csproj index 3a76622..441170b 100644 --- a/Core/Core.csproj +++ b/Core/Core.csproj @@ -56,18 +56,22 @@ + + + + - - - + + + - + @@ -76,6 +80,7 @@ + diff --git a/Core/Models/CntrlComparison.cs b/Core/Models/CntrlComparison.cs index 85022c4..09c363f 100644 --- a/Core/Models/CntrlComparison.cs +++ b/Core/Models/CntrlComparison.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; +using System.Linq; namespace LeafWeb.Core.Models { @@ -11,5 +11,11 @@ namespace LeafWeb.Core.Models { public virtual IEnumerable FittingInfo { get; set; } public virtual IEnumerable PhotosyntheticInfo { get; set; } + + public string CurveID => FittingInfo.First().CurveID; + + public bool FitGi => FittingInfo.First().FitGi; + + public bool FitGammaStar => FittingInfo.First().FitGammaStar; } } \ No newline at end of file diff --git a/Core/Utility/ReflectionExtensions.cs b/Core/Utility/ReflectionExtensions.cs new file mode 100644 index 0000000..2ac1fe2 --- /dev/null +++ b/Core/Utility/ReflectionExtensions.cs @@ -0,0 +1,46 @@ +using System; +using System.ComponentModel; +using System.Diagnostics; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; +using Fasterflect; + +namespace LeafWeb.Core.Utility +{ + public static class ReflectionExtensions + { + public static string GetPropertyDisplayName(Expression> propertyExpression) + { + var memberInfo = GetPropertyInformation(propertyExpression.Body); + if (memberInfo == null) + { + throw new ArgumentException("No property reference expression was found.", nameof(propertyExpression)); + } + + var attr = memberInfo.Attributes().SingleOrDefault(); + return attr == null ? memberInfo.Name : attr.DisplayName; + } + + public static MemberInfo GetPropertyInformation(Expression propertyExpression) + { + Debug.Assert(propertyExpression != null, "propertyExpression != null"); + var memberExpr = propertyExpression as MemberExpression; + if (memberExpr == null) + { + var unaryExpr = propertyExpression as UnaryExpression; + if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert) + { + memberExpr = unaryExpr.Operand as MemberExpression; + } + } + + if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property) + { + return memberExpr.Member; + } + + return null; + } + } +} \ No newline at end of file diff --git a/LeafWeb.sln b/LeafWeb.sln index a2a37db..763ac46 100644 --- a/LeafWeb.sln +++ b/LeafWeb.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2012 +# Visual Studio 14 +VisualStudioVersion = 14.0.23107.0 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web", "Web\Web.csproj", "{0809033D-DBB9-41AE-8811-9A9CFDFD8966}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web.Tests", "Web.Tests\Web.Tests.csproj", "{0DBE7CB9-71B3-46BA-8045-0F1E36C1C8F7}" @@ -10,6 +12,9 @@ EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core.Tests", "Core.Tests\Core.Tests.csproj", "{8207F6FE-EA80-41CA-81B5-ACD020FB0F3C}" EndProject Global + GlobalSection(Performance) = preSolution + HasPerformanceSessions = true + EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU diff --git a/Web/Charter/LeafWebCharter.cs b/Web/Charter/LeafWebCharter.cs index 654db61..1b08638 100644 --- a/Web/Charter/LeafWebCharter.cs +++ b/Web/Charter/LeafWebCharter.cs @@ -10,22 +10,19 @@ namespace LeafWeb.Web.Charter public static class LeafWebCharter { // cntrlcomparison - public static IEnumerable ProduceCharts(List curveData) + public static IEnumerable ProduceCharts(CurveData curve) { - var curve = curveData[1]; // TODO: why is only the [1] used? - var curveId = curve.CurveId; - var fcfc = CurveSeries(curveId, curve.FixedCndFixedCmp, - "Internal conductance fixed, compensation point and M-M constants fixed"); - var fcec = CurveSeries(curveId, curve.FixedCndEstimatedCmp, - "Internal conductance fixed, compensation point and M-M constants estimated"); - var ecfc = CurveSeries(curveId, curve.EstimatedCndFixedCmp, - "Internal conductance estimated, compensation point and M-M constants fixed"); - var ecec = CurveSeries(curveId, curve.EstimatedCndEstimatedCmp, - "Internal conductance estimated, compensation point and M-M constants estimated"); + 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 new[] {fcfc, fcec, ecfc, ecec}.SelectMany(c => c); + return paramTitles.SelectMany(item => CurveSeries(curveId, item.param, item.title)); } private static IEnumerable CurveSeries(string curveId, CurveParamSet paramSet, string chartTitle) @@ -33,54 +30,36 @@ namespace LeafWeb.Web.Charter var chloroChart = GetChart("Chloroplastic CO2 partial pressure (Pa)"); var interChart = GetChart("Intercellular CO2 partial pressure (Pa)"); - var anetMeasChloro1 = paramSet.AnetMeasChloro1Data; - var anetMeasChloro2 = paramSet.AnetMeasChloro2Data; - var anetMeasChloro3 = paramSet.AnetMeasChloro3Data; - // Set the points for the symbol series for paramater set 1, chloroplastic - SetAnetMeasPoints(anetMeasChloro1, chloroChart.Series["Rubisco-limited"]); - SetAnetMeasPoints(anetMeasChloro2, chloroChart.Series["RuBP regeneration-limited"]); + SetAnetMeasPoints(paramSet.AnetMeasChloro1Data, chloroChart.Series["Rubisco-limited"]); + SetAnetMeasPoints(paramSet.AnetMeasChloro2Data, chloroChart.Series["RuBP regeneration-limited"]); - var tpuSeries = NewTpuSeries(anetMeasChloro3); - SetAnetMeasPoints(anetMeasChloro3, tpuSeries); + var tpuSeries = NewTpuSeries(paramSet.AnetMeasChloro3Data); + SetAnetMeasPoints(paramSet.AnetMeasChloro3Data, tpuSeries); chloroChart.Series.Add(tpuSeries); - var anetMeasInter1 = paramSet.AnetMeasInter1Data; - var anetMeasInter2 = paramSet.AnetMeasInter2Data; - var anetMeasInter3 = paramSet.AnetMeasInter3Data; - // Set the points for the symbol series for paramater set 1, intercellular - SetAnetMeasPoints(anetMeasInter1, interChart.Series["Rubisco-limited"]); - SetAnetMeasPoints(anetMeasInter2, interChart.Series["RuBP regeneration-limited"]); + SetAnetMeasPoints(paramSet.AnetMeasInter1Data, interChart.Series["Rubisco-limited"]); + SetAnetMeasPoints(paramSet.AnetMeasInter2Data, interChart.Series["RuBP regeneration-limited"]); - tpuSeries = NewTpuSeries(anetMeasInter3); - SetAnetMeasPoints(anetMeasInter3, tpuSeries); + tpuSeries = NewTpuSeries(paramSet.AnetMeasInter3Data); + SetAnetMeasPoints(paramSet.AnetMeasInter3Data, tpuSeries); interChart.Series.Add(tpuSeries); - var acChloroList = paramSet.AcChloroData; - var ajChloroList = paramSet.AjChloroData; - var atChloroList = paramSet.AtChloroData; - // Set the points on the asymptote curve for parameter set 1, chloroplast - SetAsymptotePoints(acChloroList, chloroChart.Series["acCurve"]); - SetAsymptotePoints(ajChloroList, chloroChart.Series["ajCurve"]); - SetAsymptotePoints(atChloroList, chloroChart.Series["atCurve"]); - - var acInterList = paramSet.AcInterData; - var ajInterList = paramSet.AjInterData; - var atInterList = paramSet.AtInterData; + 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(acInterList, interChart.Series["acCurve"]); - SetAsymptotePoints(ajInterList, interChart.Series["ajCurve"]); - SetAsymptotePoints(atInterList, interChart.Series["atCurve"]); + 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}; + var title = new Title($"LeafWeb curveID = {curveId}\n{chartTitle}"){Font = titleFont}; chloroChart.Titles.Add(title); interChart.Titles.Add(title); @@ -89,6 +68,7 @@ namespace LeafWeb.Web.Charter interChart.ChartAreas["ChartArea1"].AxisX.TitleFont = axisFont; interChart.ChartAreas["ChartArea1"].AxisY.TitleFont = axisFont; + yield return chloroChart; yield return interChart; } @@ -196,7 +176,7 @@ namespace LeafWeb.Web.Charter } }); - var rubiscoLimited = new Series + chart.Series.Add(new Series { MarkerSize = 8, BorderWidth = 3, @@ -209,10 +189,9 @@ namespace LeafWeb.Web.Charter Color = Color.Red, ShadowOffset = 0, YValueType = ChartValueType.Double - }; - chart.Series.Add(rubiscoLimited); + }); - var rubpRegenerationLimited = new Series + chart.Series.Add(new Series { MarkerSize = 9, BorderWidth = 3, @@ -225,10 +204,9 @@ namespace LeafWeb.Web.Charter Color = Color.Blue, ShadowOffset = 0, YValueType = ChartValueType.Double - }; - chart.Series.Add(rubpRegenerationLimited); + }); - var acCurve = new Series + chart.Series.Add(new Series { MarkerSize = 2, BorderWidth = 1, @@ -242,10 +220,9 @@ namespace LeafWeb.Web.Charter ShadowOffset = 0, YValueType = ChartValueType.Double, IsVisibleInLegend = false - }; - chart.Series.Add(acCurve); + }); - var ajCurve = new Series + chart.Series.Add(new Series { MarkerSize = 2, BorderWidth = 1, @@ -259,10 +236,9 @@ namespace LeafWeb.Web.Charter ShadowOffset = 0, YValueType = ChartValueType.Double, IsVisibleInLegend = false - }; - chart.Series.Add(ajCurve); + }); - var atCurve = new Series + chart.Series.Add(new Series { MarkerSize = 2, BorderWidth = 1, @@ -276,8 +252,7 @@ namespace LeafWeb.Web.Charter ShadowOffset = 0, YValueType = ChartValueType.Double, IsVisibleInLegend = false - }; - chart.Series.Add(atCurve); + }); return chart; } diff --git a/Web/Charter/LeafWebCharterOld.cs b/Web/Charter/LeafWebCharterOld.cs new file mode 100644 index 0000000..fa5dd13 --- /dev/null +++ b/Web/Charter/LeafWebCharterOld.cs @@ -0,0 +1,262 @@ +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using System.Web.UI.DataVisualization.Charting; +using System.Web.UI.WebControls; +using CurveData = LeafWeb.Core.CharterOld.CurveData; +using CurveParamSet = LeafWeb.Core.CharterOld.CurveParamSet; +using XyPoint = LeafWeb.Core.CharterOld.XyPoint; + +namespace LeafWeb.Web.Charter +{ + public static class LeafWebCharterOld + { + // 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; + } + } +} \ No newline at end of file diff --git a/Web/Controllers/LeafCharterController.cs b/Web/Controllers/LeafCharterController.cs index 7391076..44a9840 100644 --- a/Web/Controllers/LeafCharterController.cs +++ b/Web/Controllers/LeafCharterController.cs @@ -1,13 +1,14 @@ using System; -using System.Collections.Generic; using System.Drawing; using System.IO; using System.Linq; -using System.Web; using System.Web.Mvc; using System.Web.UI.DataVisualization.Charting; using System.Web.UI.WebControls; using LeafWeb.Core.Charter; +using LeafWeb.Core.CharterOld; +using LeafWeb.Core.Models; +using LeafWeb.Core.Parsers; using LeafWeb.Web.Charter; namespace LeafWeb.Web.Controllers @@ -20,6 +21,27 @@ namespace LeafWeb.Web.Controllers } public ActionResult LeafCharts(int number) + { + var fileInfo = new FileInfo(@"C:\Users\poprhythm\Documents\code\LeafWeb\Core.Tests\Parsers\LeafOutputData\cntrlcomparison_Wild Capsicum.csv"); + + CntrlComparison[] cntrlComparison; + using (var parser = new CntrlComparisonParser(fileInfo)) + cntrlComparison = parser.Parse(); + + var curveData = CurveDataConverter.Convert(cntrlComparison).ToArray(); + + var charts = LeafWebCharter.ProduceCharts(curveData[1]); + + using (var ms = new MemoryStream()) + { + charts.Skip(number).First().SaveImage(ms, ChartImageFormat.Png); + ms.Seek(0, SeekOrigin.Begin); + + return File(ms.ToArray(), "image/png", "mychart.png"); + } + } + + public ActionResult LeafChartsOld(int number) { var fileInfo = new FileInfo(@"C:\Users\poprhythm\Documents\code\LeafWeb\Core.Tests\Parsers\LeafOutputData\cntrlcomparison_Wild Capsicum.csv"); var curveDataList = new CurveDataList(); @@ -27,7 +49,7 @@ namespace LeafWeb.Web.Controllers { curveDataList.ReadFromStream(reader); } - var charts = LeafWebCharter.ProduceCharts(curveDataList.CurveData); + var charts = LeafWebCharterOld.ProduceCharts(curveDataList.CurveData[1]); using (var ms = new MemoryStream()) { diff --git a/Web/Scripts/angular.js b/Web/Scripts/angular.js index 34a93c1..3c64efb 100644 --- a/Web/Scripts/angular.js +++ b/Web/Scripts/angular.js @@ -1,4 +1,4 @@ -/** +/** * @license AngularJS v1.4.7 * (c) 2010-2015 Google, Inc. http://angularjs.org * License: MIT diff --git a/Web/Views/LeafCharter/Index.cshtml b/Web/Views/LeafCharter/Index.cshtml index 3d42a7a..317584d 100644 --- a/Web/Views/LeafCharter/Index.cshtml +++ b/Web/Views/LeafCharter/Index.cshtml @@ -1,8 +1,8 @@ image -image +@*image image image image image image -image \ No newline at end of file +image*@ \ No newline at end of file diff --git a/Web/Web.csproj b/Web/Web.csproj index 0344369..21117db 100644 --- a/Web/Web.csproj +++ b/Web/Web.csproj @@ -143,6 +143,7 @@ + diff --git a/Web_151207.vspx b/Web_151207.vspx new file mode 100644 index 0000000..f3b6a26 Binary files /dev/null and b/Web_151207.vspx differ