Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ ClientBin/
*.publishsettings
orleans.codegen.cs

# Including strong name files can present a security risk
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk

Expand Down Expand Up @@ -317,7 +317,7 @@ __pycache__/
# OpenCover UI analysis results
OpenCover/

# Azure Stream Analytics local run output
# Azure Stream Analytics local run output
ASALocalRun/

# MSBuild Binary and Structured Log
Expand All @@ -326,5 +326,5 @@ ASALocalRun/
# NVidia Nsight GPU debugger configuration file
*.nvuser

# MFractors (Xamarin productivity tool) working folder
# MFractors (Xamarin productivity tool) working folder
.mfractor/
2 changes: 1 addition & 1 deletion AsciiChart.Sharp.TestApp/AsciiChart.Sharp.TestApp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.1</TargetFramework>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
27 changes: 17 additions & 10 deletions AsciiChart.Sharp.TestApp/Program.cs
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
using System;
using System.Linq;
using System.Text;

namespace AsciiChart.Sharp.TestApp
{
class Program
static class Program
{
static void Main(string[] args)
static void Main()
{
var series = new double[100];
for (var i = 0; i < series.Length; i++)
{
series[i] = 15 * Math.Sin(i * ((Math.PI * 4) / series.Length));
series[i] = 15 * Math.Sin(i * (Math.PI * 4 / series.Length));
}

Console.OutputEncoding = Encoding.UTF8;
Console.WriteLine(AsciiChart.Plot(series));

Expand All @@ -24,18 +25,24 @@ static void Main(string[] args)
AxisLabelRightMargin = 0,
Height = 4,
Fill = '·',
AxisLabelFormat = "0,000.000",
AxisLabelFormat = "0,000.000"
}));



var series2 = new double[100];
for (var i = 0; i < series.Length; i++)
{
series2[i] = (200000 * Math.Cos(i * ((Math.PI * 8) / series.Length))) + 1000000;
series2[i] = 200000 * Math.Cos(i * (Math.PI * 8 / series.Length)) + 1000000;
}

Console.WriteLine();
Console.WriteLine(AsciiChart.Plot(series2, new Options{Height = 10}));

Console.WriteLine();
Console.WriteLine(AsciiChart.Plot(
Enumerable.Range(0, 6)
.Select(i => Enumerable.Range(-40, 81).Select(x => Math.Abs(x) > 40 - i ? double.NaN : Math.Sqrt((40 - i) * (40 - i) - x * x) / 2))
.ToList(),
new Options { AxisLabelFormat = "0" }));
}
}
}
}
16 changes: 16 additions & 0 deletions AsciiChart.Sharp.Tests/AsciiChart.Sharp.Tests.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
<PackageReference Include="NUnit" Version="3.13.2" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\AsciiChart.Sharp\AsciiChart.Sharp.csproj" />
</ItemGroup>

</Project>
248 changes: 248 additions & 0 deletions AsciiChart.Sharp.Tests/Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
using System;
using System.Text.RegularExpressions;
using NUnit.Framework;

namespace AsciiChart.Sharp.Tests
{
public class Tests
{
static readonly Regex _normalize = new Regex(@" *(\r\n|\n\r|\n|\r)", RegexOptions.Compiled);

[Test]
[TestCaseSource(nameof(Cases))]
public void TestPlot(double[] series, Options opts, string expected)
{
var actual = AsciiChart.Plot(series, opts);
Assert.AreEqual(Normalize(expected), Normalize(actual));
}

static object[][] Cases =
{
new object[] { new double[] { 1 }, null, " 1.00 ┼ " },
new object[] { new double[] { 1, 1, 1, 1, 1 }, null, " 1.00 ┼──── " },
new object[] { new double[] { 0, 0, 0, 0, 0 }, null, " 0.00 ┼──── " },
new object[]
{
new double[] { 2, 1, 1, 2, -2, 5, 7, 11, 3, 7, 1 }, null, @"
11.00 ┤ ╭╮
10.00 ┤ ││
9.00 ┤ ││
8.00 ┤ ││
7.00 ┤ ╭╯│╭╮
6.00 ┤ │ │││
5.00 ┤ ╭╯ │││
4.00 ┤ │ │││
3.00 ┤ │ ╰╯│
2.00 ┼╮ ╭╮│ │
1.00 ┤╰─╯││ ╰
0.00 ┤ ││
-1.00 ┤ ││
-2.00 ┤ ╰╯"
},
new object[]
{
new double[] { 2, 1, 1, 2, -2, 5, 7, 11, 3, 7, 4, 5, 6, 9, 4, 0, 6, 1, 5, 3, 6, 2 }, null, @"
11.00 ┤ ╭╮
10.00 ┤ ││
9.00 ┤ ││ ╭╮
8.00 ┤ ││ ││
7.00 ┤ ╭╯│╭╮ ││
6.00 ┤ │ │││ ╭╯│ ╭╮ ╭╮
5.00 ┤ ╭╯ │││╭╯ │ ││╭╮││
4.00 ┤ │ ││╰╯ ╰╮││││││
3.00 ┤ │ ╰╯ ││││╰╯│
2.00 ┼╮ ╭╮│ ││││ ╰
1.00 ┤╰─╯││ ││╰╯
0.00 ┤ ││ ╰╯
-1.00 ┤ ││
-2.00 ┤ ╰╯"
},
new object[]
{
new[] { 0.2, 0.1, 0.2, 2, -0.9, 0.7, 0.91, 0.3, 0.7, 0.4, 0.5 }, null, @"
2.00 ┤ ╭╮
1.03 ┤ ││╭─╮╭╮╭
0.07 ┼──╯││ ╰╯╰╯
-0.90 ┤ ╰╯"
},
new object[]
{
new double[] { 2, 1, 1, 2, -2, 5, 7, 11, 3, 7, 1 }, new Options { Height = 4 }, @"
11.00 ┤ ╭╮
7.75 ┤ ╭─╯│╭╮
4.50 ┼╮ ╭╮│ ╰╯│
1.25 ┤╰─╯││ ╰
-2.00 ┤ ╰╯"
},
new object[]
{
new[] { 0.453, 0.141, 0.951, 0.251, 0.223, 0.581, 0.771, 0.191, 0.393, 0.617, 0.478 }, new Options { Height = 8 }, @"
0.95 ┤ ╭╮
0.85 ┤ ││ ╭╮
0.75 ┤ ││ ││
0.65 ┤ ││ ╭╯│ ╭╮
0.55 ┤ ││ │ │ │╰
0.44 ┼╮││ │ │╭╯
0.34 ┤│││ │ ││
0.24 ┤││╰─╯ ╰╯
0.14 ┤╰╯"
},
new object[]
{
new[] { 0.01, 0.004, 0.003, 0.0042, 0.0083, 0.0033, 0.0079 }, new Options { AxisLabelFormat = "0.000", Height = 7 }, @"
0.010 ┼╮
0.009 ┤│
0.008 ┤│ ╭╮╭
0.007 ┤│ │││
0.006 ┤│ │││
0.005 ┤│ │││
0.004 ┤╰╮╭╯││
0.003 ┤ ╰╯ ╰╯"
},
new object[]
{
new double[] { 192, 431, 112, 449, -122, 375, 782, 123, 911, 1711, 172 }, new Options { AxisLabelFormat = "0", Height = 10 }, @"
1711 ┤ ╭╮
1528 ┤ ││
1344 ┤ ││
1161 ┤ ││
978 ┤ ╭╯│
795 ┤ ╭╮│ │
611 ┤ │││ │
428 ┤╭╮╭╮╭╯││ │
245 ┼╯╰╯││ ╰╯ ╰
61 ┤ ││
-122 ┤ ╰╯"
},
new object[]
{
new[]
{
0, 0, 0, 0, 1.5, 0, 0, -0.5, 9, -3, 0, 0, 1, 2, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1.5, 0, 0, -0.5, 8, -3, 0, 0, 1, 2, 1, 0, 0, 0, 0,
0, 0, 0, 0, 1.5, 0, 0, -0.5, 10, -3, 0, 0, 1, 2, 1, 0, 0, 0, 0
},
new Options { AxisLabelRightMargin = 4, Height = 10 },
@"
10.00 ┤ ╭╮
8.70 ┤ ╭╮ ││
7.40 ┤ ││ ╭╮ ││
6.10 ┤ ││ ││ ││
4.80 ┤ ││ ││ ││
3.50 ┤ ││ ││ ││
2.20 ┤ ││ ╭╮ ││ ╭╮ ││ ╭╮
0.90 ┤ ╭╮ ││ ╭╯╰╮ ╭╮ ││ ╭╯╰╮ ╭╮ ││ ╭╯╰╮
-0.40 ┼───╯╰──╯│╭─╯ ╰───────╯╰──╯│╭─╯ ╰───────╯╰──╯│╭─╯ ╰───
-1.70 ┤ ││ ││ ││
-3.00 ┤ ╰╯ ╰╯ ╰╯"
},
new object[]
{
new double[] { -5, -2, -3, -4, 0, -5, -6, -7, -8, 0, -9, -3, -5, -2, -9, -3, -1 }, null, @"
0.00 ┤ ╭╮ ╭╮
-1.00 ┤ ││ ││ ╭
-2.00 ┤╭╮ ││ ││ ╭╮ │
-3.00 ┤│╰╮││ ││╭╮││╭╯
-4.00 ┤│ ╰╯│ │││││││
-5.00 ┼╯ ╰╮ │││╰╯││
-6.00 ┤ ╰╮ │││ ││
-7.00 ┤ ╰╮│││ ││
-8.00 ┤ ╰╯││ ││
-9.00 ┤ ╰╯ ╰╯"
},
new object[]
{
new[]
{
57.76, 54.04, 56.31, 57.02, 59.5, 52.63, 52.97, 56.44, 56.75, 52.96, 55.54, 55.09, 58.22, 56.85, 60.61, 59.62, 59.73, 59.93, 56.3, 54.69, 55.32, 54.03, 50.98, 50.48, 54.55, 47.49,
55.3, 46.74, 46, 45.8, 49.6, 48.83, 47.64, 46.61, 54.72, 42.77, 50.3, 42.79, 41.84, 44.19, 43.36, 45.62, 45.09, 44.95, 50.36, 47.21, 47.77, 52.04, 47.46, 44.19, 47.22, 45.55,
40.65, 39.64, 37.26, 40.71, 42.15, 36.45, 39.14, 36.62
},
new Options { Height = 24 },
@"
60.61 ┤ ╭╮ ╭╮
59.60 ┤ ╭╮ │╰─╯│
58.60 ┤ ││ ╭╮│ │
57.59 ┼╮ ╭╯│ │││ │
56.58 ┤│╭╯ │ ╭─╮ │╰╯ ╰╮
55.58 ┤││ │ │ │╭─╯ │╭╮ ╭╮
54.57 ┤╰╯ │ │ ││ ╰╯╰╮ ╭╮││ ╭╮
53.56 ┤ │╭╯ ╰╯ │ ││││ ││
52.56 ┤ ╰╯ │ ││││ ││ ╭╮
51.55 ┤ ╰╮││││ ││ ││
50.54 ┤ ╰╯│││ ││╭╮ ╭╮ ││
49.54 ┤ │││ ╭─╮ ││││ ││ ││
48.53 ┤ │││ │ │ ││││ ││ ││
47.52 ┤ ╰╯│ │ ╰╮││││ │╰─╯╰╮╭╮
46.52 ┤ ╰─╮│ ╰╯│││ │ │││
45.51 ┤ ╰╯ │││ ╭──╯ ││╰╮
44.50 ┤ │││ ╭╮│ ╰╯ │
43.50 ┤ ││╰╮│╰╯ │
42.49 ┤ ╰╯ ╰╯ │ ╭╮
41.48 ┤ │ ││
40.48 ┤ ╰╮ ╭╯│
39.47 ┤ ╰╮│ │╭╮
38.46 ┤ ││ │││
37.46 ┤ ╰╯ │││
36.45 ┤ ╰╯╰"
},
new object[] { new[] { 1, 1, double.NaN, 1, 1 }, null, @" 1.00 ┼─╴╶─ " },
new object[] { new[] { double.NaN, 1 }, null, @" 1.00 ┤╶ " },
new object[]
{
new[] { 0, 0, 1, 1, double.NaN, double.NaN, 3, 3, 4 }, null, @"
4.00 ┤ ╭
3.00 ┤ ╶─╯
2.00 ┤
1.00 ┤ ╭─╴
0.00 ┼─╯"
},
new object[]
{
new[] { 0.1, 0.2, 0.3, double.NaN, 0.5, 0.6, 0.7, double.NaN, double.NaN, 0.9, 1 }, new Options { Height = 9 }, @"
1.00 ┤ ╭
0.90 ┤ ╶╯
0.80 ┤
0.70 ┤ ╭╴
0.60 ┤ ╭╯
0.50 ┤ ╶╯
0.40 ┤
0.30 ┤ ╭╴
0.20 ┤╭╯
0.10 ┼╯"
}
};

[Test]
[TestCaseSource(nameof(MultiCases))]
public void TestPlotMulti(double[][] series, Options opts, string expected)
{
var actual = AsciiChart.Plot(series, opts);
Assert.AreEqual(Normalize(expected), Normalize(actual));
}

static object[][] MultiCases =
{
new object[]
{
new[] { new double[] { 0 }, new double[] { 1 }, new double[] { 2 } }, null, @"
2.00 ┼
1.00 ┼
0.00 ┼"
},
new object[]
{
new[] { new[] { 0, 0, 2, 2, double.NaN }, new double[] { 1, 1, 1, 1, 1, 1, 1 }, new[] { double.NaN, double.NaN, double.NaN, 0, 0, 2, 2 } }, null, @"
2.00 ┤ ╭─╴╭─
1.00 ┼────│─
0.00 ┼─╯╶─╯"
},
new object[]
{
new[] { new double[] { 0, 0, 0 }, new[] { double.NaN, 0, 0 }, new[] { double.NaN, double.NaN, 0 } }, null, " 0.00 ┼╶╶ "
}
};

static string Normalize(string text) => _normalize.Replace(text.Trim('\r', '\n') + Environment.NewLine, Environment.NewLine);
}
}
6 changes: 6 additions & 0 deletions AsciiChart.Sharp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AsciiChart.Sharp", "AsciiCh
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsciiChart.Sharp.TestApp", "AsciiChart.Sharp.TestApp\AsciiChart.Sharp.TestApp.csproj", "{F0FE0917-C3FF-4B1D-9143-43850116EDFD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsciiChart.Sharp.Tests", "AsciiChart.Sharp.Tests\AsciiChart.Sharp.Tests.csproj", "{D4D2802B-1207-43AA-8678-4F489A0BE698}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand All @@ -21,6 +23,10 @@ Global
{F0FE0917-C3FF-4B1D-9143-43850116EDFD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F0FE0917-C3FF-4B1D-9143-43850116EDFD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F0FE0917-C3FF-4B1D-9143-43850116EDFD}.Release|Any CPU.Build.0 = Release|Any CPU
{D4D2802B-1207-43AA-8678-4F489A0BE698}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4D2802B-1207-43AA-8678-4F489A0BE698}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4D2802B-1207-43AA-8678-4F489A0BE698}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4D2802B-1207-43AA-8678-4F489A0BE698}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Loading