Changeset 15110 for trunk/sources/HeuristicLab.DataPreprocessing
- Timestamp:
- 07/03/17 10:57:53 (8 years ago)
- Location:
- trunk/sources/HeuristicLab.DataPreprocessing
- Files:
-
- 2 deleted
- 26 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/sources/HeuristicLab.DataPreprocessing
-
Property
svn:mergeinfo
set to
/branches/DataPreprocessing Enhancements/HeuristicLab.DataPreprocessing merged eligible
-
Property
svn:mergeinfo
set to
-
trunk/sources/HeuristicLab.DataPreprocessing/3.4
-
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/CorrelationMatrixContent.cs
r14185 r15110 27 27 namespace HeuristicLab.DataPreprocessing { 28 28 [Item("Feature Correlation Matrix", "Represents the feature correlation matrix.")] 29 public class CorrelationMatrixContent : Item, IView ChartShortcut {29 public class CorrelationMatrixContent : Item, IViewShortcut { 30 30 public static new Image StaticItemImage { 31 31 get { return HeuristicLab.Common.Resources.VSImageLibrary.Gradient; } 32 32 } 33 33 34 p rivate PreprocessingContext Context { get;set; }35 p rivateITransactionalPreprocessingData PreprocessingData {34 public PreprocessingContext Context { get; private set; } 35 public ITransactionalPreprocessingData PreprocessingData { 36 36 get { return Context.Data; } 37 37 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/DataCompletenessChartContent.cs
r13508 r15110 1 using System.Drawing; 1 #region License Information 2 /* HeuristicLab 3 * Copyright (C) 2002-2016 Heuristic and Evolutionary Algorithms Laboratory (HEAL) 4 * 5 * This file is part of HeuristicLab. 6 * 7 * HeuristicLab is free software: you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * 12 * HeuristicLab is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 #endregion 21 22 using System.Drawing; 2 23 using HeuristicLab.Common; 3 24 using HeuristicLab.Core; 4 25 5 26 namespace HeuristicLab.DataPreprocessing { 6 [Item("Data CompletenessChart", "Represents a datacompleteness chart.")]27 [Item("Data Completeness Chart", "Represents a datacompleteness chart.")] 7 28 8 public class DataCompletenessChartContent : Item, IView ChartShortcut {29 public class DataCompletenessChartContent : Item, IViewShortcut { 9 30 public static new Image StaticItemImage { 10 31 get { return HeuristicLab.Common.Resources.VSImageLibrary.EditBrightnessContrast; } 11 32 } 12 33 13 //public DataGridLogic DataGridLogic { get; private set; }14 34 public SearchLogic SearchLogic { get; private set; } 15 35 -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/DataGridContent.cs
r14185 r15110 30 30 namespace HeuristicLab.DataPreprocessing { 31 31 32 [Item("Data Grid", "Represents a data grid.")]32 [Item("Data Grid", "Represents a data grid.")] 33 33 public class DataGridContent : Item, IStringConvertibleMatrix, IViewShortcut { 34 35 public ITransactionalPreprocessingData PreProcessingData { get; private set; }36 37 34 public static new Image StaticItemImage { 38 35 get { return HeuristicLab.Common.Resources.VSImageLibrary.Table; } 39 36 } 37 38 public ITransactionalPreprocessingData PreProcessingData { get; private set; } 40 39 41 40 public ManipulationLogic ManipulationLogic { get; private set; } … … 43 42 44 43 public int Rows { 45 get { 46 return PreProcessingData.Rows; 47 } 48 set { 49 //does nothing 50 } 44 get { return PreProcessingData.Rows; } 45 set { } 51 46 } 52 47 53 48 public int Columns { 54 get { 55 return PreProcessingData.Columns; 56 } 57 set { 58 //does nothing 59 } 49 get { return PreProcessingData.Columns; } 50 set { } 60 51 } 61 52 62 53 public IEnumerable<string> ColumnNames { 63 get { 64 return PreProcessingData.VariableNames; 65 } 66 set { 67 68 } 54 get { return PreProcessingData.VariableNames; } 55 set { } 69 56 } 70 57 71 58 public IEnumerable<string> RowNames { 72 get { 73 return Enumerable.Range(1, Rows).Select(n => n.ToString()); 74 } 75 set { 76 throw new NotSupportedException(); 77 } 59 get { return Enumerable.Range(1, Rows).Select(n => n.ToString()); } 60 set { throw new NotSupportedException(); } 78 61 } 79 62 80 63 public bool SortableView { 81 get { 82 return true; 83 } 84 set { 85 throw new NotSupportedException(); 86 } 64 get { return true; } 65 set { throw new NotSupportedException(); } 87 66 } 88 67 … … 91 70 } 92 71 93 94 72 public IDictionary<int, IList<int>> Selection { 95 73 get { return PreProcessingData.Selection; } 96 74 set { PreProcessingData.Selection = value; } 97 75 } 98 99 76 100 77 public DataGridContent(ITransactionalPreprocessingData preProcessingData, ManipulationLogic theManipulationLogic, FilterLogic theFilterLogic) { … … 137 114 } 138 115 139 140 116 #region unused stuff/not implemented but necessary due to IStringConvertibleMatrix 141 117 #pragma warning disable 0067 … … 154 130 public event EventHandler<EventArgs<int, int>> ItemChanged; 155 131 public event EventHandler Reset; 156 157 132 #pragma warning restore 0067 158 133 #endregion 159 160 134 } 161 135 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/FilterContent.cs
r14185 r15110 28 28 [Item("Filter", "Represents the filter grid.")] 29 29 public class FilterContent : Item, IViewShortcut { 30 31 30 public static new Image StaticItemImage { 32 31 get { return HeuristicLab.Common.Resources.VSImageLibrary.Filter; } 33 32 } 34 33 35 private ICheckedItemCollection<IFilter> filters = new CheckedItemCollection<IFilter>();36 37 34 public FilterLogic FilterLogic { get; private set; } 38 35 39 public ICheckedItemCollection<IFilter> Filters { 40 get { 41 return this.filters; 42 } 43 set { 44 this.filters = value; 45 } 46 } 36 public ICheckedItemCollection<IFilter> Filters { get; private set; } 47 37 48 private bool isAndCombination = true; 49 public bool IsAndCombination { 50 get { 51 return this.isAndCombination; 52 } 53 set { 54 this.isAndCombination = value; 55 } 56 } 38 public bool IsAndCombination { get; set; } 57 39 58 40 public FilterContent(FilterLogic filterLogic) { 41 Filters = new CheckedItemCollection<IFilter>(); 42 IsAndCombination = true; 59 43 FilterLogic = filterLogic; 60 44 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/HistogramContent.cs
r14185 r15110 20 20 #endregion 21 21 22 using System .Collections.Generic;22 using System; 23 23 using System.Drawing; 24 24 using System.Linq; 25 using HeuristicLab.Analysis; 25 26 using HeuristicLab.Common; 26 27 using HeuristicLab.Core; … … 29 30 [Item("Histogram", "Represents the histogram grid.")] 30 31 public class HistogramContent : PreprocessingChartContent { 31 32 32 public static new Image StaticItemImage { 33 33 get { return HeuristicLab.Common.Resources.VSImageLibrary.Statistics; } 34 34 } 35 private const int MAX_DISTINCT_VALUES_FOR_CLASSIFCATION = 20;36 35 37 p rivate int classifierVariableIndex = 0;36 public string GroupingVariableName { get; set; } 38 37 39 public int ClassifierVariableIndex { 40 get { return this.classifierVariableIndex; } 41 set { this.classifierVariableIndex = value; } 42 } 43 public bool IsDetailedChartViewEnabled { get; set; } 38 public int Bins { get; set; } 39 public bool ExactBins { get; set; } 44 40 41 public LegendOrder Order { get; set; } 45 42 46 43 public HistogramContent(IFilteredPreprocessingData preprocessingData) 47 44 : base(preprocessingData) { 48 AllInOneMode = false; 45 Bins = 10; 46 ExactBins = false; 49 47 } 50 48 … … 56 54 } 57 55 58 public IEnumerable<string> GetVariableNamesForHistogramClassification() { 59 List<string> doubleVariableNames = new List<string>(); 56 public static DataTable CreateHistogram(IFilteredPreprocessingData preprocessingData, string variableName, string groupingVariableName, DataTableVisualProperties.DataTableHistogramAggregation aggregation, LegendOrder legendOrder = LegendOrder.Appearance) { 57 var dataTable = new DataTable { 58 VisualProperties = { Title = variableName, HistogramAggregation = aggregation }, 59 }; 60 60 61 //only return variable names from type double 62 for (int i = 0; i < PreprocessingData.Columns; ++i) { 63 if (PreprocessingData.VariableHasType<double>(i)) { 64 double distinctValueCount = PreprocessingData.GetValues<double>(i).GroupBy(x => x).Count(); 65 bool distinctValuesOk = distinctValueCount <= MAX_DISTINCT_VALUES_FOR_CLASSIFCATION; 66 if (distinctValuesOk) 67 doubleVariableNames.Add(PreprocessingData.GetVariableName(i)); 68 } 61 if (string.IsNullOrEmpty(groupingVariableName)) { 62 var row = PreprocessingChartContent.CreateDataRow(preprocessingData, variableName, DataRowVisualProperties.DataRowChartType.Histogram); 63 row.VisualProperties.IsVisibleInLegend = false; 64 dataTable.Rows.Add(row); 65 return dataTable; 69 66 } 70 return doubleVariableNames; 67 68 int variableIndex = preprocessingData.GetColumnIndex(variableName); 69 var variableValues = preprocessingData.GetValues<double>(variableIndex); 70 int groupVariableIndex = preprocessingData.GetColumnIndex(groupingVariableName); 71 var groupingValues = Enumerable.Empty<string>(); 72 73 if (preprocessingData.VariableHasType<double>(groupVariableIndex)) { 74 groupingValues = preprocessingData.GetValues<double>(groupVariableIndex).Select(x => x.ToString()); 75 } else if (preprocessingData.VariableHasType<string>(groupVariableIndex)) { 76 groupingValues = preprocessingData.GetValues<string>(groupVariableIndex); 77 } else if (preprocessingData.VariableHasType<DateTime>(groupVariableIndex)) { 78 groupingValues = preprocessingData.GetValues<DateTime>(groupVariableIndex).Select(x => x.ToString()); 79 } 80 81 var groups = groupingValues.Zip(variableValues, Tuple.Create).GroupBy(t => t.Item1, t => t.Item2); 82 83 if (legendOrder == LegendOrder.Alphabetically) 84 groups = groups.OrderBy(x => x.Key, new NaturalStringComparer()); 85 86 foreach (var group in groups) { 87 var classRow = new DataRow { 88 Name = group.Key, 89 VisualProperties = { 90 ChartType = DataRowVisualProperties.DataRowChartType.Histogram, 91 IsVisibleInLegend = !string.IsNullOrEmpty(groupingVariableName) 92 } 93 }; 94 classRow.Values.AddRange(group); 95 dataTable.Rows.Add(classRow); 96 } 97 return dataTable; 71 98 } 72 73 99 } 74 100 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/LineChartContent.cs
r14185 r15110 26 26 namespace HeuristicLab.DataPreprocessing { 27 27 28 [Item("Line Chart", "Represents the line chart grid.")]28 [Item("Line Chart", "Represents the line chart grid.")] 29 29 public class LineChartContent : PreprocessingChartContent { 30 public bool AllInOneMode { get; set; } 30 31 31 32 public static new Image StaticItemImage { … … 35 36 public LineChartContent(IFilteredPreprocessingData preprocessingData) 36 37 : base(preprocessingData) { 38 AllInOneMode = true; 37 39 } 38 40 39 41 public LineChartContent(LineChartContent content, Cloner cloner) 40 42 : base(content, cloner) { 43 this.AllInOneMode = content.AllInOneMode; 41 44 } 42 45 public override IDeepCloneable Clone(Cloner cloner) { -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/ManipulationContent.cs
r14185 r15110 28 28 [Item("Manipulation", "Represents the available manipulations on a data set.")] 29 29 public class ManipulationContent : Item, IViewShortcut { 30 31 private ManipulationLogic manipulationLogic;32 private SearchLogic searchLogic;33 private FilterLogic filterLogic;34 35 public ManipulationLogic ManipulationLogic { get { return manipulationLogic; } }36 public SearchLogic SearchLogic { get { return searchLogic; } }37 public FilterLogic FilterLogic { get { return filterLogic; } }38 39 30 public static new Image StaticItemImage { 40 31 get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; } 41 32 } 42 33 43 public ManipulationContent(ManipulationLogic theManipulationLogic, SearchLogic theSearchLogic, FilterLogic theFilterLogic) { 44 manipulationLogic = theManipulationLogic; 45 searchLogic = theSearchLogic; 46 filterLogic = theFilterLogic; 34 public ManipulationLogic ManipulationLogic { get; private set; } 35 public SearchLogic SearchLogic { get; private set; } 36 public FilterLogic FilterLogic { get; private set; } 37 38 public ManipulationContent(ManipulationLogic manipulationLogic, SearchLogic searchLogic, FilterLogic filterLogic) { 39 ManipulationLogic = manipulationLogic; 40 SearchLogic = searchLogic; 41 FilterLogic = filterLogic; 47 42 } 48 43 … … 52 47 return new ManipulationContent(this, cloner); 53 48 } 54 55 56 49 } 57 50 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/PreprocessingChartContent.cs
r14418 r15110 23 23 using System.Collections.Generic; 24 24 using System.Drawing; 25 using System.Linq; 25 26 using HeuristicLab.Analysis; 26 27 using HeuristicLab.Common; 28 using HeuristicLab.Common.Resources; 27 29 using HeuristicLab.Core; 28 30 using HeuristicLab.Data; … … 30 32 namespace HeuristicLab.DataPreprocessing { 31 33 [Item("PreprocessingChart", "Represents a preprocessing chart.")] 32 public class PreprocessingChartContent : Item, IViewChartShortcut { 33 public static new Image StaticItemImage { 34 get { return HeuristicLab.Common.Resources.VSImageLibrary.PieChart; } 34 public class PreprocessingChartContent : Item, IViewShortcut { 35 public enum LegendOrder { 36 Appearance, 37 Alphabetically 35 38 } 36 39 37 private bool allInOneMode = true; 38 public bool AllInOneMode { 39 get { return this.allInOneMode; } 40 set { this.allInOneMode = value; } 40 public static new Image StaticItemImage { 41 get { return VSImageLibrary.PieChart; } 41 42 } 42 43 43 44 private ICheckedItemList<StringValue> variableItemList = null; 44 45 public ICheckedItemList<StringValue> VariableItemList { 45 get { return this.variableItemList; } 46 set { this.variableItemList = value; } 46 get { 47 if (variableItemList == null) 48 variableItemList = CreateVariableItemList(PreprocessingData); 49 return this.variableItemList; 50 } 47 51 } 48 52 49 53 public IFilteredPreprocessingData PreprocessingData { get; private set; } 54 public event DataPreprocessingChangedEventHandler Changed { 55 add { PreprocessingData.Changed += value; } 56 remove { PreprocessingData.Changed -= value; } 57 } 50 58 51 59 public PreprocessingChartContent(IFilteredPreprocessingData preprocessingData) { … … 55 63 public PreprocessingChartContent(PreprocessingChartContent content, Cloner cloner) 56 64 : base(content, cloner) { 57 this.allInOneMode = content.allInOneMode;58 65 this.PreprocessingData = content.PreprocessingData; 59 66 this.variableItemList = cloner.Clone<ICheckedItemList<StringValue>>(variableItemList); … … 63 70 } 64 71 72 public DataRow CreateDataRow(string variableName, DataRowVisualProperties.DataRowChartType chartType) { 73 return CreateDataRow(PreprocessingData, variableName, chartType); 74 } 65 75 66 public DataRow CreateDataRow(string variableName, DataRowVisualProperties.DataRowChartType chartType) {67 IList<double> values = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableName));76 public static DataRow CreateDataRow(IFilteredPreprocessingData preprocessingData, string variableName, DataRowVisualProperties.DataRowChartType chartType) { 77 IList<double> values = preprocessingData.GetValues<double>(preprocessingData.GetColumnIndex(variableName)); 68 78 DataRow row = new DataRow(variableName, "", values); 69 79 row.VisualProperties.ChartType = chartType; … … 71 81 } 72 82 73 public List<DataRow> CreateAllDataRows(DataRowVisualProperties.DataRowChartType chartType) { 74 List<DataRow> dataRows = new List<DataRow>(); 75 foreach (var name in PreprocessingData.GetDoubleVariableNames()) 76 dataRows.Add(CreateDataRow(name, chartType)); 77 return dataRows; 78 } 79 80 public DataRow CreateSelectedDataRow(string variableName, DataRowVisualProperties.DataRowChartType chartType) { 81 82 IDictionary<int, IList<int>> selection = PreprocessingData.Selection; 83 int variableIndex = PreprocessingData.GetColumnIndex(variableName); 84 85 if (selection.Keys.Contains(variableIndex)) { 86 List<int> selectedIndices = new List<int>(selection[variableIndex]); 87 //need selection with more than 1 value 88 if (selectedIndices.Count < 2) 89 return null; 90 91 selectedIndices.Sort(); 92 int start = selectedIndices[0]; 93 int end = selectedIndices[selectedIndices.Count - 1]; 94 95 DataRow rowSelect = CreateDataRowRange(variableName, start, end, chartType); 96 return rowSelect; 97 } else 98 return null; 99 } 100 101 public DataRow CreateDataRowRange(string variableName, int start, int end, DataRowVisualProperties.DataRowChartType chartType) { 102 IList<double> values = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableName)); 103 IList<double> valuesRange = new List<double>(); 104 for (int i = 0; i < values.Count; i++) { 105 if (i >= start && i <= end) 106 valuesRange.Add(values[i]); 107 else 108 valuesRange.Add(Double.NaN); 109 } 110 111 DataRow row = new DataRow(variableName, "", valuesRange); 112 row.VisualProperties.ChartType = chartType; 113 return row; 114 } 115 116 public List<DataRow> CreateAllSelectedDataRows(DataRowVisualProperties.DataRowChartType chartType) { 117 List<DataRow> dataRows = new List<DataRow>(); 118 foreach (var name in PreprocessingData.GetDoubleVariableNames()) { 119 DataRow row = CreateSelectedDataRow(name, chartType); 120 if (row != null) 121 dataRows.Add(row); 122 } 123 return dataRows; 124 } 125 126 127 public ICheckedItemList<StringValue> CreateVariableItemList(IList<string> checkedItems = null) { 128 if (checkedItems == null) checkedItems = new string[0]; 83 private static ICheckedItemList<StringValue> CreateVariableItemList(IPreprocessingData preprocessingData) { 129 84 ICheckedItemList<StringValue> itemList = new CheckedItemList<StringValue>(); 130 foreach (string name in PreprocessingData.GetDoubleVariableNames()) {85 foreach (string name in preprocessingData.GetDoubleVariableNames()) { 131 86 var n = new StringValue(name); 132 itemList.Add(n, checkedItems.Contains(name)); 87 bool isInputTarget = preprocessingData.InputVariables.Contains(name) || preprocessingData.TargetVariable == name; 88 itemList.Add(n, isInputTarget); 133 89 } 134 90 return new ReadOnlyCheckedItemList<StringValue>(itemList); 135 91 } 136 92 137 public event DataPreprocessingChangedEventHandler Changed { 138 add { PreprocessingData.Changed += value; } 139 remove { PreprocessingData.Changed -= value; } 93 private const int MAX_DISTINCT_VALUES_FOR_GROUPING = 20; 94 public static IEnumerable<string> GetVariableNamesForGrouping(IPreprocessingData preprocessingData) { 95 var variableNames = new List<string>(); 96 97 for (int i = 0; i < preprocessingData.Columns; ++i) { 98 int distinctValues = Int32.MaxValue; 99 if (preprocessingData.VariableHasType<double>(i)) 100 distinctValues = preprocessingData.GetValues<double>(i).GroupBy(x => x).Count(); 101 else if (preprocessingData.VariableHasType<string>(i)) 102 distinctValues = preprocessingData.GetValues<string>(i).GroupBy(x => x).Count(); 103 else if (preprocessingData.VariableHasType<DateTime>(i)) 104 distinctValues = preprocessingData.GetValues<DateTime>(i).GroupBy(x => x).Count(); 105 106 if (distinctValues <= MAX_DISTINCT_VALUES_FOR_GROUPING) 107 variableNames.Add(preprocessingData.GetVariableName(i)); 108 } 109 return variableNames; 140 110 } 141 142 111 } 143 112 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/ScatterPlotContent.cs
r14185 r15110 20 20 #endregion 21 21 22 using System; 22 23 using System.Collections.Generic; 23 using System.Drawing;24 24 using System.Linq; 25 25 using HeuristicLab.Analysis; 26 26 using HeuristicLab.Common; 27 using HeuristicLab. Core;27 using HeuristicLab.Visualization.ChartControlsExtensions; 28 28 29 29 namespace HeuristicLab.DataPreprocessing { 30 30 31 [Item("ScatterPlot", "Represents a scatter plot.")]32 public class ScatterPlotContent : PreprocessingChartContent {31 public abstract class ScatterPlotContent : PreprocessingChartContent { 32 public string GroupingVariable { get; set; } 33 33 34 public string SelectedXVariable { get; set; } 35 public string SelectedYVariable { get; set; } 36 public string SelectedColorVariable { get; set; } 37 38 public ScatterPlotContent(IFilteredPreprocessingData preprocessingData) 34 protected ScatterPlotContent(IFilteredPreprocessingData preprocessingData) 39 35 : base(preprocessingData) { 40 36 } 41 37 42 p ublicScatterPlotContent(ScatterPlotContent content, Cloner cloner)38 protected ScatterPlotContent(ScatterPlotContent content, Cloner cloner) 43 39 : base(content, cloner) { 44 this.SelectedXVariable = content.SelectedXVariable;45 this.SelectedYVariable = content.SelectedYVariable;46 this.SelectedColorVariable = content.SelectedColorVariable;47 40 } 48 41 49 public static new Image StaticItemImage { 50 get { return HeuristicLab.Common.Resources.VSImageLibrary.Performance; } 51 } 52 53 public override IDeepCloneable Clone(Cloner cloner) { 54 return new ScatterPlotContent(this, cloner); 55 } 56 57 public ScatterPlot CreateScatterPlot(string variableNameX, string variableNameY, string variableNameColor = "-") { 42 public static ScatterPlot CreateScatterPlot(IFilteredPreprocessingData preprocessingData, string variableNameX, string variableNameY, string variableNameGroup = "-", LegendOrder legendOrder = LegendOrder.Appearance) { 58 43 ScatterPlot scatterPlot = new ScatterPlot(); 59 44 60 IList<double> xValues = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableNameX)); 61 IList<double> yValues = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableNameY)); 62 if (variableNameColor == null || variableNameColor == "-") { 63 List<Point2D<double>> points = new List<Point2D<double>>(); 45 IList<double> xValues = preprocessingData.GetValues<double>(preprocessingData.GetColumnIndex(variableNameX)); 46 IList<double> yValues = preprocessingData.GetValues<double>(preprocessingData.GetColumnIndex(variableNameY)); 64 47 65 for (int i = 0; i < xValues.Count; i++) { 66 Point2D<double> point = new Point2D<double>(xValues[i], yValues[i]); 67 points.Add(point); 68 } 48 var points = xValues.Zip(yValues, (x, y) => new Point2D<double>(x, y)).ToList(); 49 var validPoints = points.Where(p => !double.IsNaN(p.X) && !double.IsNaN(p.Y) && !double.IsInfinity(p.X) && !double.IsInfinity(p.Y)).ToList(); 50 if (validPoints.Any()) { 51 try { 52 double axisMin, axisMax, axisInterval; 53 ChartUtil.CalculateOptimalAxisInterval(validPoints.Min(p => p.X), validPoints.Max(p => p.X), out axisMin, out axisMax, out axisInterval); 54 scatterPlot.VisualProperties.XAxisMinimumAuto = false; 55 scatterPlot.VisualProperties.XAxisMaximumAuto = false; 56 scatterPlot.VisualProperties.XAxisMinimumFixedValue = axisMin; 57 scatterPlot.VisualProperties.XAxisMaximumFixedValue = axisMax; 58 } catch (ArgumentOutOfRangeException) { } // error during CalculateOptimalAxisInterval 59 try { 60 double axisMin, axisMax, axisInterval; 61 ChartUtil.CalculateOptimalAxisInterval(validPoints.Min(p => p.Y), validPoints.Max(p => p.Y), out axisMin, out axisMax, out axisInterval); 62 scatterPlot.VisualProperties.YAxisMinimumAuto = false; 63 scatterPlot.VisualProperties.YAxisMaximumAuto = false; 64 scatterPlot.VisualProperties.YAxisMinimumFixedValue = axisMin; 65 scatterPlot.VisualProperties.YAxisMaximumFixedValue = axisMax; 66 } catch (ArgumentOutOfRangeException) { } // error during CalculateOptimalAxisInterval 67 } 69 68 70 ScatterPlotDataRow scdr = new ScatterPlotDataRow(variableNameX + " - " + variableNameY, "", points); 69 70 //No Grouping 71 if (string.IsNullOrEmpty(variableNameGroup) || variableNameGroup == "-") { 72 ScatterPlotDataRow scdr = new ScatterPlotDataRow(variableNameX + " - " + variableNameY, "", validPoints); 73 scdr.VisualProperties.IsVisibleInLegend = false; 71 74 scatterPlot.Rows.Add(scdr); 75 return scatterPlot; 76 } 72 77 73 } else { 74 var colorValues = PreprocessingData.GetValues<double>(PreprocessingData.GetColumnIndex(variableNameColor)); 75 var data = xValues.Zip(yValues, (x, y) => new { x, y }).Zip(colorValues, (v, c) => new { v.x, v.y, c }).ToList(); 76 var gradients = ColorGradient.Colors; 77 int curGradient = 0; 78 int numColors = colorValues.Distinct().Count(); 79 foreach (var colorValue in colorValues.Distinct()) { 80 var values = data.Where(x => x.c == colorValue); 81 var row = new ScatterPlotDataRow( 82 variableNameX + " - " + variableNameY + " (" + colorValue + ")", 83 "", 84 values.Select(v => new Point2D<double>(v.x, v.y)), 85 new ScatterPlotDataRowVisualProperties() { Color = gradients[curGradient] }); 86 curGradient += gradients.Count / numColors; 87 scatterPlot.Rows.Add(row); 88 } 78 //Grouping 79 int groupVariableIndex = preprocessingData.GetColumnIndex(variableNameGroup); 80 var groupingValues = Enumerable.Empty<string>(); 81 82 if (preprocessingData.VariableHasType<double>(groupVariableIndex)) { 83 groupingValues = preprocessingData.GetValues<double>(groupVariableIndex).Select(x => x.ToString()); 84 } else if (preprocessingData.VariableHasType<string>(groupVariableIndex)) { 85 groupingValues = preprocessingData.GetValues<string>(groupVariableIndex); 86 } else if (preprocessingData.VariableHasType<DateTime>(groupVariableIndex)) { 87 groupingValues = preprocessingData.GetValues<DateTime>(groupVariableIndex).Select(x => x.ToString()); 88 } 89 var groups = groupingValues.Zip(validPoints, Tuple.Create).GroupBy(t => t.Item1, t => t.Item2); 90 91 if (legendOrder == LegendOrder.Alphabetically) 92 groups = groups.OrderBy(x => x.Key, new NaturalStringComparer()); 93 94 foreach (var group in groups) { 95 var scdr = new ScatterPlotDataRow { 96 Name = group.Key, 97 VisualProperties = { 98 IsVisibleInLegend = true, 99 PointSize = 6 100 } 101 }; 102 scdr.Points.AddRange(group); 103 scatterPlot.Rows.Add(scdr); 89 104 } 90 105 return scatterPlot; -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/StatisticsContent.cs
r14185 r15110 27 27 [Item("Statistics", "Represents the statistics grid.")] 28 28 public class StatisticsContent : Item, IViewShortcut { 29 public static new Image StaticItemImage { 30 get { return HeuristicLab.Common.Resources.VSImageLibrary.Object; } 31 } 29 32 30 private readonly StatisticsLogic statisticsLogic; 31 public StatisticsContent(StatisticsLogic theStatisticsLogic) { 32 statisticsLogic = theStatisticsLogic; 33 public ITransactionalPreprocessingData PreprocessingData { get; private set; } 34 public StatisticsLogic StatisticsLogic { get; private set; } 35 36 public StatisticsContent(ITransactionalPreprocessingData preProcessingData, StatisticsLogic statisticsLogic) { 37 PreprocessingData = preProcessingData; 38 StatisticsLogic = statisticsLogic; 33 39 } 34 40 35 41 public StatisticsContent(StatisticsContent content, Cloner cloner) 36 42 : base(content, cloner) { 37 38 }39 40 public StatisticsLogic StatisticsLogic {41 get { return statisticsLogic; }42 }43 44 public static new Image StaticItemImage {45 get { return HeuristicLab.Common.Resources.VSImageLibrary.Object; }46 43 } 47 44 … … 51 48 52 49 public event DataPreprocessingChangedEventHandler Changed { 53 add { statisticsLogic.Changed += value; }54 remove { statisticsLogic.Changed -= value; }50 add { StatisticsLogic.Changed += value; } 51 remove { StatisticsLogic.Changed -= value; } 55 52 } 56 57 53 } 58 54 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Content/TransformationContent.cs
r14185 r15110 28 28 [Item("Transformation", "Represents the transformation grid.")] 29 29 public class TransformationContent : Item, IViewShortcut { 30 public static new Image StaticItemImage { 31 get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; } 32 } 30 33 31 34 public IPreprocessingData Data { get; private set; } … … 33 36 34 37 public ICheckedItemList<ITransformation> CheckedTransformationList { get; private set; } 35 36 public static new Image StaticItemImage {37 get { return HeuristicLab.Common.Resources.VSImageLibrary.Method; }38 }39 38 40 39 public TransformationContent(IPreprocessingData data, FilterLogic filterLogic) { -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Data/FilteredPreprocessingData.cs
r14381 r15110 271 271 272 272 #region IPreprocessingData Members 273 274 273 public bool Validate(string value, out string errorMessage, int columnIndex) { 275 274 return originalData.Validate(value, out errorMessage, columnIndex); -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Data/IPreprocessingData.cs
r14381 r15110 27 27 28 28 namespace HeuristicLab.DataPreprocessing { 29 30 29 public interface IPreprocessingData : INamedItem { 31 30 T GetCell<T>(int columnIndex, int rowIndex); -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Data/ITransactionalPreprocessingData.cs
r14185 r15110 24 24 namespace HeuristicLab.DataPreprocessing { 25 25 public interface ITransactionalPreprocessingData : IPreprocessingData { 26 27 26 event DataPreprocessingChangedEventHandler Changed; 28 27 -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Data/PreprocessingData.cs
r14947 r15110 33 33 [Item("PreprocessingData", "Represents data used for preprocessing.")] 34 34 public abstract class PreprocessingData : NamedItem, IPreprocessingData { 35 36 35 public IntRange TrainingPartition { get; set; } 37 36 public IntRange TestPartition { get; set; } 38 37 39 protected IList<ITransformation> transformations; 40 public IList<ITransformation> Transformations { 41 get { return transformations; } 42 } 38 public IList<ITransformation> Transformations { get; protected set; } 43 39 44 40 protected IList<IList> variableValues; … … 85 81 TrainingPartition = (IntRange)original.TrainingPartition.Clone(cloner); 86 82 TestPartition = (IntRange)original.TestPartition.Clone(cloner); 87 transformations = new List<ITransformation>(original.transformations.Select(cloner.Clone));83 Transformations = new List<ITransformation>(original.Transformations.Select(cloner.Clone)); 88 84 89 85 InputVariables = new List<string>(original.InputVariables); … … 97 93 Name = "Preprocessing Data"; 98 94 99 transformations = new List<ITransformation>();95 Transformations = new List<ITransformation>(); 100 96 selection = new Dictionary<int, IList<int>>(); 101 97 … … 166 162 167 163 #region IPreprocessingData Members 168 169 164 public abstract T GetCell<T>(int columnIndex, int rowIndex); 170 165 -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Data/TransactionalPreprocessingData.cs
r14185 r15110 33 33 [Item("PreprocessingData", "Represents data used for preprocessing.")] 34 34 public class TransactionalPreprocessingData : PreprocessingData, ITransactionalPreprocessingData { 35 36 35 private class Snapshot { 37 36 public IList<IList> VariableValues { get; set; } … … 70 69 TrainingPartition = new IntRange(TrainingPartition.Start, TrainingPartition.End), 71 70 TestPartition = new IntRange(TestPartition.Start, TestPartition.End), 72 Transformations = new List<ITransformation>( transformations),71 Transformations = new List<ITransformation>(Transformations), 73 72 ChangedType = changedType, 74 73 ChangedColumn = column, … … 83 82 84 83 #region NamedItem abstract Member Implementations 85 86 84 public override IDeepCloneable Clone(Cloner cloner) { 87 85 return new TransactionalPreprocessingData(this, cloner); 88 86 } 89 90 87 #endregion 91 88 92 89 #region Overridden IPreprocessingData Members 93 94 90 public override T GetCell<T>(int columnIndex, int rowIndex) { 95 91 return (T)variableValues[columnIndex][rowIndex]; … … 216 212 } 217 213 218 219 214 public override void InsertRow(int rowIndex) { 220 215 SaveSnapshot(DataPreprocessingChangedEventType.DeleteRow, -1, rowIndex); … … 346 341 347 342 #region TransactionalPreprocessingData members 348 349 343 public bool IsUndoAvailable { 350 344 get { return undoHistory.Count > 0; } … … 358 352 TrainingPartition = previousSnapshot.TrainingPartition; 359 353 TestPartition = previousSnapshot.TestPartition; 360 transformations = previousSnapshot.Transformations;354 Transformations = previousSnapshot.Transformations; 361 355 undoHistory.Remove(previousSnapshot); 362 356 OnChanged(previousSnapshot.ChangedType, … … 384 378 OnChanged(@event, -1, -1); 385 379 } 386 387 380 #endregion 388 381 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/HeuristicLab.DataPreprocessing-3.4.csproj
r14886 r15110 18 18 <DebugType>full</DebugType> 19 19 <Optimize>false</Optimize> 20 <OutputPath> ..\..\bin\</OutputPath>20 <OutputPath>$(SolutionDir)\bin\</OutputPath> 21 21 <DefineConstants>DEBUG;TRACE</DefineConstants> 22 22 <ErrorReport>prompt</ErrorReport> … … 28 28 <DebugType>pdbonly</DebugType> 29 29 <Optimize>true</Optimize> 30 <OutputPath> ..\..\bin\</OutputPath>30 <OutputPath>$(SolutionDir)\bin\</OutputPath> 31 31 <DefineConstants>TRACE</DefineConstants> 32 32 <ErrorReport>prompt</ErrorReport> … … 36 36 <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> 37 37 <PlatformTarget>x64</PlatformTarget> 38 <OutputPath> ..\..\bin\</OutputPath>38 <OutputPath>$(SolutionDir)\bin\</OutputPath> 39 39 <DefineConstants>DEBUG;TRACE</DefineConstants> 40 40 <Prefer32Bit>false</Prefer32Bit> … … 42 42 <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> 43 43 <PlatformTarget>x64</PlatformTarget> 44 <OutputPath> ..\..\bin\</OutputPath>44 <OutputPath>$(SolutionDir)\bin\</OutputPath> 45 45 <Optimize>true</Optimize> 46 46 <Prefer32Bit>false</Prefer32Bit> … … 48 48 <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> 49 49 <DebugSymbols>true</DebugSymbols> 50 <OutputPath> ..\..\bin\</OutputPath>50 <OutputPath>$(SolutionDir)\bin\</OutputPath> 51 51 <DefineConstants>DEBUG;TRACE</DefineConstants> 52 52 <DebugType>full</DebugType> … … 57 57 </PropertyGroup> 58 58 <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> 59 <OutputPath> ..\..\bin\</OutputPath>59 <OutputPath>$(SolutionDir)\bin\</OutputPath> 60 60 <DefineConstants>TRACE</DefineConstants> 61 61 <Optimize>true</Optimize> … … 78 78 </ItemGroup> 79 79 <ItemGroup> 80 <Compile Include="Content\MultiScatterPlotContent.cs" /> 81 <Compile Include="Content\SingleScatterPlotContent.cs" /> 80 82 <Compile Include="Content\ScatterPlotContent.cs" /> 81 83 <Compile Include="Content\DataCompletenessChartContent.cs" /> … … 84 86 <Compile Include="Content\PreprocessingChartContent.cs" /> 85 87 <Compile Include="Data\PreprocessingData.cs" /> 86 <Compile Include="Content\PreprocessingDataTable.cs" />87 <Compile Include="Content\IViewChartShortcut.cs" />88 88 <Compile Include="Data\IFilteredPreprocessingData.cs" /> 89 89 <Compile Include="Content\CorrelationMatrixContent.cs" /> … … 118 118 <ItemGroup> 119 119 <ProjectReference Include="..\..\HeuristicLab.Analysis\3.3\HeuristicLab.Analysis-3.3.csproj"> 120 <Project>{887425 b4-4348-49ed-a457-b7d2c26ddbf9}</Project>120 <Project>{887425B4-4348-49ED-A457-B7D2C26DDBF9}</Project> 121 121 <Name>HeuristicLab.Analysis-3.3</Name> 122 122 <Private>False</Private> 123 123 </ProjectReference> 124 124 <ProjectReference Include="..\..\HeuristicLab.Collections\3.3\HeuristicLab.Collections-3.3.csproj"> 125 <Project>{958 b43bc-cc5c-4fa2-8628-2b3b01d890b6}</Project>125 <Project>{958B43BC-CC5C-4FA2-8628-2B3B01D890B6}</Project> 126 126 <Name>HeuristicLab.Collections-3.3</Name> 127 127 <Private>False</Private> 128 128 </ProjectReference> 129 129 <ProjectReference Include="..\..\HeuristicLab.Common.Resources\3.3\HeuristicLab.Common.Resources-3.3.csproj"> 130 <Project>{0 e27a536-1c4a-4624-a65e-dc4f4f23e3e1}</Project>130 <Project>{0E27A536-1C4A-4624-A65E-DC4F4F23E3E1}</Project> 131 131 <Name>HeuristicLab.Common.Resources-3.3</Name> 132 132 <Private>False</Private> 133 133 </ProjectReference> 134 134 <ProjectReference Include="..\..\HeuristicLab.Common\3.3\HeuristicLab.Common-3.3.csproj"> 135 <Project>{ a9ad58b9-3ef9-4cc1-97e5-8d909039ff5c}</Project>135 <Project>{A9AD58B9-3EF9-4CC1-97E5-8D909039FF5C}</Project> 136 136 <Name>HeuristicLab.Common-3.3</Name> 137 137 <Private>False</Private> 138 138 </ProjectReference> 139 139 <ProjectReference Include="..\..\HeuristicLab.Core\3.3\HeuristicLab.Core-3.3.csproj"> 140 <Project>{ c36bd924-a541-4a00-afa8-41701378ddc5}</Project>140 <Project>{C36BD924-A541-4A00-AFA8-41701378DDC5}</Project> 141 141 <Name>HeuristicLab.Core-3.3</Name> 142 142 <Private>False</Private> 143 143 </ProjectReference> 144 144 <ProjectReference Include="..\..\HeuristicLab.Data\3.3\HeuristicLab.Data-3.3.csproj"> 145 <Project>{ bbab9df5-5ef3-4ba8-ade9-b36e82114937}</Project>145 <Project>{BBAB9DF5-5EF3-4BA8-ADE9-B36E82114937}</Project> 146 146 <Name>HeuristicLab.Data-3.3</Name> 147 147 <Private>False</Private> 148 148 </ProjectReference> 149 149 <ProjectReference Include="..\..\HeuristicLab.Optimization\3.3\HeuristicLab.Optimization-3.3.csproj"> 150 <Project>{14 ab8d24-25bc-400c-a846-4627aa945192}</Project>150 <Project>{14AB8D24-25BC-400C-A846-4627AA945192}</Project> 151 151 <Name>HeuristicLab.Optimization-3.3</Name> 152 152 <Private>False</Private> … … 158 158 </ProjectReference> 159 159 <ProjectReference Include="..\..\HeuristicLab.PluginInfrastructure\3.3\HeuristicLab.PluginInfrastructure-3.3.csproj"> 160 <Project>{94186 a6a-5176-4402-ae83-886557b53cca}</Project>160 <Project>{94186A6A-5176-4402-AE83-886557B53CCA}</Project> 161 161 <Name>HeuristicLab.PluginInfrastructure-3.3</Name> 162 162 <Private>False</Private> 163 163 </ProjectReference> 164 164 <ProjectReference Include="..\..\HeuristicLab.Problems.DataAnalysis\3.4\HeuristicLab.Problems.DataAnalysis-3.4.csproj"> 165 <Project>{ df87c13e-a889-46ff-8153-66dcaa8c5674}</Project>165 <Project>{DF87C13E-A889-46FF-8153-66DCAA8C5674}</Project> 166 166 <Name>HeuristicLab.Problems.DataAnalysis-3.4</Name> 167 167 <Private>False</Private> … … 170 170 <Project>{F4539FB6-4708-40C9-BE64-0A1390AEA197}</Project> 171 171 <Name>HeuristicLab.Random-3.3</Name> 172 <Private>False</Private> 173 </ProjectReference> 174 <ProjectReference Include="..\..\HeuristicLab.Visualization.ChartControlsExtensions\3.3\HeuristicLab.Visualization.ChartControlsExtensions-3.3.csproj"> 175 <Project>{315BDA09-3F4F-49B3-9790-B37CFC1C5750}</Project> 176 <Name>HeuristicLab.Visualization.ChartControlsExtensions-3.3</Name> 172 177 <Private>False</Private> 173 178 </ProjectReference> -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Logic/Filter/ComparisonFilter.cs
r14185 r15110 30 30 [Item("ComparisonFilter", "A filter which compares the member of the preprocessing data with the constraint data.")] 31 31 public class ComparisonFilter : ComparisonConstraint, IFilter { 32 33 32 public override string ItemName { 34 33 get { return "ComparisonFilter"; } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Logic/FilterLogic.cs
r14185 r15110 27 27 namespace HeuristicLab.DataPreprocessing { 28 28 public class FilterLogic { 29 30 29 public IFilteredPreprocessingData PreprocessingData { get; private set; } 31 30 32 31 public bool IsFiltered { 33 get { 34 return PreprocessingData.IsFiltered; 35 } 32 get { return PreprocessingData.IsFiltered; } 36 33 } 37 34 -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Logic/ManipulationLogic.cs
r14886 r15110 40 40 } 41 41 42 public ManipulationLogic(ITransactionalPreprocessingData _prepocessingData, SearchLogic theSearchLogic, StatisticsLogic theStatisticsLogic) {43 preprocessingData = _prepocessingData;42 public ManipulationLogic(ITransactionalPreprocessingData preprocessingData, SearchLogic theSearchLogic, StatisticsLogic theStatisticsLogic) { 43 this.preprocessingData = preprocessingData; 44 44 searchLogic = theSearchLogic; 45 45 statisticsLogic = theStatisticsLogic; … … 109 109 preprocessingData.InTransaction(() => { 110 110 foreach (var column in cells) { 111 int countValues = 0;112 if (preprocessingData.VariableHasType<double>(column.Key)) {113 countValues = preprocessingData.GetValues<double>(column.Key).Count();114 } else if (preprocessingData.VariableHasType<DateTime>(column.Key)) {115 countValues = preprocessingData.GetValues<DateTime>(column.Key).Count();116 }117 118 111 IList<Tuple<int, int>> startEndings = GetStartAndEndingsForInterpolation(column); 119 112 foreach (var tuple in startEndings) { … … 291 284 292 285 public List<int> RowsWithMissingValuesGreater(double percent) { 293 294 286 List<int> rows = new List<int>(); 295 287 … … 305 297 306 298 public List<int> ColumnsWithMissingValuesGreater(double percent) { 307 308 299 List<int> columns = new List<int>(); 309 300 for (int i = 0; i < preprocessingData.Columns; ++i) { … … 318 309 319 310 public List<int> ColumnsWithVarianceSmaller(double variance) { 320 321 311 List<int> columns = new List<int>(); 322 312 for (int i = 0; i < preprocessingData.Columns; ++i) { … … 362 352 }); 363 353 } 364 365 354 } 366 355 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Logic/StatisticsLogic.cs
r14185 r15110 27 27 namespace HeuristicLab.DataPreprocessing { 28 28 public class StatisticsLogic { 29 30 29 private readonly ITransactionalPreprocessingData preprocessingData; 31 30 private readonly SearchLogic searchLogic; -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/Plugin.cs.frame
r14886 r15110 34 34 [PluginDependency("HeuristicLab.Collections", "3.3")] 35 35 [PluginDependency("HeuristicLab.Data","3.3")] 36 [PluginDependency("HeuristicLab.Optimization", "3.3")] 36 [PluginDependency("HeuristicLab.Optimization", "3.3")] 37 37 [PluginDependency("HeuristicLab.Persistence", "3.3")] 38 38 [PluginDependency("HeuristicLab.Problems.DataAnalysis","3.4")] 39 39 [PluginDependency("HeuristicLab.Random", "3.3")] 40 [PluginDependency("HeuristicLab.Visualization.ChartControlsExtensions", "3.3")] 40 41 public class HeuristicLabDataPreprocessingPlugin : PluginBase { 41 42 } -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/PreprocessingContext.cs
r14332 r15110 32 32 [StorableClass] 33 33 public class PreprocessingContext : NamedItem, IStorableContent { 34 35 34 public string Filename { get; set; } 36 35 -
trunk/sources/HeuristicLab.DataPreprocessing/3.4/ProblemDataCreator.cs
r14185 r15110 28 28 namespace HeuristicLab.DataPreprocessing { 29 29 public class ProblemDataCreator { 30 31 30 private readonly PreprocessingContext context; 32 31 33 32 private Dataset ExportedDataset { 34 get { 35 return context.Data.ExportToDataset(); 36 } 33 get { return context.Data.ExportToDataset(); } 37 34 } 38 35 39 private IList<ITransformation> Transformations { get { return context.Data.Transformations; } } 36 private IList<ITransformation> Transformations { 37 get { return context.Data.Transformations; } 38 } 40 39 41 40 public ProblemDataCreator(PreprocessingContext context) {
Note: See TracChangeset
for help on using the changeset viewer.