首页 > 解决方案 > 图表布局不正确

问题描述

我创建了一个应该显示的程序,以显示在给定日期创建了多少文件。我想在带有 Livecharts 的图表中显示这些计数。对于我拥有的每个驱动器,我都会在我的 SeriesCollection 中创建一个新系列。但是当我想将值添加到系列并显示系列时,值不会显示在它们创建的实际日期上,而是显示在图表的左侧。

为了更好地理解我的意思是图表的图片。1红色的 E:驱动器从 2016 年开始 - 今天,黄色的仅从 2020 年左右开始 - 今天。然而,黄色和蓝色系列在左侧,表明最后创建的文件是在 2016 年左右。

这是添加标签和值的代码,所以应该是错误的代码

// Get all Drives connected to the PC
            var drives = Directory.GetLogicalDrives();

            foreach (var drive in drives)
            {
                // Skip C drive, because it is too big on my pc and takes 3 minutes
                // Delete the line after performance upgrades or if not debugging anymore
                if (drive == "C:\\")
                    continue;

                // Start Task, to not halt the Programm
                var r = await DoWork(drive);

                // Add each Drive as Series
                SeriesCollection.Add(new LineSeries
                {
                    Title = $"{drive}: Drive",
                    Values = new ChartValues<int> { },
                    LineSmoothness = 0,
                });

                // Order the dictionary returned by DoWork
                var l = r.OrderBy(key => key.Key);
                var dict = l;

                foreach (KeyValuePair<DateTime, int> entry in dict)
                {
                    // Dont need to add another label of the same day
                    if (!Labels.Contains(Convert.ToString(entry.Key.Date)))
                        Labels.Add(Convert.ToString(entry.Key.Date));

                    // Add the value to the series
                    SeriesCollection[SeriesCollection.Count - 1].Values.Add(entry.Value);
                }
            }

如果您好奇,这里是完整代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using LiveCharts;
using LiveCharts.Wpf;
using System.ComponentModel;
using System.IO;

namespace GraphOfFileDownloads
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();

            SeriesCollection = new SeriesCollection { };
            Labels = new List<string>();
            DataContext = this;
        }

        public SeriesCollection SeriesCollection { get; set; }
        public List<String> Labels { get; set; }
        public Func<int, string> YFormatter { get; set; }

        private async void BtnStart_Click(object sender, RoutedEventArgs e)
        {
            // Get all Drives connected to the PC
            var drives = Directory.GetLogicalDrives();

            foreach (var drive in drives)
            {
                // Skip C drive, because it is too big on my pc and takes 3 minutes
                // Delete the line after performance upgrades or if not debugging anymore
                if (drive == "C:\\")
                    continue;

                // Start Task, to not halt the Programm
                var r = await DoWork(drive);

                // Add each Drive as Series
                SeriesCollection.Add(new LineSeries
                {
                    Title = $"{drive}: Drive",
                    Values = new ChartValues<int> { },
                    LineSmoothness = 0,
                });

                // Order the dictionary returned by DoWork
                var l = r.OrderBy(key => key.Key);
                var dict = l;

                foreach (KeyValuePair<DateTime, int> entry in dict)
                {
                    // Dont need to add another label of the same day
                    if (!Labels.Contains(Convert.ToString(entry.Key.Date)))
                        Labels.Add(Convert.ToString(entry.Key.Date));

                    // Add the value to the series
                    SeriesCollection[SeriesCollection.Count - 1].Values.Add(entry.Value);
                }
            }
        }

        private async Task<Dictionary<DateTime, int>> DoWork(string drive)
        {
            var dict = await Task.Run(() => GetFileDateCount(drive));
            return dict;
        }

        private Dictionary<DateTime, int> GetFileDateCount(string drive)
        {
            // Create some essentials
            List<DateTime> dateTimes = new List<DateTime>();
            Dictionary<DateTime, int> creationDates = new Dictionary<DateTime, int>();

            // Start working through the drive Recursivly
            UpdateListDateTimesRecursive(drive, ref dateTimes);

            // Add up how many times files were created on a given Date
            foreach (var time in dateTimes)
            {
                if (creationDates.ContainsKey(time))
                {
                    creationDates[time] += 1;
                }
                else
                {
                    creationDates.Add(time, 1);
                }
            }

            return creationDates;
        }

        private void UpdateListDateTimesRecursive(string path, ref List<DateTime> dateTimes)
        {
            // Get child Directories from given path
            var dirs = Directory.GetDirectories(path);

            foreach (var dir in dirs)
            {
                try
                {
                    // Get all Files contained in this Directory
                    var files = Directory.GetFiles(dir);

                    // Add the dates of files to list, to count later
                    foreach (var file in files)
                    {

                        try
                        {
                            dateTimes.Add(File.GetCreationTime(file).Date);
                        }
                        // It is to be expected, that some Files cannot be accessed, so just ignore them
                        catch (System.UnauthorizedAccessException)
                        {
                            Console.WriteLine("File: {0} is not Available", file);
                        }
                    }

                    // Go further through the Directories
                    UpdateListDateTimesRecursive(dir, ref dateTimes);
                }
                // It is to be expected, that some Directories cannot be accessed, so just ignore them
                catch (System.UnauthorizedAccessException)
                {
                    Console.WriteLine("Path: {0} is not Available", dir);
                }
            }
        }
    }
}

最后,这是 XAML

<Window x:Class="GraphOfFileDownloads.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:GraphOfFileDownloads"
        xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="650" Width="1000">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="800"/>
            <ColumnDefinition Width="200"/>
        </Grid.ColumnDefinitions>
        <lvc:CartesianChart Series="{Binding SeriesCollection}" LegendLocation="Right" >
            <lvc:CartesianChart.AxisY>
                <lvc:Axis Title="Amount"></lvc:Axis>
            </lvc:CartesianChart.AxisY>
            <lvc:CartesianChart.AxisX>
                <lvc:Axis Title="Date" Labels="{Binding Labels}"></lvc:Axis>
            </lvc:CartesianChart.AxisX>
        </lvc:CartesianChart>
        <StackPanel Grid.Column="1" VerticalAlignment="Top" Margin="10">
            <StackPanel.Resources>
                <Style TargetType="{x:Type Button}">
                    <Setter Property="Margin" Value="0,10,0, 0"/>
                </Style>
            </StackPanel.Resources>
            <Button Height="50" x:Name="btnStart" Click="BtnStart_Click">
                Start
            </Button>
        </StackPanel>
    </Grid>
</Window>

标签: c#wpflivecharts

解决方案


推荐阅读