项目控制条形图 条形的缩放

本文关键字:缩放 控制 条形图 项目 | 更新日期: 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 格式记录了多个日期时间
  • 条形应按这些日期时间缩放
例如,我可以有一个 01:22:11 的

条形图或一个 00:01:11 的柱线,最大数量为 6。

将这些日期时间值缩放到某个双精度值的最佳方法是什么?此值将用于给出图表上条形的大小。

猜我正在寻找某种计算,可以计算我的所有值,所以我不会突然得到一个非常大的值并且超出我的 UI。

最干净的解决方案是将所有柱线相互比较,当一个改变时,另一个柱线会增长/收缩,但到目前为止还不需要这样做,除非它不像听起来那么复杂。

酒吧字符本身不需要过于精确,它仅用于了解情况的总体情况。确切的值将写入数据库中。

欢迎任何建议!

谢谢彼得·

项目控制条形图 条形的缩放

我会选择一个基准日期,并使您的集合图显示基准日期和数据日期之间的天数/小时数/分钟数

您甚至可以使用转换器执行此操作,其中将基准日期作为转换器参数传入。

您的两个示例日期(01:22:1100:01:11 )实际上是时间,因此在这种情况下,我只绘制自 0 以来的分钟数,因此要绘制的实际数据值将是 82 和 1

为了响应您的编辑询问缩放,您将以百分比形式绘制所有内容。在这种情况下,取最大数字,并根据最大数字的百分比绘制每隔一个数字。

因此,使用您的两个示例时间,我会将它们转换为数字 82 和 1,将较大的数字 (82) 转换为 100%,并返回一个包含每个数字的百分比为 82 的列表,因此返回列表将包含 100% 和 1.2% (1/82)。

您仍然可以在 ViewModelItemsSource 转换器中执行此操作(转换器会将整个列表作为参数,并返回返回值的整个列表)

<小时 />

编辑

为了回应您在下面的评论,以下是我将如何使用ItemsSource上的Converter进行设置。转换器只是获取一个数据值,并将其转换为仅特定于显示 UI 的另一个值。

初始 XAML 如下所示:

<ItemsControl ItemsSource="{Binding MyCollection, 
    Converter="{StaticResource MyTimeConverter}}" />

其中MyCollectionObservableCollection<DateTime>MyTimeConverter执行以下操作:

  1. 将传入的value转换为ObservableCollection<DateTime>,因为所有转换器参数都作为object传入
  2. 循环浏览集合并找出最大的时间
  3. 取集合中最大的时间,并计算出它有多少分钟。这将是您的 100% 值,您将基于所有其他时间,因此将最大时间的分钟数存储在变量中
  4. 为返回值创建新List<decimal>
  5. 循环开始收集。对于集合中的每次,将其除以您在步骤 3 中存储的"100% 值",这将为您提供该条形与最大值进行比较的时间百分比。将此百分比添加到回报List<decimal>
  6. 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 具有计算最大值然后定义缩放的逻辑。