Wpf 绘制列之间没有空格的列图
我正在使用WPF工具包,并试图呈现一个类似直方图的图形。特别是,我希望每一列都与另一列相对。列之间应该没有间隙 创建柱状图时,可以应用许多组件。(参见下面的示例XAML)。有人知道你是否可以在其中一个元素上设置一个属性,它指的是列之间空白的宽度吗Wpf 绘制列之间没有空格的列图,wpf,graph,wpftoolkit,charts,silverlight-toolkit,Wpf,Graph,Wpftoolkit,Charts,Silverlight Toolkit,我正在使用WPF工具包,并试图呈现一个类似直方图的图形。特别是,我希望每一列都与另一列相对。列之间应该没有间隙 创建柱状图时,可以应用许多组件。(参见下面的示例XAML)。有人知道你是否可以在其中一个元素上设置一个属性,它指的是列之间空白的宽度吗 <charting:Chart Height="600" Width="Auto" HorizontalAlignment="Stretch" Name="MyChart"
<charting:Chart Height="600" Width="Auto" HorizontalAlignment="Stretch" Name="MyChart"
Title="Column Graph" LegendTitle="Legend">
<charting:ColumnSeries
Name="theColumnSeries"
Title="Series A"
IndependentValueBinding="{Binding Path=Name}"
DependentValueBinding="{Binding Path=Population}"
Margin="0"
>
</charting:ColumnSeries>
<charting:Chart.Axes>
<charting:LinearAxis
Orientation="Y"
Minimum="200000"
Maximum="2500000"
ShowGridLines="True" />
<charting:CategoryAxis
Name="chartCategoryAxis"
/>
</charting:Chart.Axes>
</charting:Chart>
在没有神奇答案的情况下,我从codeplex下载了wpftoolkit代码
通过阅读代码,我可以在ColumnSeries.UpdateDapPoint方法中看到以下代码行:
double segmentWidth = coordinateRangeWidth * 0.8;
这是一个非常明确的“否”,您不能通过设置公共属性来更改列之间的间距
我要尝试的解决方案是编写一个从ColumnSeries继承的新类,并重写UpdateDapPoint
以后编辑
好的,我开始工作了。如果有人感兴趣,我已经附上Historogramseries类的完整代码
public class HistogramSeries : ColumnSeries, ISeries
{
protected override void UpdateDataPoint(DataPoint dataPoint)
{
// That set the height and width.
base.UpdateDataPoint(dataPoint);
// Now we override the part about setting the width
object category = dataPoint.ActualIndependentValue;
var coordinateRange = GetCategoryRange(category);
double minimum = (double)coordinateRange.Minimum.Value;
double maximum = (double)coordinateRange.Maximum.Value;
double coordinateRangeWidth = (maximum - minimum);
const int WIDTH_MULTIPLIER = 1; // Harcoded to 0.8 in the parent. Could make this a dependency property
double segmentWidth = coordinateRangeWidth * WIDTH_MULTIPLIER;
var columnSeries = SeriesHost.Series.OfType<ColumnSeries>().Where(series => series.ActualIndependentAxis == ActualIndependentAxis);
int numberOfSeries = columnSeries.Count();
double columnWidth = segmentWidth / numberOfSeries;
int seriesIndex = columnSeries.IndexOf(this);
double offset = seriesIndex * Math.Round(columnWidth) + coordinateRangeWidth * 0.1;
double dataPointX = minimum + offset;
double left = Math.Round(dataPointX);
double width = Math.Round(columnWidth);
Canvas.SetLeft(dataPoint, left);
dataPoint.Width = width;
}
#region ISeries Members
System.Collections.ObjectModel.ObservableCollection<object> ISeries.LegendItems
{
get { return base.LegendItems; }
}
#endregion
#region IRequireSeriesHost Members
ISeriesHost IRequireSeriesHost.SeriesHost
{
get { return base.SeriesHost;}
set { base.SeriesHost = value; }
}
#endregion
}
// Copied from the DataVisualization library
// (It was an internal class)
static class MyEnumerableFunctions
{
public static int IndexOf(this IEnumerable that, object value)
{
int index = 0;
foreach (object item in that)
{
if (object.ReferenceEquals(value, item) || value.Equals(item))
{
return index;
}
index++;
}
return -1;
}
}
公共类历史记录系列:列系列、ISeries
{
受保护的覆盖无效更新数据点(数据点数据点)
{
//设置了高度和宽度。
base.UpdateDataPoint(数据点);
//现在我们覆盖关于设置宽度的部分
对象类别=dataPoint.RealizationIndependentValue;
var坐标=GetCategoryRange(类别);
双最小值=(双)坐标.minimum.Value;
双最大值=(双)坐标.max.Value;
双坐标宽度=(最大值-最小值);
const int WIDTH_MULTIPLIER=1;//在父级中已编码为0.8。可能使其成为依赖项属性
双段宽度=坐标宽度*宽度乘子;
var columnSeries=seriehost.Series.OfType()。其中(Series=>Series.ActualIndependentAxis==ActualIndependentAxis);
int numberOfSeries=columnSeries.Count();
双列宽=分段宽度/编号系列;
int seriesIndex=columnSeries.IndexOf(this);
双偏移=系列索引*数学圆(列宽)+坐标宽度*0.1;
双数据点x=最小值+偏移量;
左双=数学圆(dataPointX);
双宽度=数学圆(列宽);
Canvas.SetLeft(数据点,左侧);
数据点宽度=宽度;
}
#区域ISeries成员
System.Collections.ObjectModel.ObservableCollection ISeries.LegendItems
{
获取{return base.LegendItems;}
}
#端区
#地区I需要最优秀的会员
ISeriesHost iRequestriesHost.SeriesHost
{
获取{return base.seriehost;}
设置{base.seriehost=value;}
}
#端区
}
//从DataVisualization库复制
//(这是一个内部类)
静态类MyEnumerableFunctions
{
公共静态int IndexOf(this IEnumerable that,object value)
{
int指数=0;
foreach(其中的对象项)
{
if(object.ReferenceEquals(value,item)| | value.Equals(item))
{
收益指数;
}
索引++;
}
返回-1;
}
}
代码示例的Thx。这几乎正是我所需要的。我把它翻译成VB.Net并删除了次要部分
Imports System.Windows.Controls.DataVisualization.Charting
Public Class HistogramSeries
Inherits ColumnSeries
Protected Overrides Sub UpdateDataPoint(dataPoint As DataPoint)
MyBase.UpdateDataPoint(dataPoint)
' Now we override the part about setting the width
Dim category As Object = dataPoint.ActualIndependentValue
Dim coordinateRange = GetCategoryRange(category)
Dim minimum As Double = CDbl(coordinateRange.Minimum.Value)
Dim maximum As Double = CDbl(coordinateRange.Maximum.Value)
Dim coordinateRangeWidth As Double = (maximum - minimum)
Const WIDTH_MULTIPLIER As Integer = 1 ' Harcoded to 0.8 in the parent. Could make this a dependency property
Dim segmentWidth As Double = coordinateRangeWidth * WIDTH_MULTIPLIER
Dim columnS As System.Collections.Generic.IEnumerable(Of ColumnSeries) = SeriesHost.Series.OfType(Of ColumnSeries)().Where(Function(series) series.ActualIndependentAxis Is ActualIndependentAxis)
Dim numberOfSeries As Integer = columnS.Count
Dim columnWidth As Double = segmentWidth / numberOfSeries
Dim seriesIndex As Integer = columnS.ToList.IndexOf(Me)
Dim offset As Double = seriesIndex * Math.Round(columnWidth) + coordinateRangeWidth * 0.1
Dim dataPointX As Double = minimum + offset
Dim left As Double = Math.Round(dataPointX)
Dim width As Double = Math.Round(columnWidth)
Canvas.SetLeft(dataPoint, left)
dataPoint.Width = width
End Sub
End Class
请让我知道你的进展,我很想看看你是否能解决这个问题!