我在一个控制台应用程序中工作,并试图在C#控制台中绘制图表,但我无法将标记与X轴上的值对齐,我try 在星号中添加间距,但一无所获,您有什么 idea 吗?我应该用循环来做这个

理想情况下,我希望打印X轴上值的第二位数字上方的标记

这是存储在数组PHValues[]和Dates[]中作为参考的数据

Date,       pH Level
10-21-2023, 12.3
10-22-2023, 11.9
10-23-2023, 13.6
10-24-2023, 11.9
10-25-2023, 10.8

这是我的代码:

 static void DisplayChart(double[] pHValues, string[] dates, int count)
 {
     string message = "\nNo entries available for the graph. ";
     if (count == 0)
     {         
         DisplayContinueMessage(message);
         return;
     }

     var distinctPhValues = pHValues.Distinct().OrderByDescending(x => x).ToArray();

     foreach (var value in distinctPhValues)
     {
         //print pH values in the Y-axis
         Console.Write($"{value:0.0}| ");

         for (int i = 0; i < count; i++)
         {
             if (pHValues[i] == value)
             {
                 Console.Write("  * ");
             } 
             else
             {
                 Console.Write("  ");
             }
         }
         Console.WriteLine();
     }

     // Print dates on the X-axis
     Console.WriteLine("----------------------");
     Console.Write("Day|  ");
     
     for (int i = 0; i < count; i++)
     {
         Console.Write($"{dates[i].Substring(3, 2)}  ");
     }

     Console.ReadLine();


 }

这就是我得到的:


13.6|     *
12.3| *
11.9|   *   *
10.8|         *
0.0|
----------------------
Day|  21  22  23  24  25

推荐答案

X轴上的日期的第二位数字彼此相隔3个字符.对齐Y轴后,您需要做的就是重复打印一个空格/星号,然后是3个空格.

要对齐Y轴,可以通过查找具有最多字符的ph值来找到其宽度(当然,如果您知道这些值必须在某个范围内,则可以使用更快的方法):

var yAxisWidth = distinctPhValues
    .Select(x => $"{x:0.0}".Length).Max();

然后,您可以使用PadLeft(或PadRight,如果您想要左对齐)来打印ph值.

foreach (var value in distinctPhValues)
{
    //print pH values in the Y-axis
    Console.Write($"{value:0.0}".PadLeft(yAxisWidth));
    Console.Write("|  "); // note I added an extra space here to account for the first digit of the first date
    for (int i = 0; i < pHValues.Length; i++)
    {
        if (pHValues[i] == value)
        {
            Console.Write("*");
        } 
        else
        {
            Console.Write(" ");
        }
        Console.Write("   "); // the stars are all 3 spaces apart from each other
    }
    Console.WriteLine();
}

X轴的长度很容易计算--用每个日期占用的字符数乘以dates.Length(即4),再加上Y轴的宽度

Console.WriteLine(new string('-', yAxisWidth + 4 * dates.Length));
Console.Write("Day".PadLeft(yAxisWidth));
Console.Write("| ");

for (int i = 0; i < dates.Length; i++)
{
    // consider actually using a DateTime/DateOnly instead of strings to represent dates
    // then you can do:
    // Console.Write($"{dates[i].Day,2}  ");
    Console.Write($"{dates[i].Substring(3, 2)}  ");
}

用法示例:

DisplayChart(
    new double[] {
        12.3, 11.9, 13.6, 11.9, 10.8
    },
    new string[] {
        "10-21-2023",
        "10-22-2023",
        "10-23-2023",
        "10-24-2023",
        "10-25-2023",
    }
);

输出示例:

13.6|          *           
12.3|  *                   
11.9|      *       *       
10.8|                  *   
------------------------
 Day| 21  22  23  24  25

Csharp相关问答推荐

在包含空项的列表上使用具有断言T的摘要表

如何将字节数组转换为字符串并返回?

EF Core判断是否应用了AsSplitQuery()

C#相同名称的枚举方法和normal方法,参数类型不同

REST API端点中异步后台代码执行的类型

调用Task.Run()与DoSomethingAsync()有什么不同?

反序列化私有成员

如何使用MailKit删除邮箱?

在Docker容器中运行API项目时,无法本地浏览到index.html

为什么我不能从我的异步任务方法中返回异步任务方法?

匿名类型的AbstractValidator

用于请求用户返回列表的C#Google API

如何在C#中从MongoDB IPipelineStageDefinition中获取聚合命令的字段/选项?

C#使用相同内存的多个数组

当我手动停止和关闭系统并打开时,Windows服务未启动

如何使用IHostedService添加数据种子方法

使用LibraryImport在多个dll中导入相同的函数

如何使ExecuteAsync异步运行

如何在JSON:API中定义的&过滤查询参数系列&标准的GET请求中传递多个相关参数?

无法将.Net Framework 4.8.1升级到.Net 7