簡體   English   中英

ItemsControl條形圖縮放條形圖

[英]ItemsControl Bar Chart Scaling of the bars

編輯:添加代碼

此外,由於DateTimes不是真正的日期時間(shrings in hh:mm:ss format),我決定只使用字符串並使用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值)。

  • 我的程序以HH:mm:ss格式記錄幾個DateTimes
  • 應在這些日期時間縮放條形

例如,我可以使用01:22:11的條形圖或00:01:11的條形圖,最大金額為6。

將這些DateTime值縮放到某個double值的最佳方法是什么? 此值將用於給出圖表上條形的大小。

猜猜我正在尋找某種計算方法來計算我所有的值,所以我不會突然得到一個非常大的值並且超出我的UI。

最干凈的解決方案是將所有條形圖相互比較,當一個條形圖發生變化時,另一個條形圖會增大/縮小,但這並不是必需的,盡管它不像聽起來那么復雜。

條形碼本身並不需要過於精確,它只能用於了解情況的一般情況。 確切的值將寫入數據庫中。

歡迎任何建議!

謝謝PeterP。

規范化。

  • 將總時間轉換為秒。
  • (將總可用寬度除以總時間)= factorA
  • 要找到每個條的適當寬度,請將其時間乘以factorA

編輯:選擇一個合適的日期/時間來測量零,或者你可以使用你的DateTime對象的總秒數屬性

我會選擇一個基准日期,並使您的集合圖表顯示基准日期和數據日期之間的天數/小時/分鍾數

您甚至可以使用轉換器執行此操作,您可以將基准日期作為轉換器參數傳遞。

你的兩個例子日期( 01:22:1100:01:11 )實際上是時間,所以在這種情況下,我只是繪制了自0以來的分鍾數,因此您對圖表的實際數據值將為82和1

為了回應您關於縮放的編輯問題,您將以百分比形式繪制所有內容。 在這種情況下,請根據最大數字的百分比取最大數字並繪制每隔一個數字的圖表。

因此,使用您的兩個示例時間,我將它們轉換為數字82和1,將較大的數字(82)轉換為100%,並返回包含每個數字的百分比的列表為82,因此返回列表將包含100 %和1.2%(1/82)。

您仍然可以在ViewModelItemsSource Converter中執行此操作(轉換器將整個列表作為參數,並返回整個列表以返回值)


編輯

為了回應您下面的評論,以下是我如何使用ItemsSource上的Converter進行設置。 轉換器只需獲取數據值,並將其轉換為僅適用於顯示UI的另一個值。

最初的XAML看起來像這樣:

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

其中MyCollection是一個ObservableCollection<DateTime>MyTimeConverter執行以下操作:

  1. 將傳入的valueObservableCollection<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綁定的名為MyCollectionObservableCollection<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天,盡管根據數據的不同,這可能會使圖表偏差超過您的偏好。

聽起來你只需要跟蹤所有值的最大值。 然后,根據此最大值縮放每個值:

var scale = value / maximum;
var height = scale * ActualHeight;

當然,實際設置每個項目高度的方式可能是通過綁定。

imho你整個條形圖應該在后面有一個ViewModel,這個VM有邏輯來計算最大值,然后定義縮放。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM