Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Брозовский Максим #11

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 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
40 changes: 40 additions & 0 deletions TagCloud/CloudLayouter/CircularCloudLayouter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using SkiaSharp;
using TagCloud.PointsGenerator;

namespace TagCloud.CloudLayouter;

public class CircularCloudLayouter(SKPoint center) : ICloudLayouter
{
private const double OptimalRadius = 1;
private const double OptimalAngleOffset = 0.5;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно вынести в какой-нибудь класс конфигурации для настройки layouter'a и передавать в него как настройки


private readonly List<SKRect> rectangles = [];
private readonly SpiralPointsGenerator pointsGenerator = new(center, OptimalRadius, OptimalAngleOffset);

public SKPoint Center => center;
public IEnumerable<SKRect> Rectangles => rectangles;

public SKRect PutNextRectangle(SKSize rectangleSize)
{
while (true)
{
var rectanglePosition = pointsGenerator.GetNextPoint();
var rectangle = CreateRectangleWithCenter(rectanglePosition, rectangleSize);

if (rectangles.Any(rectangle.IntersectsWith)) continue;

rectangles.Add(rectangle);

return rectangle;
}
}

private static SKRect CreateRectangleWithCenter(SKPoint center, SKSize rectangleSize)
{
var left = center.X - rectangleSize.Width / 2;
var top = center.Y - rectangleSize.Height / 2;

return new SKRect(left, top, left + rectangleSize.Width, top + rectangleSize.Height);
}
}

8 changes: 8 additions & 0 deletions TagCloud/CloudLayouter/ICloudLayouter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using SkiaSharp;

namespace TagCloud.CloudLayouter;

public interface ICloudLayouter
{
public SKRect PutNextRectangle(SKSize rectangleSize);
}
8 changes: 8 additions & 0 deletions TagCloud/PointsGenerator/IPointsGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using SkiaSharp;

namespace TagCloud.PointsGenerator;

public interface IPointsGenerator
{
public SKPoint GetNextPoint();
}
41 changes: 41 additions & 0 deletions TagCloud/PointsGenerator/SpiralPointsGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using SkiaSharp;

namespace TagCloud.PointsGenerator;

public class SpiralPointsGenerator : IPointsGenerator
{
private readonly double angleOffset;
private readonly double radius;
private readonly SKPoint start;
private double angle;

public SpiralPointsGenerator(SKPoint start, double radius, double angleOffset)
{
if (radius <= 0)
throw new ArgumentException("radius must be greater than 0");
if (angleOffset <= 0)
throw new ArgumentException("angleOffset must be greater than 0");

this.angleOffset = angleOffset * Math.PI / 180;
this.radius = radius;
this.start = start;
}

public SKPoint GetNextPoint()
{
var nextPoint = GetPointByPolarCords();
angle += angleOffset;
return nextPoint;
}

private SKPoint GetPointByPolarCords()
{
var offsetPerRadian = radius / (2 * Math.PI);
var radiusVector = offsetPerRadian * angle;

var x = (int)Math.Round(radiusVector * Math.Cos(angle) + start.X);
var y = (int)Math.Round(radiusVector * Math.Sin(angle) + start.Y);

return new SKPoint(x, y);
}
}
16 changes: 16 additions & 0 deletions TagCloud/TagCloud.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CsvHelper" Version="33.0.1" />
<PackageReference Include="DocX" Version="3.0.1" />
<PackageReference Include="SkiaSharp" Version="3.116.1" />
<PackageReference Include="WeCantSpell.Hunspell" Version="5.2.1" />
</ItemGroup>

</Project>
14 changes: 14 additions & 0 deletions TagCloud/TagCloudGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using TagCloud.Visualization;
using TagCloud.WordsFilter;
using TagCloud.WordsReader;

namespace TagCloud;

public class TagCloudGenerator(IWordsReader reader, TagCloudImageGenerator imageGenerator,
IEnumerable<IWordsFilter> filters)
{
public string GenerateTagCloud()
{
throw new NotImplementedException();
}
}
8 changes: 8 additions & 0 deletions TagCloud/Utility/EnumerableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace TagCloud.Utility;

public static class EnumerableExtensions
{
public static string Join(this IEnumerable<string> words, string separator = "") => string.Join(separator, words);

public static IEnumerable<string> ToLower(this IEnumerable<string> words) => words.Select(w => w.ToLower());
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Как будто лишняя оболочка уже существующих методов

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Убрал

19 changes: 19 additions & 0 deletions TagCloud/Utility/RandomExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using SkiaSharp;

namespace TagCloud.Utility;

public static class RandomExtensions
{
public static SKSize NextSkSize(this Random random, int minValue, int maxValue)
{
if (minValue <= 0)
throw new ArgumentOutOfRangeException(nameof(minValue), "minValue must be greater than 0");
if (maxValue < minValue)
throw new ArgumentOutOfRangeException(nameof(maxValue), "maxValue must be greater than minValue");

return new SKSize(random.Next(minValue, maxValue), random.Next(minValue, maxValue));
}

public static SKPoint NextSkPoint(this Random random, int minValue, int maxValue) =>
new (random.Next(minValue, maxValue), random.Next(minValue, maxValue));
}
30 changes: 30 additions & 0 deletions TagCloud/Visualization/TagCloudImageGenerator.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using SkiaSharp;

namespace TagCloud.Visualization;

public class TagCloudImageGenerator(SKSizeI Size, SKTypeface fontFamily ,SKColor background, SKColor foreground)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тоже кажется прикольно было бы иметь конфигурацию

{
public SKBitmap CreateBitmap(List<SKRect> rectangles)
{
var bitmap = new SKBitmap(Size.Width, Size.Height);
var canvas = new SKCanvas(bitmap);
var paint = new SKPaint
{
Color = SKColors.Black,
Style = SKPaintStyle.Stroke
};

canvas.Clear(SKColors.White);

var xOffset = bitmap.Width / 2f - rectangles.First().Location.X;
var yOffset = bitmap.Height / 2f - rectangles.First().Location.Y;

foreach (var rectangle in rectangles)
{
rectangle.Offset(xOffset, yOffset);
canvas.DrawRect(rectangle, paint);
}

return bitmap;
}
}
22 changes: 22 additions & 0 deletions TagCloud/Visualization/TagCloudSaver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using SkiaSharp;

namespace TagCloud.Visualization;

public static class TagCloudSaver
{
private const int ImageQuality = 80;
private const string DefaultImageDirectory = "../../../imgs";

public static string Save(SKBitmap bitmap, string filePath,
SKEncodedImageFormat format = SKEncodedImageFormat.Png)
{
var defaultImagePath = Path.Combine(DefaultImageDirectory, $"{DateTime.Now:yy-MM-dd-HH-mm}");
var path = Path.GetDirectoryName(filePath) ?? defaultImagePath;
Directory.CreateDirectory(path);
var formatName = Enum.GetName(typeof(SKEncodedImageFormat), format)!.ToLower();
using var file = File.OpenWrite($"{filePath}.{formatName}");
bitmap.Encode(format, ImageQuality).SaveTo(file);

return path;
}
}
10 changes: 10 additions & 0 deletions TagCloud/WordsFilter/BoringWordsFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TagCloud.WordsFilter;

public class BoringWordsFilter : IWordsFilter
{
// TODO: implement me
public List<string> ApplyFilter(List<string> words)
{
throw new NotImplementedException();
}
}
7 changes: 7 additions & 0 deletions TagCloud/WordsFilter/IWordsFilter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TagCloud.WordsFilter;

public interface IWordsFilter
{
// Applying filter on list of words
List<string> ApplyFilter(List<string> words);
}
10 changes: 10 additions & 0 deletions TagCloud/WordsReader/CsvFileReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TagCloud.WordsReader;

public class CsvFileReader : IWordsReader
{
// TODO: implement me
public List<string> ReadWords()
{
throw new NotImplementedException();
}
}
10 changes: 10 additions & 0 deletions TagCloud/WordsReader/FileReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TagCloud.WordsReader;

public class FileReader : IWordsReader
{
// TODO: implement me
public List<string> ReadWords()
{
throw new NotImplementedException();
}
}
7 changes: 7 additions & 0 deletions TagCloud/WordsReader/IWordsReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace TagCloud.WordsReader;

public interface IWordsReader
{
// Reads words from filestream
List<string> ReadWords();
}
10 changes: 10 additions & 0 deletions TagCloud/WordsReader/WordFileReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace TagCloud.WordsReader;

public class WordFileReader : IWordsReader
{
// TODO: implement me
public List<string> ReadWords()
{
throw new NotImplementedException();
}
}
5 changes: 5 additions & 0 deletions TagCloudClient/Options.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace TagCloudClient;

public class Options
{
}
10 changes: 10 additions & 0 deletions TagCloudClient/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

namespace TagCloudClient;

internal class Program
{
public static void Main(string[] args)
{
// TODO: console application goes here
}
}
19 changes: 19 additions & 0 deletions TagCloudClient/TagCloudClient.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\TagCloud\TagCloud.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Autofac" Version="8.2.0" />
<PackageReference Include="CommandLineParser" Version="2.9.1" />
</ItemGroup>

</Project>
Loading