项目控制条形图 条形的缩放
本文关键字:缩放 控制 条形图 项目 | 更新日期: 2023-09-27 18:31:35
编辑:添加的代码
另外,由于日期时间不是真正的日期时间(hh:mm:ss格式的sTrings),我决定只使用字符串,并使用TimeSpan来检索总分钟数。
<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 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>
在数据绑定中调用以下方法。那里是酒吧。值提供数据模板中 Width 值的值,该值提供条形的大小。
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才能获得酒吧本身的任何视觉效果。
我正在使用样式化的 ItemsControls,因此它看起来像条形图。
例如,一个具有 5 个值(从 1 到 5)的数组会创建 5 个条形,这些条形具有不同的条形尺寸,并且每个条形都有不同的颜色。与以下示例非常相似 http://www.c-sharpcorner.com/uploadfile/mahesh/bar-chart-in-wpf/
问题:
我的问题是条形的比例大小(在这种情况下是 width 属性,因此需要 int/double 值)。
- 我的程序以 HH:mm:ss 格式记录了多个日期时间
- 条形应按这些日期时间缩放
条形图或一个 00:01:11 的柱线,最大数量为 6。
将这些日期时间值缩放到某个双精度值的最佳方法是什么?此值将用于给出图表上条形的大小。
猜猜我正在寻找某种计算,可以计算我的所有值,所以我不会突然得到一个非常大的值并且超出我的 UI。
最干净的解决方案是将所有柱线相互比较,当一个改变时,另一个柱线会增长/收缩,但到目前为止还不需要这样做,除非它不像听起来那么复杂。
酒吧字符本身不需要过于精确,它仅用于了解情况的总体情况。确切的值将写入数据库中。
欢迎任何建议!
谢谢彼得·
我会选择一个基准日期,并使您的集合图显示基准日期和数据日期之间的天数/小时数/分钟数
您甚至可以使用转换器执行此操作,其中将基准日期作为转换器参数传入。
您的两个示例日期(01:22:11
和 00:01:11
)实际上是时间,因此在这种情况下,我只绘制自 0 以来的分钟数,因此要绘制的实际数据值将是 82 和 1
为了响应您的编辑询问缩放,您将以百分比形式绘制所有内容。在这种情况下,取最大数字,并根据最大数字的百分比绘制每隔一个数字。
因此,使用您的两个示例时间,我会将它们转换为数字 82 和 1,将较大的数字 (82) 转换为 100%,并返回一个包含每个数字的百分比为 82 的列表,因此返回列表将包含 100% 和 1.2% (1/82)。
您仍然可以在 ViewModel
或 ItemsSource
转换器中执行此操作(转换器会将整个列表作为参数,并返回返回值的整个列表)
编辑
为了回应您在下面的评论,以下是我将如何使用ItemsSource
上的Converter
进行设置。转换器只是获取一个数据值,并将其转换为仅特定于显示 UI 的另一个值。
初始 XAML 如下所示:
<ItemsControl ItemsSource="{Binding MyCollection,
Converter="{StaticResource MyTimeConverter}}" />
其中MyCollection
是ObservableCollection<DateTime>
,MyTimeConverter
执行以下操作:
- 将传入的
value
转换为ObservableCollection<DateTime>
,因为所有转换器参数都作为object
传入 - 循环浏览集合并找出最大的时间
- 取集合中最大的时间,并计算出它有多少分钟。这将是您的 100% 值,您将基于所有其他时间,因此将最大时间的分钟数存储在变量中
- 为返回值创建新
List<decimal>
- 循环开始收集。对于集合中的每次,将其除以您在步骤 3 中存储的"100% 值",这将为您提供该条形与最大值进行比较的时间百分比。将此百分比添加到回报
List<decimal>
- 将
List<decimal>
返回ItemsControl
。此List<decimal>
将用作ItemsSource
,而不是实际ObservableCollection<DateTime>
这意味着您的ItemsControl
现在绑定到小数集合,其中一个值为 100%,将采用屏幕的整个宽度,所有其他值都缩放到最大值。
关于使用计时器更新集合的问题,计时器应更新ItemsControl
绑定到的名为MyCollection
ObservableCollection<DateTime>
。计时器根本不应该知道或关心转换器代码。
例如,如果您的计时器想要使用一组全新的时间重新创建MyCollection
,那么它可以,并且 UI 将自动重新运行转换器代码并更新条形图,因为ObservableCollections
会在集合更改和 UI 需要更新时告诉 UI。
至于我在下面的评论中提到的"基准日期",如果您绘制一组日期而不是时间,您会需要一个基线日期,这样您的图表就不会延伸到1/1/0001
。您不想使用最小日期,因为这会导致您的最低值在条形图中显示为 0,因此您需要将Converter
传递一个特定日期以用作图表中的起点。如果基准日期是 1/1/12,而最大的日期是 3/1/12,则图表将从 1/1/12 延伸至 3/1/12。
基准日期将在转换器的步骤 3 和 5 中使用。例如,您可以获取基准日期和数据日期之间的天数,而不是获取时间中的分钟数。
您还可以在转换器中计算基准日期,例如最低日期前 10 天,尽管这可能会使图表比您希望的更倾斜,具体取决于数据。
Normalise。
- 将总时间转换为秒。 (将总
- 可用宽度除以总时间)= 因子A
- 要找到每个条形的适当宽度,请将其时间乘以因子 A
编辑:选择一个合适的日期/时间来测量零,或者你可以只使用日期时间对象的总秒属性
听起来您只需要跟踪所有值的最大值。然后,根据此最大值缩放每个值:
var scale = value / maximum;
var height = scale * ActualHeight;
当然,您实际设置每个项目高度的方式可能是通过绑定。
我直言,整个条形图的背面应该有一个 ViewModel,并且此 VM 具有计算最大值然后定义缩放的逻辑。