编辑:添加代码
此外,由于DateTimes不是真正的Datetimes(shrings in hh:mm:ss format),我决定只使用Strings并使用TimeSpan来检索totalMinutes。
<ObjectDataProvider x:Key="odpLbGrafiek" ObjectType="{x:Type myClasses:GrafiekBar}" MethodName="GetDataGrafiek"/>
<DataTemplate x:Key="GrafiekItemTemplate">
<Border Width="Auto" Height="Auto">
<Grid>
<Rectangle StrokeThickness="0" Height="30"
Margin="15"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Width="{Binding Value}"
Fill="{Binding Fill}">
<Rectangle.LayoutTransform>
<ScaleTransform ScaleX="20" />
</Rectangle.LayoutTransform>
</Rectangle>
</Grid>
</Border>
</DataTemplate>
“填充”实际上给出了条形图栏上的大小。
itemsControl:
<ItemsControl x:Name="icGrafiek"
Margin="20,3,0,0"
ItemsSource="{Binding Source={StaticResource odpLbGrafiek}}"
ItemTemplate="{DynamicResource GrafiekItemTemplate}"
RenderTransformOrigin="1,0.5" HorizontalAlignment="Left" VerticalAlignment="Top" Grid.RowSpan="6">
<ItemsControl.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1" ScaleX="1"/>
<SkewTransform AngleY="0" AngleX="0"/>
<RotateTransform Angle="180"/>
<TranslateTransform/>
</TransformGroup>
</ItemsControl.RenderTransform>
</ItemsControl>
在数据绑定中调用以下方法。 bar.Value给出了datatemplate中宽度值的值,该值给出了条形的大小。
public ObservableCollection<GrafiekBar> GetDataGrafiek()
{
var converter = new System.Windows.Media.BrushConverter();
Double maxValueStilstanden = GetLargestValueStilstanden();
TimeSpan tsMaxValue = TimeSpan.Parse(maxValueStilstanden.ToString());
totalMinutesMaxValue = tsMaxValue.TotalMinutes;
//calculate % of stilstanden Values
foreach(String t in stilStandenList)
{
TimeSpan ts = TimeSpan.Parse(t);
Double totalMin = ts.TotalMinutes;
totalMin = totalMin / totalMinutesMaxValue * 100;
valuesChartPercentage.Add(totalMin);
}
for (int j = 0; j < valuesChartPercentage.Count; j++)
{
GrafiekBar bar = new GrafiekBar();
bar.Value = valuesChartPercentage[j];
bar.Fill = converter.ConvertFromString(kleuren[j]) as Brush;
listGrafiek.Add(bar);
}
return listGrafiek;
}
另一个问题实际上是宽度(条的大小)。我实际上必须做* 10000来获得酒吧本身的任何视觉效果。
我正在使用样式的 ItemsControl ,因此它看起来像条形图。
因此,例如,具有从1到5的5个值的数组创建具有不同条形尺寸的5个条形,并且每个条形具有不同的颜色。 与以下示例http://www.c-sharpcorner.com/uploadfile/mahesh/bar-chart-in-wpf/
大致相同问题:
我的问题在于条形的缩放大小(在这种情况下为width属性,因此需要int / double值)。
例如,我可以有一个01:22:11的栏或00:01:11的栏,最多可达6个。
将这些DateTime值缩放到某个double值的最佳方法是什么? 该值将用于给出图表上条形的大小。
猜猜我正在寻找某种计算方法来计算我的所有值,所以我不会突然得到一个非常大的值并且超出我的UI。
最干净的解决方案是将所有条形图彼此进行比较,当一个条形图发生变化时,另一个条形图会增大/缩小,但这并不是必需的,尽管它不像听起来那么复杂。
条形码本身并不需要过于精确,它只能用于了解情况的一般情况。确切的值将写入数据库。
欢迎任何建议!
谢谢PeterP。
答案 0 :(得分:1)
归一化。
编辑:选择合适的日期/时间来测量零,或者你可以使用你的DateTime对象的总秒数属性
答案 1 :(得分:1)
我会选择一个基准日期,并使您的收集图表显示基准日期和数据日期之间的天数/小时/分钟
您甚至可以使用转换器执行此操作,您可以将基准日期作为转换器参数传递。
您的两个示例日期(01:22:11
和00:01:11
)实际上是时间,所以在这种情况下,我只是绘制了自0以来的分钟数,因此您的实际数据值将会显示为是82和1
为了回应您关于缩放的编辑问题,您将以百分比形式绘制所有内容。在这种情况下,请根据最大数字的百分比取最大数字并绘制每隔一个数字的图表。
因此,使用您的两个示例时间,我将它们转换为数字82和1,将较大的数字(82)转换为100%,并返回包含每个数字的百分比的列表为82,因此返回列表将包含100%和1.2%(1/82)。
您仍然可以在ViewModel
或ItemsSource
转换器中执行此操作(转换器会将整个列表作为参数,并返回整个返回值列表)
修改强>
在回复下面的评论时,我将使用Converter
上的ItemsSource
进行设置。转换器只需获取一个数据值,并将其转换为另一个特定于显示UI的值。
最初的XAML看起来像这样:
<ItemsControl ItemsSource="{Binding MyCollection,
Converter="{StaticResource MyTimeConverter}}" />
其中MyCollection
是ObservableCollection<DateTime>
,MyTimeConverter
执行以下操作:
value
投放为ObservableCollection<DateTime>
,因为所有转换器参数都以object
传递List<decimal>
List<decimal>
List<decimal>
返回ItemsControl
。此List<decimal>
将用作ItemsSource
,而不是实际的ObservableCollection<DateTime>
这意味着您的ItemsControl
现在绑定到一组小数,其中一个值为100%,将占据屏幕的整个宽度,所有其他值都缩放到最大值。
关于使用计时器更新集合的问题,您的计时器应更新ObservableCollection<DateTime>
绑定的MyCollection
ItemsControl
。定时器根本不应该知道或关心转换器代码。
例如,如果您的计时器想要用一整套新的时间重新创建MyCollection
,那么它可以,并且UI将自动重新运行转换器代码并更新条形图,因为{{ 1}}将在集合发生变化并且UI需要更新时告诉UI。
至于&#34;基准日期&#34;我在下面的评论中指的是,如果你要绘制一组日期而不是时间,你会想要一个基线日期,这样你的图形就不会延伸到ObservableCollections
。您不想使用最小日期,因为这会导致您的条形图中显示为最低值,因此您可以将1/1/0001
特定日期作为起点用于图形。如果基准日期是1/1/12并且您的最大日期是3/1/12,那么您的图表将从1/1/12延伸到3/1/12。
基准日期将用于转换器的步骤3和5。例如,您可以获得基准日期和数据日期之间的天数,而不是获得当时的分钟数。
您还可以计算转换器中的基准日期,例如最低日期之前的10天,但这可能会使图表偏差超出您的喜好,具体取决于数据。
答案 2 :(得分:0)
听起来你只需跟踪所有值的最大值。然后,根据此最大值缩放每个值:
var scale = value / maximum;
var height = scale * ActualHeight;
当然,实际设置每个项目高度的方式可能是通过绑定。
答案 3 :(得分:0)
imho你的整个条形图应该在后面有一个ViewModel,这个VM有逻辑来计算最大值,然后定义缩放。