LiveCharts ColumnSeries не отображается - PullRequest
0 голосов
/ 12 января 2019

Я использую LiveCharts в WPF для визуализации результатов некоторых анализов. Результаты анализа добавляются в коллекцию SeriesCollection и отображаются в CartesianChart. Вы можете выбрать, какой тип серии использовать: LineSeries или ColumnSeries. Затем выбранный тип создается и добавляется в коллекцию SeriesCollection.

Существует пользовательское сопоставление для выбора значений X и Y из значений ChartValues ​​и AxisFormatter для оси X.

Графики являются частью Blacklight.Controls.Wpf.DragDockPanelHost. Каждая диаграмма представляет собой DragDockPanel со стилем, прикрепленным к нему. Сама диаграмма является ContentControl с TemplateSelector, который возвращает CartesianChart-XAML в качестве DataTemplate.

Я уже пытался установить Fill или Stroke для серии или поместить туда несколько ColumnSeries вручную, но это не помогло.

Заполнение серииКоллекция:

private SeriesCollection _Series;
public SeriesCollection Series
{
    get { return _Series; }
    set { SetProperty<SeriesCollection>(ref _Series, value); }
}

...

private void createDiagram()
{
    if (this._Analysis!= null && this._Diagram != null)
    {
        this.Series.Clear();
        foreach (KeyValuePair<state, Dictionary<DateTime, int>> kvp in this.Analysis.Execute())
        {
            Series series = Activator.CreateInstance(Diagram) as Series;
            if (series != null)
            {
                series.Title = kvp.Key.name;
                series.Values = new ChartValues<KeyValuePair<DateTime, int>>(kvp.Value);
                this.Serien.Add(series);
            }
        }
    }
}

Картограф и AxisFormatter:

CartesianMapper<KeyValuePair<DateTime, int>> mapper = Mappers.Xy<KeyValuePair<DateTime, int>>().X(kvp => ((DateTimeOffset)kvp.Key).ToUnixTimeSeconds()).Y(kvp => kvp.Value);
this.Series = new SeriesCollection(mapper);
this.XFormatter = value =>
{
    return DateTimeOffset.FromUnixTimeSeconds((long)value).DateTime.ToString("dd.MM.yyyy HH:mm");
};

TemplateSelector:

public class DashboardElementTemplateSelector : DataTemplateSelector
  {
    public DataTemplate ListDashboardElementTemplate { get; set; }
    public DataTemplate SingleValueDashboardElementTemplate { get; set; }

    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
      if (item is ListDashboardElementViewModel)
        return this.ListDashboardElementTemplate;
      else
        return this.SingleValueDashboardElementTemplate;
    }
  }

XAML DragDockPanelHost:

  <UserControl.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary>
          <DataTemplate x:Key="listElement">
            <views:ListDashboardElementView/>
          </DataTemplate>
          <DataTemplate x:Key="singleValueElement">
            <views:SingleValueDashboardElementView/>
          </DataTemplate>
          <tempselect:DashboardElementTemplateSelector x:Key="elementTempSelector"
                                                       ListDashboardElementTemplate="{StaticResource listElement}"
                                                       SingleValueDashboardElementTemplate="{StaticResource singleValueElement}"
                                                       />
        </ResourceDictionary>
        <ResourceDictionary>
          <conv:BooleanToVisibilityConverter x:Key="visCon"/>
        </ResourceDictionary>
      </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
  </UserControl.Resources>

<bl:DragDockPanelHost ItemsSource="{Binding Diagrams}" Grid.Row="1" Margin="20" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
      <bl:DragDockPanelHost.Style>
        <Style TargetType="bl:DragDockPanelHost">
          <Setter Property="ItemsPanel">
            <Setter.Value>
              <ItemsPanelTemplate>
                <Canvas ClipToBounds="True" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                </Canvas>
              </ItemsPanelTemplate>
            </Setter.Value>
          </Setter>
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="bl:DragDockPanelHost">
                <ItemsPresenter/>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </bl:DragDockPanelHost.Style>
      <bl:DragDockPanelHost.DefaultPanelStyle>
        <Style TargetType="{x:Type bl:DragDockPanel}">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate>
                <Grid Margin="10">
                  <Grid Margin="5">
                    <Grid.RowDefinitions>
                      <RowDefinition Height="30"/>
                      <RowDefinition/>
                    </Grid.RowDefinitions>
                    <Border Background="#00000000" Margin="-2" Padding="5" Grid.Row="0">
                      <Grid>
                        <Grid.ColumnDefinitions>
                          <ColumnDefinition Width="4*"/>
                          <ColumnDefinition Width="2*"/>
                        </Grid.ColumnDefinitions>
                        <WrapPanel>
                          <Image Width="20" x:Name="GripBarElement" Source="/Aisys.XStorage.Dashboard;component/Images/move.png" Grid.Column="0" Cursor="Hand" HorizontalAlignment="Left"/>
                          <TextBlock Text="{Binding Name}" Grid.Column="0" FontSize="16" FontWeight="Bold" Margin="10,0,0,0"/>
                        </WrapPanel>
                        <WrapPanel HorizontalAlignment="Right" Grid.Column="2">
                          <Button Command="{Binding ExecuteCommand}" CommandParameter="{Binding}" Margin="5,0,5,0">
                            <Button.Template>
                              <ControlTemplate>
                                <Image Source="/Aisys.XStorage.Dashboard;component/Images/Refresh.png"/>
                              </ControlTemplate>
                            </Button.Template>
                          </Button>
                          <Button Width="20" Command="{Binding DataContext.RemoveDiagramCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type bl:DragDockPanelHost}}}" CommandParameter="{Binding}">
                            <Button.Template>
                              <ControlTemplate>
                                <Image Source="/Aisys.XStorage.Dashboard;component/Images/Remove.png"/>
                              </ControlTemplate>
                            </Button.Template>
                          </Button>
                          <Button Command="{Binding DataContext.ShowPropertiesCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type bl:DragDockPanelHost}}}" CommandParameter="{Binding}" Margin="5,0,5,0">
                            <Button.Template>
                              <ControlTemplate>
                                <Image Source="/Aisys.XStorage.Dashboard;component/Images/Preferences.png"/>
                              </ControlTemplate>
                            </Button.Template>
                          </Button>
                          <ToggleButton x:Name="MaximizeToggleButton" VerticalAlignment="Top" HorizontalAlignment="Right" IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay, Path=IsMaximized}" Margin="0,5,5,0" Width="25" Height="25" Cursor="Hand">
                            <ToggleButton.Template>
                              <ControlTemplate TargetType="ToggleButton">
                                <Image Source="/Aisys.XStorage.Dashboard;component/Images/Maximize.png" Margin="0,0,0,5"/>
                              </ControlTemplate>
                            </ToggleButton.Template>
                          </ToggleButton>
                        </WrapPanel>
                      </Grid>
                    </Border>
                    <Separator VerticalAlignment="Bottom" Margin="0,0,0,0"/>
                    <ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource elementTempSelector}" Grid.Row="1" Margin="10"/>
                  </Grid>
                </Grid>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </bl:DragDockPanelHost.DefaultPanelStyle>
    </bl:DragDockPanelHost>

XAML графика:

  <Grid>
    <lvc:CartesianChart Series="{Binding Series}" LegendLocation="Right" Name="chart">
      <lvc:CartesianChart.AxisX>
        <lvc:Axis Title="Zeit" LabelFormatter="{Binding XFormatter}">
        </lvc:Axis>
      </lvc:CartesianChart.AxisX>
    </lvc:CartesianChart>
  </Grid>

Если я выбираю LineSeries, все работает нормально. Но когда я использую ColumnSeries ничего не отображается. Вы можете видеть, что ось перерисована и разделители перемещаются. Легенда также нарисована, но столбцы не видны.

Есть идеи, почему это происходит?

1 Ответ

0 голосов
/ 05 июня 2019

У меня недавно была такая же проблема. К сожалению, это нигде не задокументировано, но по какой-то причине , если у вас слишком много точек данных для размера графика, тогда ни один из столбцов не отобразит . Вы можете либо попытаться уменьшить количество точек данных, пока они не будут работать (в моем случае 90 точек данных не будут отображаться, а 30 будет отображаться), либо в ColumnSeries есть свойство ColumnPadding , которое можно уменьшить до ноль и посмотрим, поможет ли это.

...