diff --git a/Library/WinFormControls/ColumnFilterLogic.cs b/Library/WinFormControls/ColumnFilterLogic.cs index f238471b..9a98684b 100644 --- a/Library/WinFormControls/ColumnFilterLogic.cs +++ b/Library/WinFormControls/ColumnFilterLogic.cs @@ -194,14 +194,7 @@ public string FilterExpression return m_FilterExpressionValue.Length > 0 ? m_FilterExpressionValue : m_FilterExpressionOperator; } } - /// - /// Rebuild the ValueClusters based on the data passed in - /// - /// The avalibale values - /// Maximun number of items to show - /// - public BuildValueClustersResult ReBuildValueClusters(in ICollection columnValues, int maxValues) => ValueClusterCollection.ReBuildValueClusters(DataType, columnValues, DataPropertyNameEscaped, Active, maxValues); - + /// /// Gets or sets the operator, setting the operator will build the filter /// diff --git a/Library/WinFormControls/CsvTools.WinFormControlsLibrary.csproj b/Library/WinFormControls/CsvTools.WinFormControlsLibrary.csproj index 08da5f88..85001ca2 100644 --- a/Library/WinFormControls/CsvTools.WinFormControlsLibrary.csproj +++ b/Library/WinFormControls/CsvTools.WinFormControlsLibrary.csproj @@ -53,9 +53,7 @@ Form - - UserControl - + diff --git a/Library/WinFormControls/FromColumnFilter.Designer.cs b/Library/WinFormControls/FromColumnFilter.Designer.cs index 4f73c3d6..f8960fc6 100644 --- a/Library/WinFormControls/FromColumnFilter.Designer.cs +++ b/Library/WinFormControls/FromColumnFilter.Designer.cs @@ -40,9 +40,13 @@ private void InitializeComponent() this.textBoxValue = new System.Windows.Forms.TextBox(); this.listViewCluster = new System.Windows.Forms.ListView(); this.panelTop = new System.Windows.Forms.Panel(); + this.radioButtonEven = new System.Windows.Forms.RadioButton(); + this.radioButtonCombine = new System.Windows.Forms.RadioButton(); + this.radioButtonReg = new System.Windows.Forms.RadioButton(); this.toolTip = new System.Windows.Forms.ToolTip(this.components); this.timerFilter = new System.Windows.Forms.Timer(this.components); this.labelError = new System.Windows.Forms.Label(); + this.timerRebuild = new System.Windows.Forms.Timer(this.components); colText = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); colItems = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader())); ((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit(); @@ -68,7 +72,7 @@ private void InitializeComponent() this.buttonFilter.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.buttonFilter.AutoSize = true; this.buttonFilter.DialogResult = System.Windows.Forms.DialogResult.OK; - this.buttonFilter.Location = new System.Drawing.Point(444, 2); + this.buttonFilter.Location = new System.Drawing.Point(598, 2); this.buttonFilter.Name = "buttonFilter"; this.buttonFilter.Size = new System.Drawing.Size(87, 23); this.buttonFilter.TabIndex = 3; @@ -100,7 +104,7 @@ private void InitializeComponent() // dateTimePickerValue // this.dateTimePickerValue.Format = System.Windows.Forms.DateTimePickerFormat.Short; - this.dateTimePickerValue.Location = new System.Drawing.Point(185, 3); + this.dateTimePickerValue.Location = new System.Drawing.Point(176, 4); this.dateTimePickerValue.Name = "dateTimePickerValue"; this.dateTimePickerValue.Size = new System.Drawing.Size(129, 20); this.dateTimePickerValue.TabIndex = 0; @@ -109,9 +113,9 @@ private void InitializeComponent() // // textBoxValue // - this.textBoxValue.Location = new System.Drawing.Point(185, 3); + this.textBoxValue.Location = new System.Drawing.Point(176, 4); this.textBoxValue.Name = "textBoxValue"; - this.textBoxValue.Size = new System.Drawing.Size(250, 20); + this.textBoxValue.Size = new System.Drawing.Size(211, 20); this.textBoxValue.TabIndex = 1; this.toolTip.SetToolTip(this.textBoxValue, "Text to filter. Please use decimal point for numbers"); this.textBoxValue.Visible = false; @@ -129,7 +133,7 @@ private void InitializeComponent() this.listViewCluster.Location = new System.Drawing.Point(0, 28); this.listViewCluster.Name = "listViewCluster"; this.listViewCluster.ShowGroups = false; - this.listViewCluster.Size = new System.Drawing.Size(535, 369); + this.listViewCluster.Size = new System.Drawing.Size(689, 351); this.listViewCluster.TabIndex = 1; this.toolTip.SetToolTip(this.listViewCluster, "Check allowed values. Count is based on filtered records."); this.listViewCluster.UseCompatibleStateImageBehavior = false; @@ -139,6 +143,9 @@ private void InitializeComponent() // panelTop // this.panelTop.AutoSize = true; + this.panelTop.Controls.Add(this.radioButtonEven); + this.panelTop.Controls.Add(this.radioButtonCombine); + this.panelTop.Controls.Add(this.radioButtonReg); this.panelTop.Controls.Add(this.textBoxValue); this.panelTop.Controls.Add(this.dateTimePickerValue); this.panelTop.Controls.Add(this.buttonFilter); @@ -147,10 +154,48 @@ private void InitializeComponent() this.panelTop.Dock = System.Windows.Forms.DockStyle.Top; this.panelTop.Location = new System.Drawing.Point(0, 0); this.panelTop.Name = "panelTop"; - this.panelTop.Size = new System.Drawing.Size(535, 28); + this.panelTop.Size = new System.Drawing.Size(689, 28); this.panelTop.TabIndex = 0; this.panelTop.Resize += new System.EventHandler(this.PanelTop_Resize); // + // radioButtonEven + // + this.radioButtonEven.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.radioButtonEven.AutoSize = true; + this.radioButtonEven.Location = new System.Drawing.Point(542, 5); + this.radioButtonEven.Name = "radioButtonEven"; + this.radioButtonEven.Size = new System.Drawing.Size(50, 17); + this.radioButtonEven.TabIndex = 4; + this.radioButtonEven.Text = "Even"; + this.radioButtonEven.UseVisualStyleBackColor = true; + this.radioButtonEven.CheckedChanged += new System.EventHandler(this.ClusterTypeChanged); + // + // radioButtonCombine + // + this.radioButtonCombine.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.radioButtonCombine.AutoSize = true; + this.radioButtonCombine.Location = new System.Drawing.Point(470, 5); + this.radioButtonCombine.Name = "radioButtonCombine"; + this.radioButtonCombine.Size = new System.Drawing.Size(66, 17); + this.radioButtonCombine.TabIndex = 4; + this.radioButtonCombine.Text = "Combine"; + this.radioButtonCombine.UseVisualStyleBackColor = true; + this.radioButtonCombine.CheckedChanged += new System.EventHandler(this.ClusterTypeChanged); + // + // radioButtonReg + // + this.radioButtonReg.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.radioButtonReg.AutoSize = true; + this.radioButtonReg.Checked = true; + this.radioButtonReg.Location = new System.Drawing.Point(402, 5); + this.radioButtonReg.Name = "radioButtonReg"; + this.radioButtonReg.Size = new System.Drawing.Size(62, 17); + this.radioButtonReg.TabIndex = 4; + this.radioButtonReg.TabStop = true; + this.radioButtonReg.Text = "Regular"; + this.radioButtonReg.UseVisualStyleBackColor = true; + this.radioButtonReg.CheckedChanged += new System.EventHandler(this.ClusterTypeChanged); + // // timerFilter // this.timerFilter.Enabled = true; @@ -176,19 +221,25 @@ private void InitializeComponent() this.labelError.Text = "Error Information"; this.labelError.Visible = false; // + // timerRebuild + // + this.timerRebuild.Enabled = true; + this.timerRebuild.Interval = 200; + this.timerRebuild.Tick += new System.EventHandler(this.timerRebuild_Tick); + // // FromColumnFilter // this.AcceptButton = this.buttonFilter; this.AutoValidate = System.Windows.Forms.AutoValidate.EnablePreventFocusChange; this.BackColor = System.Drawing.SystemColors.Control; - this.ClientSize = new System.Drawing.Size(535, 397); + this.ClientSize = new System.Drawing.Size(689, 379); this.Controls.Add(this.labelError); this.Controls.Add(this.listViewCluster); this.Controls.Add(this.panelTop); this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.SizableToolWindow; this.MaximizeBox = false; this.MinimizeBox = false; - this.MinimumSize = new System.Drawing.Size(551, 260); + this.MinimumSize = new System.Drawing.Size(705, 260); this.Name = "FromColumnFilter"; this.Text = "Filter"; this.Activated += new System.EventHandler(this.FromDataGridViewFilter_Activated); @@ -214,5 +265,9 @@ private void InitializeComponent() private System.Windows.Forms.ToolTip toolTip; private System.Windows.Forms.Timer timerFilter; private System.Windows.Forms.Label labelError; + private System.Windows.Forms.RadioButton radioButtonEven; + private System.Windows.Forms.RadioButton radioButtonCombine; + private System.Windows.Forms.RadioButton radioButtonReg; + private System.Windows.Forms.Timer timerRebuild; } } \ No newline at end of file diff --git a/Library/WinFormControls/FromColumnFilter.cs b/Library/WinFormControls/FromColumnFilter.cs index 15041f32..2d88295c 100644 --- a/Library/WinFormControls/FromColumnFilter.cs +++ b/Library/WinFormControls/FromColumnFilter.cs @@ -28,7 +28,8 @@ namespace CsvTools public sealed partial class FromColumnFilter : ResizeForm { private readonly ColumnFilterLogic m_DataGridViewColumnFilter; - + private readonly ICollection m_Values; + private readonly int m_MaxCluster; /// /// Initializes a new instance of the class. /// @@ -38,7 +39,8 @@ public sealed partial class FromColumnFilter : ResizeForm public FromColumnFilter(in ColumnFilterLogic dataGridViewColumnFilter, in ICollection columnValues, int maxCluster) { m_DataGridViewColumnFilter = dataGridViewColumnFilter??throw new ArgumentNullException(nameof(dataGridViewColumnFilter)); - + m_Values = columnValues; + m_MaxCluster = maxCluster; InitializeComponent(); Text = $"Filter : {m_DataGridViewColumnFilter.DataPropertyName}"; @@ -48,34 +50,15 @@ public FromColumnFilter(in ColumnFilterLogic dataGridViewColumnFilter, in IColle // ReSharper disable once CoVariantArrayConversion comboBoxOperator.Items.AddRange(ColumnFilterLogic.GetOperators(m_DataGridViewColumnFilter.DataType)); comboBoxOperator.SelectedIndex = 0; - comboBoxOperator.EndUpdate(); + comboBoxOperator.EndUpdate(); - var result = m_DataGridViewColumnFilter.ReBuildValueClusters(columnValues, maxCluster); - if (result == BuildValueClustersResult.ListFilled) - { - FilterItems(""); - } - else + timerRebuild.Start(); + + if (m_DataGridViewColumnFilter.DataType == DataTypeEnum.String || m_DataGridViewColumnFilter.DataType == DataTypeEnum.Guid || m_DataGridViewColumnFilter.DataType == DataTypeEnum.Boolean) { - listViewCluster.CheckBoxes = false; - var explain = "Error collecting the values"; - switch (result) - { - case BuildValueClustersResult.WrongType: - explain="Datatype did not match"; - break; - case BuildValueClustersResult.TooManyValues: - explain="Too many different values"; - break; - case BuildValueClustersResult.NoValues: - explain="No value found"; - break; - } - toolTip.SetToolTip(this.listViewCluster, explain); - labelError.Text = explain; - labelError.Visible=true; - toolTip.SetToolTip(this.labelError, explain); - listViewCluster.Enabled = false; + radioButtonCombine.Enabled = false; + radioButtonEven.Enabled = false; + radioButtonReg.Enabled = false; } } @@ -254,6 +237,44 @@ private void TimerFilter_Tick(object sender, EventArgs e) { ParentForm.ShowError(ex); } - } + } + + private void timerRebuild_Tick(object sender, EventArgs e) + { + timerRebuild.Stop(); + var result = m_DataGridViewColumnFilter.ValueClusterCollection.ReBuildValueClusters(m_DataGridViewColumnFilter.DataType, m_Values, m_DataGridViewColumnFilter.DataPropertyNameEscaped, m_DataGridViewColumnFilter.Active, m_MaxCluster, radioButtonCombine.Checked, radioButtonEven.Checked); + if (result == BuildValueClustersResult.ListFilled) + { + FilterItems(""); + } + else + { + listViewCluster.CheckBoxes = false; + var explain = "Error collecting the values"; + switch (result) + { + case BuildValueClustersResult.WrongType: + explain="Datatype did not match"; + break; + case BuildValueClustersResult.TooManyValues: + explain="Too many different values"; + break; + case BuildValueClustersResult.NoValues: + explain="No value found"; + break; + } + toolTip.SetToolTip(this.listViewCluster, explain); + labelError.Text = explain; + labelError.Visible=true; + toolTip.SetToolTip(this.labelError, explain); + listViewCluster.Enabled = false; + } + } + + private void ClusterTypeChanged(object sender, EventArgs e) + { + timerRebuild.Stop(); + timerRebuild.Start(); + } } } \ No newline at end of file diff --git a/Library/WinFormControls/FromColumnFilter.resx b/Library/WinFormControls/FromColumnFilter.resx index 9bbb8780..0881b76a 100644 --- a/Library/WinFormControls/FromColumnFilter.resx +++ b/Library/WinFormControls/FromColumnFilter.resx @@ -129,7 +129,13 @@ 140, 17 + + 140, 17 + 231, 17 + + 328, 19 + \ No newline at end of file diff --git a/Library/WinFormControls/ValueClusterCollection.cs b/Library/WinFormControls/ValueClusterCollection.cs index b95d9f0f..d707d328 100644 --- a/Library/WinFormControls/ValueClusterCollection.cs +++ b/Library/WinFormControls/ValueClusterCollection.cs @@ -31,9 +31,9 @@ public sealed class ValueClusterCollection : ICollection public int Count => m_ValueClusters.Count; public bool IsReadOnly => m_ValueClusters.IsReadOnly; - private ValueCluster lastValueCluster = new ValueCluster("Dummy", string.Empty, int.MaxValue, null); + private ValueCluster m_Last = new ValueCluster("Dummy", string.Empty, int.MaxValue, null); - public BuildValueClustersResult ReBuildValueClusters(DataTypeEnum type, in ICollection values, in string escapedName, bool isActive, int maxNumber) + public BuildValueClustersResult ReBuildValueClusters(DataTypeEnum type, in ICollection values, in string escapedName, bool isActive, int maxNumber = 40, bool combine = true, bool even = false) { if (values is null) throw new ArgumentNullException(nameof(values)); @@ -88,7 +88,10 @@ public BuildValueClustersResult ReBuildValueClusters(DataTypeEnum type, in IColl } AddValueClusterNull(escapedName, m_CountNull); - return BuildValueClustersDate(typedValues, escapedName, maxNumber); + if (even) + return BuildValueClustersDateEven(typedValues, escapedName, maxNumber); + else + return BuildValueClustersDate(typedValues, escapedName, maxNumber, combine); } else if (type == DataTypeEnum.Integer || type == DataTypeEnum.Numeric || type == DataTypeEnum.Double) { @@ -111,7 +114,10 @@ public BuildValueClustersResult ReBuildValueClusters(DataTypeEnum type, in IColl } } AddValueClusterNull(escapedName, m_CountNull); - return BuildValueClustersNumeric(typedValues, escapedName, maxNumber, type != DataTypeEnum.Integer); + if (even) + return BuildValueClustersNumericEven(typedValues, escapedName, maxNumber); + else + return BuildValueClustersNumeric(typedValues, escapedName, maxNumber, type != DataTypeEnum.Integer, combine); } else return BuildValueClustersResult.WrongType; @@ -130,11 +136,88 @@ public BuildValueClustersResult ReBuildValueClusters(DataTypeEnum type, in IColl public IEnumerable GetActiveValueCluster() => m_ValueClusters.Where(value => !string.IsNullOrEmpty(value.Display) && value.Active); + private BuildValueClustersResult BuildValueClustersDateEven(in ICollection values, in string escapedName, int max) + { + var distinctValues = values.Distinct().OrderBy(x => x).ToList(); + var bucket = new List<(DateTime date, int count)>(); + var bucketCount = 0; + var bucketSize = values.Count/ max; + foreach (var value in distinctValues) + { + var count = values.Count(x => x== value); + bucket.Add((value, count)); + bucketCount += count; + // progress to next bucket + if (bucketCount > bucketSize) + { + + var from = bucket.First().date; + var to = bucket.Last().date; + var display = $"{from:d} – {to:d}"; + if (from.Date == to.Date) + display = $"{from:d} {from:t} – {to:t}"; + var existing = false; + try + { + existing = m_ValueClusters.Any(x => x.Start is DateTime start && start <= from + && x.Start is DateTime end && end >= to); + } + catch + { + } + if (!existing) + m_ValueClusters.Add(new ValueCluster(display, $"({escapedName} >= #{from.ToString("MM/dd/yyyy HH:mm", CultureInfo.InvariantCulture)}# AND {escapedName} < #{to.ToString("MM/dd/yyyy HH:mm", CultureInfo.InvariantCulture)}#)", + bucketCount, from, to)); + + bucketCount=0; + } + } + return BuildValueClustersResult.ListFilled; + } + private BuildValueClustersResult BuildValueClustersNumericEven(in ICollection values, in string escapedName, int max) + { + var distinctValues = values.Select(x => Math.Floor(x * 10d) / 10d).Distinct().OrderBy(x => x).ToList(); + var bucket = new List<(double val, int count)>(); + var bucketCount = 0; + var bucketSize = values.Count/ max; + foreach (var value in distinctValues) + { + var count = values.Count(x => x>= value && x< value+.1); + bucket.Add((value, count)); + bucketCount += count; + // progress to next bucket + if (bucketCount > bucketSize) + { + + var minValue = bucket.First().val; + var maxValue = bucket.Last().val; + var display = $"{minValue:F1} – {maxValue:F1}"; + var existing = false; + try + { + existing = m_ValueClusters.Any(x => (long) (x.Start ?? long.MinValue) <= minValue && (long) (x.End ?? long.MaxValue) >= maxValue); + } + catch + { + } + if (!existing) + { + if (count>0) + Add(new ValueCluster($"{minValue:F1} - {maxValue:F1}", // Fixed Point + string.Format(CultureInfo.InvariantCulture, "({0} >= {1:F1} AND {0} < {2:F1})", escapedName, minValue, maxValue), + bucketCount, minValue, maxValue)); + } + bucketCount=0; + } + } + return BuildValueClustersResult.ListFilled; + } + /// /// Builds the value clusters date. /// /// - private BuildValueClustersResult BuildValueClustersDate(in ICollection values, in string escapedName, int max) + private BuildValueClustersResult BuildValueClustersDate(in ICollection values, in string escapedName, int max, bool combine) { // Get the distinct values and their counts var clusterYear = new HashSet(); @@ -160,9 +243,13 @@ private BuildValueClustersResult BuildValueClustersDate(in ICollection if (clusterYear.Count == 0) return BuildValueClustersResult.NoValues; - var desiredSize = (values.Count * 3) / (max *2); - if (desiredSize < 5) - desiredSize=5; + var desiredSize = 1; + if (combine) + { + desiredSize = (values.Count * 3) / (max *2); + if (desiredSize < 5) + desiredSize=5; + } if (clusterDay.Count == 1) { clusterHour.Add(clusterHour.Min() -1); @@ -197,7 +284,7 @@ private BuildValueClustersResult BuildValueClustersDate(in ICollection private enum DateTimeRange { Hours, Days, Month, Years } - private void AddValueClusterDateTime(in string escapedName, DateTime from, DateTime to, ICollection values, DateTimeRange displayType, int desiredSize) + private void AddValueClusterDateTime(in string escapedName, DateTime from, DateTime to, ICollection values, DateTimeRange displayType, int desiredSize = int.MaxValue) { // Do not add if there is a cluster existing that spans the new value [ [ ] ] // Do not add if there is a cluster existing that spans the new value [ ] ] @@ -219,13 +306,13 @@ private void AddValueClusterDateTime(in string escapedName, DateTime from, DateT if (count >0) { // Combine buckets if the last and the current do not have many values - if (lastValueCluster.Count + count < desiredSize && lastValueCluster.Start is DateTime lastFrom) + if (m_Last.Count + count < desiredSize && m_Last.Start is DateTime lastFrom) { from = lastFrom; - count += lastValueCluster.Count; + count += m_Last.Count; // remove the last cluster it will be included with this new one - m_ValueClusters.Remove(lastValueCluster); + m_ValueClusters.Remove(m_Last); } string display = string.Empty; switch (displayType) @@ -252,9 +339,9 @@ private void AddValueClusterDateTime(in string escapedName, DateTime from, DateT display=$"{from:yyyy} – {to:yyyy}"; break; } - lastValueCluster = new ValueCluster(display, $"({escapedName} >= #{from.ToString("MM/dd/yyyy HH:mm", CultureInfo.InvariantCulture)}# AND {escapedName} < #{to.ToString("MM/dd/yyyy HH:mm", CultureInfo.InvariantCulture)}#)", + m_Last = new ValueCluster(display, $"({escapedName} >= #{from.ToString("MM/dd/yyyy HH:mm", CultureInfo.InvariantCulture)}# AND {escapedName} < #{to.ToString("MM/dd/yyyy HH:mm", CultureInfo.InvariantCulture)}#)", count, from, to); - m_ValueClusters.Add(lastValueCluster); + m_ValueClusters.Add(m_Last); } } } @@ -263,7 +350,7 @@ private void AddValueClusterDateTime(in string escapedName, DateTime from, DateT /// Builds the value clusters date. /// /// - private BuildValueClustersResult BuildValueClustersNumeric(in ICollection values, in string escapedName, int max, in bool decimals) + private BuildValueClustersResult BuildValueClustersNumeric(in ICollection values, in string escapedName, int max, bool decimals, bool combine) { // Get the distinct values and their counts var clusterFractions = new HashSet(); @@ -343,9 +430,14 @@ private BuildValueClustersResult BuildValueClustersNumeric(in ICollection x)+1); fittingCluster.Add(fittingCluster.Min(x => x)-1); - var desiredSize = (values.Count * 3) / (max *2); - if (desiredSize < 5) - desiredSize=5; + var desiredSize = 1; + if (combine) + { + desiredSize = (values.Count * 3) / (max *2); + if (desiredSize < 5) + desiredSize=5; + } + foreach (var dic in fittingCluster.OrderBy(x => x)) { var minValue = (long) (dic * factor); @@ -368,15 +460,15 @@ private BuildValueClustersResult BuildValueClustersNumeric(in ICollection0) { // Combine buckets if teh last and the current do not have many values - if (lastValueCluster.Count + count < desiredSize && lastValueCluster.Start is long lastMin) + if (m_Last.Count + count < desiredSize && m_Last.Start is long lastMin) { minValue = lastMin; - count += lastValueCluster.Count; + count += m_Last.Count; // remove the last cluster it will be included with thie one - m_ValueClusters.Remove(lastValueCluster); + m_ValueClusters.Remove(m_Last); } - lastValueCluster = new ValueCluster($"[{minValue:N0},{maxValue:N0})", string.Format(CultureInfo.InvariantCulture, "({0} >= {1} AND {0} < {2})", escapedName, minValue, maxValue), count, minValue, maxValue); - m_ValueClusters.Add(lastValueCluster); + m_Last = new ValueCluster($"[{minValue:N0},{maxValue:N0})", string.Format(CultureInfo.InvariantCulture, "({0} >= {1} AND {0} < {2})", escapedName, minValue, maxValue), count, minValue, maxValue); + m_ValueClusters.Add(m_Last); } } @@ -439,8 +531,8 @@ private BuildValueClustersResult BuildValueClustersString(in IEnumerable { if (!m_ValueClusters.Any(x => string.Equals(x.Start?.ToString() ?? string.Empty, text))) { - lastValueCluster = new ValueCluster(text, $"({escapedName} = '{text.SqlQuote()}')", values.Count(dataRow => string.Equals(dataRow, text, StringComparison.OrdinalIgnoreCase)), text); - m_ValueClusters.Add(lastValueCluster); + m_Last = new ValueCluster(text, $"({escapedName} = '{text.SqlQuote()}')", values.Count(dataRow => string.Equals(dataRow, text, StringComparison.OrdinalIgnoreCase)), text); + m_ValueClusters.Add(m_Last); } } } @@ -458,8 +550,8 @@ private BuildValueClustersResult BuildValueClustersString(in IEnumerable { if (!m_ValueClusters.Any(x => string.Equals(x.Start?.ToString() ?? string.Empty, text))) { - lastValueCluster = new ValueCluster($"{text}…", $"({escapedName} LIKE '{text.SqlQuote()}%')", values.Count(x => x.StartsWith(text, StringComparison.OrdinalIgnoreCase)), text); - m_ValueClusters.Add(lastValueCluster); + m_Last = new ValueCluster($"{text}…", $"({escapedName} LIKE '{text.SqlQuote()}%')", values.Count(x => x.StartsWith(text, StringComparison.OrdinalIgnoreCase)), text); + m_ValueClusters.Add(m_Last); } } } @@ -470,8 +562,8 @@ private void AddValueClusterNull(in string escapedName, int count) { if (!m_ValueClusters.Any(x => x.Start is null) && count>0) { - lastValueCluster = new ValueCluster(ColumnFilterLogic.OperatorIsNull, string.Format($"({escapedName} IS NULL)"), count, null); - m_ValueClusters.Add(lastValueCluster); + m_Last = new ValueCluster(ColumnFilterLogic.OperatorIsNull, string.Format($"({escapedName} IS NULL)"), count, null); + m_ValueClusters.Add(m_Last); } } diff --git a/UnitTest/WinFormControlsUnitTest/ColumnFilterLogicTests.cs b/UnitTest/WinFormControlsUnitTest/ColumnFilterLogicTests.cs index 401042f6..c867ab4d 100644 --- a/UnitTest/WinFormControlsUnitTest/ColumnFilterLogicTests.cs +++ b/UnitTest/WinFormControlsUnitTest/ColumnFilterLogicTests.cs @@ -41,8 +41,8 @@ public void ColumnFilterLogicCtor() [TestMethod] public void ApplyFilterTest() { - var columnFilterLogic = new ColumnFilterLogic(typeof(double), "Column1"); - columnFilterLogic.ApplyFilter(); + var columnFilterLogic = new ColumnFilterLogic(typeof(double), "Column1"); + columnFilterLogic.ApplyFilter(); } [TestMethod] @@ -178,7 +178,7 @@ public void AllFilterString() foreach (var op in ColumnFilterLogic.GetOperators(columnFilterLogic.DataType)) { - columnFilterLogic.Operator = op.ToString(); + columnFilterLogic.Operator = op.ToString(); // columnFilterLogic.Active = true; Assert.IsNotNull(columnFilterLogic.FilterExpression); } @@ -187,7 +187,7 @@ public void AllFilterString() [TestMethod] public void ChangeFilterString() { - var columnFilterLogic = new ColumnFilterLogic(typeof(string), "strCol") { Operator = "…xxx…", ValueText = "Hello" }; + var columnFilterLogic = new ColumnFilterLogic(typeof(string), "strCol") { Operator = "…xxx…", ValueText = "Hello" }; TestFilterExpression("[strCol] like '%Hello%'", columnFilterLogic); columnFilterLogic.ValueText="Test"; @@ -218,7 +218,7 @@ public void ValueClusterCollection() using var data = UnitTestStaticData.GetDataTable(200); using var dataView = new DataView(data, null, null, DataViewRowState.CurrentRows); - columnFilterLogic.ReBuildValueClusters(data.Rows.OfType().Select(x => x[1]).ToArray(), 20); + columnFilterLogic.ValueClusterCollection.ReBuildValueClusters(DataTypeEnum.Integer, data.Rows.OfType().Select(x => x[1]).ToArray(), "d", true, 20); var i = 0; foreach (var cluster in columnFilterLogic.ValueClusterCollection) { diff --git a/UnitTest/WinFormControlsUnitTest/ValueClusterCollectionTests.cs b/UnitTest/WinFormControlsUnitTest/ValueClusterCollectionTests.cs index b77bd6d3..843bfff5 100644 --- a/UnitTest/WinFormControlsUnitTest/ValueClusterCollectionTests.cs +++ b/UnitTest/WinFormControlsUnitTest/ValueClusterCollectionTests.cs @@ -51,8 +51,8 @@ public static void ClassCleanup() public void BuildValueClusters_StringListFilled() { var fl = GetFilterLogic(0); - Assert.AreEqual(BuildValueClustersResult.ListFilled, fl.ReBuildValueClusters(GetColumnData(0), 200)); - Assert.AreEqual(BuildValueClustersResult.ListFilled, fl.ReBuildValueClusters(GetColumnData(7), 200)); + Assert.AreEqual(BuildValueClustersResult.ListFilled, fl.ValueClusterCollection.ReBuildValueClusters(DataTypeEnum.String, GetColumnData(0), "d1", false, 200)); + Assert.AreEqual(BuildValueClustersResult.ListFilled, fl.ValueClusterCollection.ReBuildValueClusters(DataTypeEnum.String, GetColumnData(7), "d2", true, 200)); Assert.IsNotNull(fl.ValueClusterCollection); } @@ -99,7 +99,7 @@ public void BuildValueClusters_LongRangeStep1() test.ReBuildValueClusters(DataTypeEnum.Numeric, number, "dummy", true, 40); Assert.AreEqual(number.Count, test.Count); - Assert.AreEqual(number.Count, test.Select(x=> x.Count).Sum()); + Assert.AreEqual(number.Count, test.Select(x => x.Count).Sum()); Assert.AreEqual("-3", test.First().Display); Assert.AreEqual("2", test.Last().Display); } @@ -113,8 +113,8 @@ public void BuildValueClusters_LongRangeStep10() for (long i = -199; i < 200; i++) number.Add(i); - test.ReBuildValueClusters(DataTypeEnum.Integer, number, "dummy", true, 200); - Assert.AreEqual(number.Count, test.Select(x=> x.Count).Sum()); + test.ReBuildValueClusters(DataTypeEnum.Integer, number, "dummy", true, 200); + Assert.AreEqual(number.Count, test.Select(x => x.Count).Sum()); Assert.IsTrue(test.First().Display.Contains("-199")); Assert.IsTrue(test.Last().Display.Contains("200"), test.Last().Display); } @@ -134,13 +134,13 @@ public void BuildValueClusters_LongRangeStep100() for (long i = 10; i < 2000; i++) number2.Add(i); test.ReBuildValueClusters(DataTypeEnum.Integer, number2, "dummy", true, 50); - Assert.AreEqual(number2.Count, test.Select(x=> x.Count).Sum()); + Assert.AreEqual(number2.Count, test.Select(x => x.Count).Sum()); var number3 = new List(); for (long i = -500; i < -50; i++) number3.Add(i); test.ReBuildValueClusters(DataTypeEnum.Integer, number3, "dummy", true, 50); - Assert.AreEqual(number3.Count, test.Select(x=> x.Count).Sum()); + Assert.AreEqual(number3.Count, test.Select(x => x.Count).Sum()); } @@ -149,16 +149,16 @@ public void BuildValueClusters_LongRangeStep100() public void BuildValueClusters_DateTime() { var test = new ValueClusterCollection(); - + var data = GetColumnData(2); - + test.ReBuildValueClusters(DataTypeEnum.DateTime, data, "dummy", true, 150); - Assert.AreEqual(data.Count, test.Select(x=> x.Count).Sum()); + Assert.AreEqual(data.Count, test.Select(x => x.Count).Sum()); var res = test.ReBuildValueClusters(DataTypeEnum.DateTime, data, "dummy", true, 50); - Assert.AreEqual(BuildValueClustersResult.ListFilled, res ); - Assert.AreEqual(data.Count, test.Select(x=> x.Count).Sum()); + Assert.AreEqual(BuildValueClustersResult.ListFilled, res); + Assert.AreEqual(data.Count, test.Select(x => x.Count).Sum()); }