.NET 6 WinForms使用winforms-datavisualization绘制排序字母频率直方图时列未按预期排序的问题
.NET 6 WinForms使用winforms-datavisualization绘制排序字母频率直方图时列未按预期排序的问题
我最近在做一个.NET 6的WinForms项目,功能是分析文本文件里每个字母的出现频率,然后生成直方图展示结果。因为.NET 6的WinForms原生没有图表控件,我用的是winforms-datavisualization这个库。
本来我已经把统计好的字母频率放进了排序字典里,想着这样数据就是有序的了,结果绘制出来的直方图柱子却完全没按预期的顺序排列,可把我愁坏了。
我用的代码是这样的:
chart1.Series.Add(series); var keys = sortedFrequencies.Keys.ToList(); var values = sortedFrequencies.Values.ToList(); for (int i = 0; i < keys.Count; i++) { int pointIndex = series.Points.AddXY(keys[i], values[i]); series.Points[pointIndex].AxisLabel = keys[i].ToString(); textBox1.Text += keys[i].ToString(); textBox2.Text += values[i].ToString(); } chart1.ChartAreas[0].AxisX.Interval = 1; chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45; chart1.ChartAreas[0].AxisX.LabelStyle.IsStaggered = true; chart1.Invalidate();
我特意把排序字典的键和值转成列表循环添加,而且文本框里显示的键和值都是严格排序好的,但图表的柱子就是乱序的,所有列都显示出来了,可顺序完全不对。
后来我查了下原因,发现问题出在WinForms图表控件的默认行为上:它会把X轴的字符串自动识别为类别型数据,然后自己按字母顺序或者插入顺序重新排列,根本不管我们添加数据时的顺序。
找到了原因就好办了,这里有两个可行的解决办法:
办法一:把X轴转为数值型,用ASCII码映射字母
我们可以把字母转成对应的ASCII数值作为X轴的实际值,然后把标签显示为字母,这样控件会按数值排序,自然就和我们排序字典的顺序一致了。修改代码如下:
// 在添加数据点前先设置系列和X轴的数值类型 series.XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double; chart1.ChartAreas[0].AxisX.ValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Double; chart1.Series.Add(series); var keys = sortedFrequencies.Keys.ToList(); var values = sortedFrequencies.Values.ToList(); for (int i = 0; i < keys.Count; i++) { // 把字母转成ASCII码作为X值 int pointIndex = series.Points.AddXY((int)keys[i], values[i]); series.Points[pointIndex].AxisLabel = keys[i].ToString(); // 标签还是显示字母 textBox1.Text += keys[i].ToString(); textBox2.Text += values[i].ToString(); } // 剩下的X轴样式设置不变 chart1.ChartAreas[0].AxisX.Interval = 1; chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45; chart1.ChartAreas[0].AxisX.LabelStyle.IsStaggered = true; chart1.Invalidate();
办法二:禁用X轴自动排序,强制保持添加顺序
另一种更直接的方式是告诉控件不要自动排序X轴,严格按照我们添加数据点的顺序来显示。只需要在添加数据前加上两行设置:
// 禁用X轴自动排序,强制保持数据点的添加顺序 chart1.ChartAreas[0].AxisX.Sorting = System.Windows.Forms.DataVisualization.Charting.AxisSorting.None; series.IsXValueIndexed = true; chart1.Series.Add(series); // 后面的代码保持不变 var keys = sortedFrequencies.Keys.ToList(); var values = sortedFrequencies.Values.ToList(); for (int i = 0; i < keys.Count; i++) { int pointIndex = series.Points.AddXY(keys[i], values[i]); series.Points[pointIndex].AxisLabel = keys[i].ToString(); textBox1.Text += keys[i].ToString(); textBox2.Text += values[i].ToString(); } chart1.ChartAreas[0].AxisX.Interval = 1; chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45; chart1.ChartAreas[0].AxisX.LabelStyle.IsStaggered = true; chart1.Invalidate();
我试了这两种方法,都能让直方图的柱子严格按照排序字典的顺序显示,完美解决了问题!
备注:内容来源于stack exchange,提问作者IDNKEK
相关产品推荐
相关产品推荐

