Гистограммы в WinRT

61

Один из эффектных трюков со списковым элементом управления - построение гистограммы с минимальными затратами времени и сил. От вас потребуется лишь элемент ItemsControl, содержащий числовое свойство, пригодное для привязки, элемент Rectangle в ItemTemplate и панель UniformGrid или StackPanel для хранения выходных данных.

Проект RgbBarChart показывает, как это делается. Свойство ItemsSource элемента ItemsControl, конечно, содержит коллекцию объектов NamedColor. Шаблон DataTemplate представляет собой вертикальную панель StackPanel с тремя элементами Rectangle, свойства Height которых привязываются к свойствам R, G и В свойства Color объектов данных. В обычном случае это приведет к созданию трех элементов Rectangle, начинающихся от верхнего края StackPanel, но мне захотелось создать более традиционную гистограмму со столбцами, направленными снизу вверх, поэтому я перевернул столбцы при помощи RenderTransform:

<Page ...>

    <Grid Background="White">
        <Grid.Resources>
            <local:NamedColor x:Key="namedcolors" />
            <local:ColorToContrastColorConverter x:Key="colorsConverter" />
        </Grid.Resources>

        <ItemsControl ItemsSource="{Binding Source={StaticResource namedcolors},
                                            Path=All}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel RenderTransformOrigin="0.5, 0.5"
                                Name="stp"
                                Height="800" Margin="1 0">
                        <StackPanel.RenderTransform>
                            <ScaleTransform ScaleY="-1" />
                        </StackPanel.RenderTransform>

                        <Rectangle Fill="LimeGreen" Height="{Binding Color.R}" />
                        <Rectangle Fill="DarkOrange" Height="{Binding Color.G}" />
                        <Rectangle Fill="LightBlue" Height="{Binding Color.B}" />

                        <ToolTipService.ToolTip>
                            <ToolTip x:Name="tooltip"
                                     PlacementTarget="{Binding ElementName=stp}">

                                <!-- Свойству DataContext задается StackPanel с данными -->
                                <Grid DataContext="{Binding ElementName=tooltip, 
                                                            Path=PlacementTarget}">

                                    <!-- Свойству DataContext задается NamedColor -->
                                    <StackPanel DataContext="{Binding DataContext}">
                                        <TextBlock Text="{Binding Name}"
                                                   HorizontalAlignment="Center" />
                                        <StackPanel DataContext="{Binding Color}"
                                                    HorizontalAlignment="Center"
                                                    Orientation="Horizontal">
                                            <TextBlock Text="R=" />
                                            <TextBlock Text="{Binding R}" />
                                            <TextBlock Text=" G=" />
                                            <TextBlock Text="{Binding G}" />
                                            <TextBlock Text=" B=" />
                                            <TextBlock Text="{Binding B}" />
                                        </StackPanel>
                                    </StackPanel>
                                </Grid>
                            </ToolTip>
                        </ToolTipService.ToolTip>

                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>

            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <local:UniformGrid Rows="1" />
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </Grid>
</Page>

Конечно, столбцы сами по себе не слишком информативны. Один из способов идентификации представляемых значений - вывод подсказок при наведении указателя мыши. Впрочем, это довольно хлопотное решение. Чтобы связать с элементом подсказку следует задать вложенное свойство ToolTipService.ToolTip и определить элемент управления ToolTip. Класс ToolTip является производным от ContentControl, но он не принадлежит визуальному дереву, потому что «парит» над ним. Он не наследует свойства по визуальному дереву, включая исключительно важное свойство DataContext. Мне пришлось добираться до него через свойство PlacementTarget объекта ToolTip.

Ниже изображена гистограмма с красной, зеленой и синей составляющими для 141 цвета. В подсказке рядом с одним из столбцов выводится имя цвета и значения составляющих RGB:

Гистограмма на Win RT

Для белого цвета сумма составляющих равна 765 - лишь немногим менее высоты экрана (768 пикселов). Конечно, столбцы можно укоротить для меньших экранов (или больших значений) с использованием RenderTransform.

Пройди тесты
Лучший чат для C# программистов