Added document generation
@@ -0,0 +1,42 @@
|
||||
using System.Text;
|
||||
|
||||
namespace CLI.Monitor;
|
||||
|
||||
public class CompactCliTaskMonitor : TaskMonitor
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public CompactCliTaskMonitor(IEnumerable<(string? Name, Task Task)> tasks) : base(tasks) { }
|
||||
|
||||
/// <inheritdoc />
|
||||
public CompactCliTaskMonitor(IEnumerable<Task> tasks) : base(tasks) { }
|
||||
|
||||
#region Overrides of TaskMonitor
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void OnUpdate(ICollection<(string? Name, Task Task)> tasks)
|
||||
{
|
||||
int completed = 0;
|
||||
int total = tasks.Count;
|
||||
|
||||
var sb = new StringBuilder(total * 30);
|
||||
|
||||
foreach (var (_, task) in tasks)
|
||||
{
|
||||
var status = task.Status;
|
||||
|
||||
if (status > TaskStatus.WaitingForChildrenToComplete)
|
||||
{
|
||||
completed++;
|
||||
}
|
||||
|
||||
sb.Append(task.Exception is not null ? 'X' : StatusMap[status].First());
|
||||
}
|
||||
|
||||
sb.AppendLine($" ({completed}/{total - 1})");
|
||||
|
||||
Console.Clear();
|
||||
Console.Write(sb.ToString());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -2,5 +2,7 @@
|
||||
|
||||
public interface ITaskMonitor
|
||||
{
|
||||
Task Run();
|
||||
}
|
||||
TimeSpan Interval { get; init; }
|
||||
|
||||
Task Run();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,14 @@
|
||||
|
||||
public abstract class TaskMonitor : ITaskMonitor
|
||||
{
|
||||
protected static IReadOnlyDictionary<TaskStatus, string> StatusMap { get; } =
|
||||
new Dictionary<TaskStatus, string>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public TimeSpan Interval { get; init; } = TimeSpan.FromSeconds(1);
|
||||
|
||||
private readonly ICollection<(string? Name, Task Task)> _tasks;
|
||||
|
||||
protected static IReadOnlyDictionary<TaskStatus, string> StatusMap { get; } =
|
||||
new Dictionary<TaskStatus, string>
|
||||
{
|
||||
{ TaskStatus.RanToCompletion, "DONE" },
|
||||
{ TaskStatus.Faulted, "FAULT" },
|
||||
{ TaskStatus.Canceled, "CANCL" },
|
||||
@@ -13,27 +18,25 @@ public abstract class TaskMonitor : ITaskMonitor
|
||||
{ TaskStatus.WaitingForActivation, "WAIT" },
|
||||
{ TaskStatus.Running, "RUN" },
|
||||
{ TaskStatus.WaitingForChildrenToComplete, "RUN" },
|
||||
};
|
||||
};
|
||||
|
||||
private readonly ICollection<(string? Name, Task Task)> _tasks;
|
||||
protected TaskMonitor(IEnumerable<(string? Name, Task Task)> tasks) => _tasks = tasks.ToArray();
|
||||
|
||||
protected TaskMonitor(IEnumerable<(string? Name, Task Task)> tasks) => _tasks = tasks.ToArray();
|
||||
protected TaskMonitor(IEnumerable<Task> tasks) :
|
||||
this(tasks.Select(t => (t.Id.ToString(), t))!)
|
||||
{ }
|
||||
|
||||
protected TaskMonitor(IEnumerable<Task> tasks) :
|
||||
this(tasks.Select(t => (t.Id.ToString(), t))!)
|
||||
{ }
|
||||
public Task Run()
|
||||
{
|
||||
var waitTask = Task.WhenAll(_tasks.Select(i => i.Task));
|
||||
|
||||
public Task Run()
|
||||
while (!waitTask.Wait(Interval))
|
||||
{
|
||||
var waitTask = Task.WhenAll(_tasks.Select(i => i.Task));
|
||||
|
||||
while (!waitTask.Wait(TimeSpan.FromSeconds(1)))
|
||||
{
|
||||
OnUpdate(_tasks);
|
||||
}
|
||||
|
||||
return waitTask;
|
||||
OnUpdate(_tasks);
|
||||
}
|
||||
|
||||
protected abstract void OnUpdate(ICollection<(string? Name, Task Task)> tasks);
|
||||
}
|
||||
return waitTask;
|
||||
}
|
||||
|
||||
protected abstract void OnUpdate(ICollection<(string? Name, Task Task)> tasks);
|
||||
}
|
||||
|
||||
@@ -58,8 +58,6 @@ internal class EvaluationProcessor
|
||||
/// <inheritdoc />
|
||||
public Task Process(MagickImage image) => Task.Run(async () =>
|
||||
{
|
||||
Directory.CreateDirectory(OutputFolder);
|
||||
|
||||
var words = MakeProcessor()
|
||||
.Process(new[] { image })
|
||||
.Select(r => r.Word)
|
||||
|
||||
@@ -11,13 +11,16 @@ public class Program
|
||||
{
|
||||
public Task Run(string[] args)
|
||||
{
|
||||
Directory.Delete("results", true);
|
||||
Directory.CreateDirectory("results");
|
||||
|
||||
var scans = (
|
||||
from processor in MakeThresholdVariations()
|
||||
from path in ExpandPaths(args)
|
||||
select (Key: path, Task: processor.Process(new MagickImage(path)))
|
||||
).ToArray();
|
||||
|
||||
return new CliTaskMonitor(scans).Run();
|
||||
return new CompactCliTaskMonitor(scans) { Interval = TimeSpan.FromMilliseconds(500) }.Run();
|
||||
}
|
||||
|
||||
[SuppressMessage("ReSharper", "ArrangeObjectCreationWhenTypeNotEvident")]
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator.Abstract;
|
||||
|
||||
public abstract class DocumentGeneratorBase : FileSerializableBase, IDocumentGenerator
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public abstract IDocumentGenerator AppendHeading(int level, string text);
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual IDocumentGenerator Append(string? text = default)
|
||||
{
|
||||
StringBuilder.Append(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual IDocumentGenerator AppendLine(string? text = default)
|
||||
{
|
||||
StringBuilder.AppendLine(text);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract IDocumentGenerator AppendParagraph(string? text = default);
|
||||
|
||||
/// <inheritdoc />
|
||||
public IDocumentGenerator AppendTable(int columns, Action<ITableGenerator> table)
|
||||
{
|
||||
var builder = AppendTable(columns);
|
||||
table(builder);
|
||||
return AppendLine(builder.ToString());
|
||||
}
|
||||
|
||||
protected abstract ITableGenerator AppendTable(int columns);
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract string FormatImage(string path, IBounds? bounds = default);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using System.Text;
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator.Abstract;
|
||||
|
||||
public abstract class FileSerializableBase : StringSerializableBase, IFileSerializable
|
||||
{
|
||||
public abstract string FileExtension { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public void ToFile(string path, Encoding? encoding = default) =>
|
||||
File.WriteAllText($"{path}.{FileExtension}", ToString(), encoding ?? Encoding.UTF8);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
using ReportGenerator.Generator.Interface;
|
||||
using System.Text;
|
||||
|
||||
namespace ReportGenerator.Generator.Abstract;
|
||||
|
||||
public abstract class StringSerializableBase : IStringSerializable
|
||||
{
|
||||
protected StringBuilder StringBuilder { get; } = new();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() => StringBuilder.ToString();
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator.Abstract;
|
||||
|
||||
public abstract class TableGeneratorBase : StringSerializableBase, ITableGenerator
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public int Columns { get; }
|
||||
|
||||
protected TableGeneratorBase(int columns)
|
||||
{
|
||||
Columns = columns;
|
||||
}
|
||||
|
||||
#region Header
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual ITableGenerator AppendHeader(string content) =>
|
||||
AppendHeader(Enumerable.Range(0, Columns).Select(_ => content));
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract ITableGenerator AppendHeader(IEnumerable<string> row);
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual ITableGenerator AppendHeader(IEnumerable<IEnumerable<string>> rows)
|
||||
{
|
||||
foreach (var row in rows)
|
||||
{
|
||||
AppendHeader(row);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Row
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual ITableGenerator AppendRow(string content) =>
|
||||
AppendRow(Enumerable.Range(0, Columns).Select(_ => content));
|
||||
|
||||
/// <inheritdoc />
|
||||
public abstract ITableGenerator AppendRow(IEnumerable<string> row);
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual ITableGenerator AppendRows(IEnumerable<IEnumerable<string>> rows)
|
||||
{
|
||||
foreach (var row in rows)
|
||||
{
|
||||
AppendRow(row);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using ReportGenerator.Generator.Abstract;
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator.Generator;
|
||||
|
||||
public class HtmlDocumentGenerator : DocumentGeneratorBase
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string FileExtension => "html";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IDocumentGenerator AppendParagraph(string? text = default) =>
|
||||
AppendLine($"<p>{text}</p>");
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override ITableGenerator AppendTable(int columns) =>
|
||||
new HtmlTableGenerator(columns);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IDocumentGenerator AppendHeading(int level, string text) =>
|
||||
AppendLine($"<h{level}>{text}</h{level}>");
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string FormatImage(string path, IBounds? bounds = default) =>
|
||||
HtmlTools.FormatImage(path, bounds);
|
||||
|
||||
#region Overrides of StringSerializableBase
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() =>
|
||||
HtmlTools.Wrap("html", GetHead() + HtmlTools.Wrap("body", base.ToString()));
|
||||
|
||||
#endregion
|
||||
|
||||
private static string GetHead() =>
|
||||
HtmlTools.Wrap(
|
||||
"head",
|
||||
$"<meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">{GetStyle()}"
|
||||
);
|
||||
|
||||
private static string GetStyle() =>
|
||||
HtmlTools.Wrap("style",
|
||||
"html,body{width:100%;height:100%;overflow:scroll;} td,th{border:1px solid #777;padding:.5rem;text-align:center}table{border-collapse:collapse}tbody tr:nth-child(odd){background:#eee}caption{font-size:.8rem}"
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
using ReportGenerator.Generator.Abstract;
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator.Generator;
|
||||
|
||||
internal class HtmlTableGenerator : TableGeneratorBase
|
||||
{
|
||||
public (string start, string end) RowFormat { get; init; } = ("<tr>", "</tr>");
|
||||
public (string start, string end) HeaderFormat { get; init; } = ("<th>", "</th>");
|
||||
public (string start, string end) ColumnFormat { get; init; } = ("<td>", "</td>");
|
||||
|
||||
/// <inheritdoc />
|
||||
public HtmlTableGenerator(int columns) : base(columns) { }
|
||||
|
||||
#region Overrides of TableGeneratorBase
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ITableGenerator AppendHeader(IEnumerable<string> row) => AppendRow(row, RowFormat, HeaderFormat);
|
||||
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ITableGenerator AppendRow(IEnumerable<string> row) => AppendRow(row, RowFormat, ColumnFormat);
|
||||
|
||||
private ITableGenerator AppendRow(
|
||||
IEnumerable<string> row,
|
||||
(string, string) rowFormat,
|
||||
(string, string) columnFormat
|
||||
)
|
||||
{
|
||||
var (rowStart, rowEnd) = rowFormat;
|
||||
var (colStart, colEnd) = columnFormat;
|
||||
|
||||
StringBuilder
|
||||
.Append(rowStart)
|
||||
.Append(colStart)
|
||||
.AppendLine(string.Join(colEnd + colStart, row))
|
||||
.Append(colEnd)
|
||||
.Append(rowEnd);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() => "<table>" + base.ToString() + "</table>";
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
using ReportGenerator.Generator.Abstract;
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator.Generator;
|
||||
|
||||
public class MarkdownDocumentGenerator : DocumentGeneratorBase
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override string FileExtension => "md";
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IDocumentGenerator AppendHeading(int level, string text) =>
|
||||
AppendParagraph(new string('#', level) + ' ' + text);
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override ITableGenerator AppendTable(int columns) =>
|
||||
new MarkdownTableGenerator(columns);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override IDocumentGenerator AppendParagraph(string? text = default)
|
||||
{
|
||||
AppendLine(text);
|
||||
AppendLine();
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string FormatImage(string path, IBounds? bounds = default) =>
|
||||
HtmlTools.FormatImage(path, bounds);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using ReportGenerator.Generator.Abstract;
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator.Generator;
|
||||
|
||||
internal class MarkdownTableGenerator : TableGeneratorBase
|
||||
{
|
||||
public string ColumnSeparator { get; init; } = " | ";
|
||||
|
||||
/// <inheritdoc />
|
||||
internal MarkdownTableGenerator(int columns) : base(columns) { }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ITableGenerator AppendHeader(IEnumerable<string> row) => AppendRow(row).AppendRow("---");
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ITableGenerator AppendRow(IEnumerable<string> row)
|
||||
{
|
||||
StringBuilder.AppendLine(ColumnSeparator + string.Join(" | ", row) + ColumnSeparator);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator;
|
||||
|
||||
internal static class HtmlTools
|
||||
{
|
||||
public static string Wrap(string tag, string content) => $"<{tag}>{content}</{tag}>";
|
||||
|
||||
public static string FormatImage(string path, IBounds? bounds = default)
|
||||
{
|
||||
var style = bounds is null
|
||||
? string.Empty
|
||||
: GetCssStyle(bounds);
|
||||
|
||||
path += path.EndsWith(".png") ? string.Empty : ".png";
|
||||
|
||||
return $"<img src=\"{path}\" style=\"{style}\" />";
|
||||
}
|
||||
|
||||
private static string GetCssStyle(IBounds bounds)
|
||||
{
|
||||
var style = string.Empty;
|
||||
|
||||
// Width
|
||||
if (bounds.Width.HasValue)
|
||||
{
|
||||
style += $"width:{bounds.Width}{bounds.Unit};";
|
||||
}
|
||||
|
||||
if (bounds.MinWidth.HasValue)
|
||||
{
|
||||
style += $"min-width:{bounds.MinWidth}{bounds.Unit};";
|
||||
}
|
||||
|
||||
if (bounds.MaxWidth.HasValue)
|
||||
{
|
||||
style += $"max-width:{bounds.MaxWidth}{bounds.Unit};";
|
||||
}
|
||||
|
||||
// Height
|
||||
if (bounds.Height.HasValue)
|
||||
{
|
||||
style += $"height:{bounds.Height}{bounds.Unit};";
|
||||
}
|
||||
|
||||
if (bounds.MinHeight.HasValue)
|
||||
{
|
||||
style += $"min-height:{bounds.MinHeight}{bounds.Unit};";
|
||||
}
|
||||
|
||||
if (bounds.MaxHeight.HasValue)
|
||||
{
|
||||
style += $"max-height:{bounds.MaxHeight}{bounds.Unit};";
|
||||
}
|
||||
|
||||
return style;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace ReportGenerator.Generator.Interface;
|
||||
|
||||
public interface IBounds
|
||||
{
|
||||
public string Unit { get; }
|
||||
public int? MinWidth { get; }
|
||||
public int? MinHeight { get; }
|
||||
public int? MaxWidth { get; }
|
||||
public int? MaxHeight { get; }
|
||||
public int? Width { get; }
|
||||
public int? Height { get; }
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace ReportGenerator.Generator.Interface;
|
||||
|
||||
public interface IDocumentGenerator : IFileSerializable
|
||||
{
|
||||
IDocumentGenerator Append(string? text = default);
|
||||
IDocumentGenerator AppendLine(string? text = default);
|
||||
IDocumentGenerator AppendParagraph(string? text = default);
|
||||
|
||||
IDocumentGenerator AppendHeading(int level, string text);
|
||||
|
||||
IDocumentGenerator AppendTable(int columns, Action<ITableGenerator> table);
|
||||
|
||||
string FormatImage(string path, IBounds? bounds = default);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
using System.Text;
|
||||
|
||||
namespace ReportGenerator.Generator.Interface;
|
||||
|
||||
public interface IFileSerializable : IStringSerializable
|
||||
{
|
||||
public string FileExtension { get; }
|
||||
|
||||
void ToFile(string path, Encoding? encoding = default);
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace ReportGenerator.Generator.Interface;
|
||||
|
||||
public interface IStringSerializable
|
||||
{
|
||||
string ToString();
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
namespace ReportGenerator.Generator.Interface;
|
||||
|
||||
public interface ITableGenerator : IStringSerializable
|
||||
{
|
||||
int Columns { get; }
|
||||
|
||||
ITableGenerator AppendHeader(string content);
|
||||
ITableGenerator AppendHeader(IEnumerable<string> row);
|
||||
ITableGenerator AppendHeader(IEnumerable<IEnumerable<string>> rows);
|
||||
|
||||
ITableGenerator AppendRow(string content);
|
||||
ITableGenerator AppendRow(IEnumerable<string> row);
|
||||
ITableGenerator AppendRows(IEnumerable<IEnumerable<string>> rows);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using ReportGenerator.Generator.Interface;
|
||||
|
||||
namespace ReportGenerator.Generator.Model;
|
||||
|
||||
public struct Bounds : IBounds
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public string Unit => "px";
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? MinWidth { get; set; } = null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? MinHeight { get; set; } = null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? MaxWidth { get; set; } = null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? MaxHeight { get; set; } = null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? Width { get; set; } = null;
|
||||
|
||||
/// <inheritdoc />
|
||||
public int? Height { get; set; } = null;
|
||||
|
||||
public Bounds() { }
|
||||
|
||||
public Bounds(int? size)
|
||||
{
|
||||
Width = size;
|
||||
Height = size;
|
||||
}
|
||||
|
||||
public Bounds(int? min, int? max, int? size = null) : this(size)
|
||||
{
|
||||
MinWidth = min;
|
||||
MinHeight = min;
|
||||
|
||||
MaxWidth = max;
|
||||
MaxHeight = max;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using ReportGenerator.Models;
|
||||
using ReportGenerator.Generator.Generator;
|
||||
using ReportGenerator.Models;
|
||||
|
||||
namespace ReportGenerator;
|
||||
|
||||
@@ -16,13 +17,12 @@ internal static class Program
|
||||
|
||||
Console.WriteLine("Generating report");
|
||||
var scans = Scan(tagFileInfos, scanFileInfos);
|
||||
var report = ReportGenerator
|
||||
.FromData(scans)
|
||||
|
||||
new ReportGenerator(scans, new HtmlDocumentGenerator())
|
||||
.WithTitle("OCR Report")
|
||||
.WithBestOf("Best of")
|
||||
.WithFullStatistic("Statistic");
|
||||
|
||||
report.ToFile("Report.md");
|
||||
.WithFullStatistic("Statistic")
|
||||
.ToFile("report");
|
||||
|
||||
Console.WriteLine("Completed");
|
||||
}
|
||||
|
||||
@@ -1,74 +1,77 @@
|
||||
using Common.Extensions;
|
||||
using ReportGenerator.Generator.Abstract;
|
||||
using ReportGenerator.Generator.Interface;
|
||||
using ReportGenerator.Generator.Model;
|
||||
using ReportGenerator.Models;
|
||||
using System.Text;
|
||||
|
||||
namespace ReportGenerator;
|
||||
|
||||
public class ReportGenerator
|
||||
public class ReportGenerator : FileSerializableBase
|
||||
{
|
||||
private IDocumentGenerator Document { get; }
|
||||
private ICollection<ImageStats> Images { get; }
|
||||
|
||||
private readonly StringBuilder _sb = new();
|
||||
|
||||
private ReportGenerator(IEnumerable<ImageStats> stats) => Images = stats.ToArray();
|
||||
|
||||
public void ToFile(string path) =>
|
||||
File.WriteAllText(path, ToString(), Encoding.UTF8);
|
||||
public ReportGenerator(IEnumerable<ImageStats> stats, IDocumentGenerator document)
|
||||
{
|
||||
Images = stats.ToArray();
|
||||
Document = document;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string ToString() =>
|
||||
_sb.ToString();
|
||||
public override string ToString() => Document.ToString();
|
||||
|
||||
#region Fluent definition
|
||||
|
||||
public ReportGenerator WithTitle(string text)
|
||||
{
|
||||
_sb.AppendHeading(1, text);
|
||||
Document.AppendHeading(1, text);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ReportGenerator WithFullStatistic(string title)
|
||||
{
|
||||
_sb.AppendHeading(2, title);
|
||||
Document.AppendHeading(2, title);
|
||||
|
||||
foreach (var stat in Images)
|
||||
{
|
||||
_sb.AppendHeading(3, stat.ImageName);
|
||||
_sb.AppendParagraph(HtmlImage(Path.Combine("img", stat.ImageName), 350, 350));
|
||||
Document
|
||||
.AppendHeading(3, stat.ImageName)
|
||||
.AppendParagraph(
|
||||
Document.FormatImage(Path.Combine("img", stat.ImageName), new Bounds(0, 350))
|
||||
)
|
||||
.AppendTable(
|
||||
stat.Reference.Count + 5,
|
||||
table =>
|
||||
{
|
||||
table.AppendHeader(stat
|
||||
.Reference
|
||||
.Prepend("Image")
|
||||
.Prepend("CER (avg)")
|
||||
.Prepend("WER")
|
||||
.Prepend("Elapsed")
|
||||
.Prepend("Processor")
|
||||
);
|
||||
|
||||
AppendRow(stat
|
||||
.Reference
|
||||
.Prepend("Image")
|
||||
.Prepend("CER (avg)")
|
||||
.Prepend("WER")
|
||||
.Prepend("Elapsed")
|
||||
.Prepend("Processor")
|
||||
);
|
||||
var processors = stat.Processors
|
||||
.OrderBy(s => s.Distance)
|
||||
.ThenBy(s => s.ProcessingTime);
|
||||
|
||||
AppendRowSeparator(stat.Reference.Count + 5);
|
||||
foreach (var processor in processors)
|
||||
{
|
||||
var imgPath = Path.Combine("results", $"{processor.Name}.00.{stat.ImageName}.png");
|
||||
|
||||
var processors = stat.Processors
|
||||
.OrderBy(s => s.Distance)
|
||||
.ThenBy(s => s.ProcessingTime);
|
||||
|
||||
foreach (var processor in processors)
|
||||
{
|
||||
var imgPath = Path.Combine("results", $"{processor.Name}.00.{stat.ImageName}.png");
|
||||
|
||||
AppendRow(processor.Words
|
||||
.Select(s => s.ToString() ?? string.Empty)
|
||||
.Prepend(HtmlImage(imgPath, 150, 150))
|
||||
.Prepend(processor.Words.Average(s => s.Distance).ToString("F2"))
|
||||
.Prepend($"{processor.Distance * 100:F1}%")
|
||||
.Prepend($"{processor.ProcessingTime * 1000:F1}ms")
|
||||
.Prepend(processor.Name)
|
||||
table.AppendRow(processor.Words
|
||||
.Select(s => s.ToString() ?? string.Empty)
|
||||
.Prepend(Document.FormatImage(imgPath, new Bounds(0, 150)))
|
||||
.Prepend(processor.Words.Average(s => s.Distance).ToString("F2"))
|
||||
.Prepend($"{processor.Distance * 100:F1}%")
|
||||
.Prepend($"{processor.ProcessingTime * 1000:F1}ms")
|
||||
.Prepend(processor.Name)
|
||||
);
|
||||
}
|
||||
})
|
||||
.AppendParagraph(
|
||||
$"*Comparison data generated based on {stat.Reference.Count} tagged words.*"
|
||||
);
|
||||
}
|
||||
|
||||
_sb.AppendLine();
|
||||
_sb.AppendParagraph(
|
||||
$"*Comparison data generated based on {stat.Reference.Count} tagged words.*"
|
||||
);
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -77,7 +80,7 @@ public class ReportGenerator
|
||||
|
||||
public ReportGenerator WithBestOf(string title, int context = 5)
|
||||
{
|
||||
_sb.AppendHeading(2, title);
|
||||
Document.AppendHeading(2, title);
|
||||
|
||||
var lookup = Images
|
||||
.SelectMany(s => s.Processors)
|
||||
@@ -107,7 +110,7 @@ public class ReportGenerator
|
||||
|
||||
void AppendComparison(
|
||||
int level,
|
||||
string tableTitle,
|
||||
string title,
|
||||
IEnumerable<(string, double)> values,
|
||||
string valueUnit = ""
|
||||
)
|
||||
@@ -115,60 +118,32 @@ public class ReportGenerator
|
||||
var tValues = values.ToArray();
|
||||
var tContext = Math.Min(tValues.Length / 2, context);
|
||||
|
||||
_sb.AppendHeading(level, tableTitle);
|
||||
|
||||
AppendRow(new[] { "Processor", "Average" });
|
||||
AppendRowSeparator(2);
|
||||
AppendRows(tValues.Take(tContext).Select(v => new[]
|
||||
{
|
||||
v.Item1,
|
||||
v.Item2.ToString("F2") + valueUnit
|
||||
}));
|
||||
AppendRowSeparator(2, "...");
|
||||
AppendRows(tValues.TakeLast(tContext).Select(v => new[]
|
||||
{
|
||||
v.Item1,
|
||||
v.Item2.ToString("F2") + valueUnit
|
||||
}));
|
||||
Document
|
||||
.AppendHeading(level, title)
|
||||
.AppendTable(2, table => table
|
||||
.AppendHeader(new[] { "Processor", "Average" })
|
||||
.AppendRows(tValues
|
||||
.Take(tContext).Select(v => new[]
|
||||
{
|
||||
v.Item1,
|
||||
v.Item2.ToString("F2") + valueUnit
|
||||
}))
|
||||
.AppendRow("...")
|
||||
.AppendRows(tValues.TakeLast(tContext).Select(v => new[]
|
||||
{
|
||||
v.Item1,
|
||||
v.Item2.ToString("F2") + valueUnit
|
||||
}))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helpers
|
||||
#region Overrides of FileSerializableBase
|
||||
|
||||
private void AppendRow(IEnumerable<string> row)
|
||||
{
|
||||
const string separator = " | ";
|
||||
_sb.AppendLine(separator + string.Join(" | ", row) + separator);
|
||||
}
|
||||
|
||||
private void AppendRows(IEnumerable<IEnumerable<string>> rows)
|
||||
{
|
||||
foreach (var row in rows)
|
||||
{
|
||||
AppendRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
private static string HtmlImage(string path, int maxWidth, int maxHeight)
|
||||
{
|
||||
if (!path.EndsWith(".png"))
|
||||
{
|
||||
path += ".png";
|
||||
}
|
||||
|
||||
return $"<img src=\"{path}\" style=\"max-width:{maxWidth}px;max-height:{maxHeight}px;\" />";
|
||||
}
|
||||
|
||||
private void AppendRowSeparator(int columns, string content = "---") =>
|
||||
AppendRow(Enumerable.Range(0, columns).Select(_ => content));
|
||||
/// <inheritdoc />
|
||||
public override string FileExtension => Document.FileExtension;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Factory Methods
|
||||
|
||||
public static ReportGenerator FromData(IEnumerable<ImageStats> stats) => new(stats);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"words": [
|
||||
"S7-300",
|
||||
"datenbausteinkonfiguration",
|
||||
"einstellungen",
|
||||
"ok",
|
||||
"abbrechen",
|
||||
"name",
|
||||
"seriell",
|
||||
"ohne",
|
||||
"id",
|
||||
"datenbaustein",
|
||||
"0",
|
||||
"offset",
|
||||
"frei",
|
||||
"archiv kennung",
|
||||
"SO",
|
||||
"produkt ID",
|
||||
"spaltenorientiert",
|
||||
"seriell",
|
||||
"schreibstatus",
|
||||
"ok",
|
||||
"abbrechen",
|
||||
"datensatz",
|
||||
"wert",
|
||||
"datentyp",
|
||||
"stelle",
|
||||
"1",
|
||||
"doppelwort",
|
||||
"neuer",
|
||||
"wert",
|
||||
"löschen",
|
||||
"neue"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"words": [
|
||||
"SEL",
|
||||
"enter",
|
||||
"an",
|
||||
"integer",
|
||||
"between",
|
||||
"100",
|
||||
"and",
|
||||
"180000",
|
||||
"ok"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"words": [
|
||||
"variablendefinition",
|
||||
"selektieren",
|
||||
"sie",
|
||||
"das",
|
||||
"gewünschte",
|
||||
"objekt",
|
||||
"verlassen",
|
||||
"hilfe",
|
||||
"neu",
|
||||
"konfiguration",
|
||||
"archive",
|
||||
"float",
|
||||
"treibervariable",
|
||||
"bit",
|
||||
"byt",
|
||||
"wort",
|
||||
"doppelwort",
|
||||
"float",
|
||||
"string"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.3 KiB |
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"words": [
|
||||
"new",
|
||||
"opc",
|
||||
"tag",
|
||||
"declaration",
|
||||
"a",
|
||||
"new",
|
||||
"tag",
|
||||
"file",
|
||||
"filename",
|
||||
"newOpcTag.opct",
|
||||
"description",
|
||||
"back",
|
||||
"finish",
|
||||
"cancel",
|
||||
"help"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"words": [
|
||||
"select",
|
||||
"a",
|
||||
"connection",
|
||||
"connections",
|
||||
"(1)",
|
||||
"D445",
|
||||
"filter",
|
||||
"all",
|
||||
"variables",
|
||||
"only",
|
||||
"new",
|
||||
"existing",
|
||||
"variable",
|
||||
"import",
|
||||
"set",
|
||||
"resources",
|
||||
"label",
|
||||
"ok",
|
||||
"cancel"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 4.7 KiB |
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"words": [
|
||||
"define",
|
||||
"physical",
|
||||
"monitor",
|
||||
"name",
|
||||
"MM",
|
||||
"001",
|
||||
"position",
|
||||
"alternative",
|
||||
"for",
|
||||
"undedactable",
|
||||
"M",
|
||||
"000",
|
||||
"top",
|
||||
"left",
|
||||
"right",
|
||||
"bottom",
|
||||
"0",
|
||||
"1920",
|
||||
"3840",
|
||||
"1080",
|
||||
"options",
|
||||
"display",
|
||||
"in",
|
||||
"the",
|
||||
"online",
|
||||
"menu",
|
||||
"ok",
|
||||
"cancel",
|
||||
"help"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"words": [
|
||||
"filter",
|
||||
"profiles",
|
||||
"savve",
|
||||
"import",
|
||||
"trend",
|
||||
"WIZ10",
|
||||
"curve",
|
||||
"name",
|
||||
"WIZ_VAR_10",
|
||||
"WIZ_VAR_11",
|
||||
"WIZ_VAR_12",
|
||||
"filter",
|
||||
"text",
|
||||
"export",
|
||||
"delete",
|
||||
"play",
|
||||
"stop",
|
||||
"continue",
|
||||
"refresh",
|
||||
"zoom",
|
||||
"rezoom",
|
||||
"cursor",
|
||||
"on",
|
||||
"off",
|
||||
"copy",
|
||||
"to",
|
||||
"clipboard",
|
||||
"diagram",
|
||||
"settings",
|
||||
"print",
|
||||
"axis",
|
||||
"active",
|
||||
"color",
|
||||
"title"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"words": [
|
||||
"function",
|
||||
"wizard",
|
||||
"settings",
|
||||
"syntax",
|
||||
"alarm",
|
||||
"archive",
|
||||
"archiveex",
|
||||
"archivexr",
|
||||
"archivem",
|
||||
"archivemr",
|
||||
"archivemsp",
|
||||
"archivemspr",
|
||||
"archiver",
|
||||
"archivesp",
|
||||
"parameter",
|
||||
"options",
|
||||
"ok",
|
||||
"cancel",
|
||||
"help"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,52 @@
|
||||
{
|
||||
"words": [
|
||||
"reportassistant",
|
||||
"data",
|
||||
"report",
|
||||
"rdl",
|
||||
"tools",
|
||||
"data",
|
||||
"projects",
|
||||
"ZAD_CIP",
|
||||
"ZAD_GBL",
|
||||
"OEEFactor",
|
||||
"OEEFactor",
|
||||
"batchhistory",
|
||||
"DPA",
|
||||
"single",
|
||||
"alarms",
|
||||
"most",
|
||||
"frequent",
|
||||
"equipment",
|
||||
"related",
|
||||
"group",
|
||||
"consumption",
|
||||
"relative",
|
||||
"per",
|
||||
"medium",
|
||||
"group",
|
||||
"abs",
|
||||
"development",
|
||||
"costs",
|
||||
"absolute",
|
||||
"ZAD_MAIN",
|
||||
"filter",
|
||||
"equipmentfilter",
|
||||
"datetimefilter",
|
||||
"string",
|
||||
"variables",
|
||||
"integer",
|
||||
"report1",
|
||||
"filter()",
|
||||
"equipmentfilter",
|
||||
"element",
|
||||
"properties",
|
||||
"model",
|
||||
"mnestinglevel",
|
||||
"misc",
|
||||
"name",
|
||||
"parameterlist",
|
||||
"collection",
|
||||
"type"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"words": [
|
||||
"service",
|
||||
"engine",
|
||||
"profiles",
|
||||
"action",
|
||||
"open",
|
||||
"administration",
|
||||
"dialog",
|
||||
"in",
|
||||
"the",
|
||||
"service",
|
||||
"engine",
|
||||
"load",
|
||||
"profile",
|
||||
"default",
|
||||
"last",
|
||||
"freely",
|
||||
"defined",
|
||||
"name",
|
||||
"name",
|
||||
"from",
|
||||
"variable",
|
||||
"linked",
|
||||
"no",
|
||||
"save",
|
||||
"profile",
|
||||
"ok",
|
||||
"cancel",
|
||||
"help"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"words": [
|
||||
"general",
|
||||
"redundancy",
|
||||
"advanced",
|
||||
"settings",
|
||||
"communication",
|
||||
"standard",
|
||||
"port",
|
||||
"event",
|
||||
"1200",
|
||||
"9000",
|
||||
"startup",
|
||||
"no",
|
||||
"start",
|
||||
"open",
|
||||
"this",
|
||||
"box",
|
||||
"cold",
|
||||
"start",
|
||||
"load",
|
||||
"retain",
|
||||
"variables",
|
||||
"hot",
|
||||
"restart",
|
||||
"stepping",
|
||||
"mode",
|
||||
"delay",
|
||||
"s",
|
||||
"0",
|
||||
"retain",
|
||||
"data",
|
||||
"storing",
|
||||
"path",
|
||||
"for",
|
||||
"retain",
|
||||
"data",
|
||||
"users",
|
||||
"public",
|
||||
"documents",
|
||||
"zenon_projects",
|
||||
"700",
|
||||
"test",
|
||||
"rt",
|
||||
"files",
|
||||
"store",
|
||||
"variables",
|
||||
"by",
|
||||
"name",
|
||||
"cyclically",
|
||||
"data",
|
||||
"real",
|
||||
"time",
|
||||
"priority",
|
||||
"ok",
|
||||
"cancel",
|
||||
"apply",
|
||||
"help"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"words": [
|
||||
"zoom",
|
||||
"steps",
|
||||
"existing",
|
||||
"zoom",
|
||||
"steps",
|
||||
"step",
|
||||
"to",
|
||||
"%",
|
||||
"0",
|
||||
"100",
|
||||
"new",
|
||||
"edit",
|
||||
"delete",
|
||||
"ok",
|
||||
"cancel",
|
||||
"help"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
@@ -0,0 +1,131 @@
|
||||
{
|
||||
"words": [
|
||||
"new",
|
||||
"report",
|
||||
"theme",
|
||||
"extended",
|
||||
"historian",
|
||||
"analysis",
|
||||
"the",
|
||||
"report",
|
||||
"templates",
|
||||
"of",
|
||||
"this",
|
||||
"theme",
|
||||
"perform",
|
||||
"aggregated",
|
||||
"and",
|
||||
"historian",
|
||||
"analysis",
|
||||
"and",
|
||||
"associate",
|
||||
"the",
|
||||
"historian",
|
||||
"data",
|
||||
"with",
|
||||
"price",
|
||||
"values",
|
||||
"production",
|
||||
"counters",
|
||||
"standard",
|
||||
"values",
|
||||
"and",
|
||||
"the",
|
||||
"equipment",
|
||||
"modeling",
|
||||
"there",
|
||||
"are",
|
||||
"two",
|
||||
"types",
|
||||
"of",
|
||||
"report",
|
||||
"templates",
|
||||
"of",
|
||||
"this",
|
||||
"theme",
|
||||
"those",
|
||||
"that",
|
||||
"create",
|
||||
"aggregated",
|
||||
"trend",
|
||||
"data",
|
||||
"and",
|
||||
"thos",
|
||||
"that",
|
||||
"create",
|
||||
"distribution",
|
||||
"data",
|
||||
"report",
|
||||
"template",
|
||||
"relative",
|
||||
"historian",
|
||||
"aggregation",
|
||||
"with",
|
||||
"equipment",
|
||||
"group",
|
||||
"and",
|
||||
"variable",
|
||||
"selection",
|
||||
"reports",
|
||||
"based",
|
||||
"on",
|
||||
"this",
|
||||
"template",
|
||||
"calcculate",
|
||||
"for",
|
||||
"1",
|
||||
"period",
|
||||
"variable",
|
||||
"filtering",
|
||||
"is",
|
||||
"based",
|
||||
"on",
|
||||
"equipment",
|
||||
"groups",
|
||||
"the",
|
||||
"data",
|
||||
"is",
|
||||
"shown",
|
||||
"in",
|
||||
"charts",
|
||||
"and",
|
||||
"tables",
|
||||
"preview",
|
||||
"new",
|
||||
"report",
|
||||
"relative",
|
||||
"historian",
|
||||
"aggregation",
|
||||
"with",
|
||||
"equipment",
|
||||
"group",
|
||||
"and",
|
||||
"variable",
|
||||
"selection",
|
||||
"from",
|
||||
"filler",
|
||||
"labeller",
|
||||
"packer",
|
||||
"ZAD_GBL",
|
||||
"ENERGY",
|
||||
"MACHINE",
|
||||
"CYCLIC",
|
||||
"DATA",
|
||||
"PM",
|
||||
"kwh",
|
||||
"variable",
|
||||
"name",
|
||||
"absolute",
|
||||
"consumption",
|
||||
"relative",
|
||||
"consumption",
|
||||
"zenon",
|
||||
"analyzer",
|
||||
"www",
|
||||
"copadata",
|
||||
"com",
|
||||
"page",
|
||||
"ok",
|
||||
"cancel"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"words": [
|
||||
"provider",
|
||||
"options",
|
||||
"microsoft",
|
||||
"ole",
|
||||
"db",
|
||||
"provider",
|
||||
"for",
|
||||
"adbc",
|
||||
"drivers",
|
||||
"select",
|
||||
"a",
|
||||
"page",
|
||||
"general",
|
||||
"script",
|
||||
"help",
|
||||
"provider",
|
||||
"options",
|
||||
"enable",
|
||||
"name",
|
||||
"dynamic",
|
||||
"parameter",
|
||||
"nested",
|
||||
"queries",
|
||||
"level",
|
||||
"zero",
|
||||
"only",
|
||||
"allow",
|
||||
"inprocess",
|
||||
"non",
|
||||
"transacted",
|
||||
"updates",
|
||||
"index",
|
||||
"ad",
|
||||
"access",
|
||||
"path",
|
||||
"disallow",
|
||||
"adhoc",
|
||||
"access",
|
||||
"supports",
|
||||
"like",
|
||||
"operator",
|
||||
"linked",
|
||||
"server",
|
||||
"using",
|
||||
"this",
|
||||
"provider",
|
||||
"my",
|
||||
"sql",
|
||||
"server",
|
||||
"these",
|
||||
"options",
|
||||
"are",
|
||||
"applied",
|
||||
"to",
|
||||
"all",
|
||||
"linked",
|
||||
"servers",
|
||||
"that",
|
||||
"use",
|
||||
"this",
|
||||
"provider",
|
||||
"ready",
|
||||
"ok",
|
||||
"cancel",
|
||||
"view",
|
||||
"connection",
|
||||
"properties",
|
||||
"connection",
|
||||
"server",
|
||||
"CDSBG036",
|
||||
"ZA2",
|
||||
"haraldr",
|
||||
"cd",
|
||||
"ok",
|
||||
"cancel"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 93 KiB |
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"words": [
|
||||
"scatter",
|
||||
"plot",
|
||||
"meanings",
|
||||
"horizontal",
|
||||
"indicator",
|
||||
"mea",
|
||||
"horizontalindicator",
|
||||
"vertical",
|
||||
"indicator",
|
||||
"meaning",
|
||||
"verticalindicator",
|
||||
"configure",
|
||||
"scatter",
|
||||
"plot"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"words": [
|
||||
"wind",
|
||||
"rose",
|
||||
"configuration",
|
||||
"report",
|
||||
"meaning",
|
||||
"for",
|
||||
"wind",
|
||||
"direction",
|
||||
"granularity",
|
||||
"directions",
|
||||
"16",
|
||||
"N",
|
||||
"NNE",
|
||||
"NE",
|
||||
"ENE",
|
||||
"E",
|
||||
"angular",
|
||||
"measurement",
|
||||
"degree",
|
||||
"validation",
|
||||
"results",
|
||||
"validate",
|
||||
"ok",
|
||||
"cancel",
|
||||
"configuration",
|
||||
"indicator",
|
||||
"variable"
|
||||
]
|
||||
}
|
||||
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
@@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
# useful for tagging: https://www.htmlstrip.com/string-text-to-json-list-to-json-converter
|
||||
|
||||
for i in *.png; do echo "{\n \"words\": [\n \"\"\n ]\n}" > "${i/.png/.json}"; done
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 889 B After Width: | Height: | Size: 889 B |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 17 KiB |