From 3da8a4e7c30bcaf8175da719dad767e88f80d96f Mon Sep 17 00:00:00 2001 From: Griboedoff Date: Mon, 12 Dec 2016 21:26:46 +0500 Subject: [PATCH 1/8] add basic infrastructure --- FractalPainter/fractalPainter.csproj | 3 + FractalPainter/packages.config | 1 + .../Core/Interfaces/ICloudBuilder.cs | 9 ++ .../Core/Interfaces/IFileReader.cs | 9 ++ .../Core/Interfaces/IPriorityGiver.cs | 9 ++ .../TagsCloudApp/Core/Interfaces/IRenderer.cs | 8 ++ .../Core/Interfaces/ITextPreprocessor.cs | 9 ++ TagsCloudApp/TagsCloudApp/Core/TagCloud.cs | 18 +++ .../TagsCloudApp/Core/TagCloudItem.cs | 22 +++ TagsCloudApp/TagsCloudApp/Core/WordInfo.cs | 41 ++++++ .../Implementations/CircularCloudBuilder.cs | 128 ++++++++++++++++++ .../Implementations/PngRenderer.cs | 36 +++++ .../Implementations/SamePriorityGiver.cs | 20 +++ .../Implementations/SimpleTextPreprocessor.cs | 98 ++++++++++++++ .../TagsCloudApp/Implementations/Spiral.cs | 39 ++++++ .../TagsCloudApp/Implementations/TxtReader.cs | 14 ++ TagsCloudApp/TagsCloudApp/Program.cs | 30 ++++ .../TagsCloudApp/Properties/AssemblyInfo.cs | 40 ++++++ TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj | 82 +++++++++++ TagsCloudApp/TagsCloudApp/packages.config | 4 + TagsCloudApp/TagsCloudApp/test | 8 ++ di.sln | 6 + 22 files changed, 634 insertions(+) create mode 100644 TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/Interfaces/IFileReader.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/Interfaces/IPriorityGiver.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/TagCloud.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/WordInfo.cs create mode 100644 TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs create mode 100644 TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs create mode 100644 TagsCloudApp/TagsCloudApp/Implementations/SamePriorityGiver.cs create mode 100644 TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs create mode 100644 TagsCloudApp/TagsCloudApp/Implementations/Spiral.cs create mode 100644 TagsCloudApp/TagsCloudApp/Implementations/TxtReader.cs create mode 100644 TagsCloudApp/TagsCloudApp/Program.cs create mode 100644 TagsCloudApp/TagsCloudApp/Properties/AssemblyInfo.cs create mode 100644 TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj create mode 100644 TagsCloudApp/TagsCloudApp/packages.config create mode 100644 TagsCloudApp/TagsCloudApp/test diff --git a/FractalPainter/fractalPainter.csproj b/FractalPainter/fractalPainter.csproj index b30602f95..43276bf21 100644 --- a/FractalPainter/fractalPainter.csproj +++ b/FractalPainter/fractalPainter.csproj @@ -36,6 +36,9 @@ FractalPainting.App.Program + + ..\packages\Autofac.4.2.1\lib\net45\Autofac.dll + ..\packages\Castle.Core.3.2.0\lib\net45\Castle.Core.dll True diff --git a/FractalPainter/packages.config b/FractalPainter/packages.config index c4c2a676a..04bedf63c 100644 --- a/FractalPainter/packages.config +++ b/FractalPainter/packages.config @@ -1,5 +1,6 @@  + diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs new file mode 100644 index 000000000..52370ecfb --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface ICloudBuilder + { + TagCloud BuildCloud(List cloudItems); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IFileReader.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IFileReader.cs new file mode 100644 index 000000000..1a68ede63 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IFileReader.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface IFileReader + { + IEnumerable GetFileContetByWords(string path); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPriorityGiver.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPriorityGiver.cs new file mode 100644 index 000000000..22e1c0a9c --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPriorityGiver.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface IPriorityGiver + { + IEnumerable SetPriorities(List words); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs new file mode 100644 index 000000000..19910e451 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs @@ -0,0 +1,8 @@ +namespace TagsCloudApp.Core.Interfaces +{ + public interface IRenderer + { + void RenderImage(TagCloud cloud); + void SaveImageTo(string path); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs new file mode 100644 index 000000000..1374061bd --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface ITextPreprocessor + { + IEnumerable ProcessWords(IEnumerable words); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs b/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs new file mode 100644 index 000000000..b3a896c69 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using System.Drawing; +using System.Linq; + +namespace TagsCloudApp.Core +{ + public class TagCloud + { + public readonly List Items; + public Size Size; + + public TagCloud(IEnumerable items, Size size) + { + Items = items.ToList(); + Size = size; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs b/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs new file mode 100644 index 000000000..51a52ae64 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs @@ -0,0 +1,22 @@ +using System.Drawing; + +namespace TagsCloudApp.Core +{ + public class TagCloudItem + { + public readonly WordInfo WordInfo; + public int FontSize; + public Color Color; + public Font Font; + public Rectangle Rectangle; + + public TagCloudItem(Color color, WordInfo wordInfo, int fontSize, Font font, Rectangle rectangle) + { + Color = color; + WordInfo = wordInfo; + FontSize = fontSize; + Font = font; + Rectangle = rectangle; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/WordInfo.cs b/TagsCloudApp/TagsCloudApp/Core/WordInfo.cs new file mode 100644 index 000000000..93c8c376f --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/WordInfo.cs @@ -0,0 +1,41 @@ +namespace TagsCloudApp.Core +{ + public class WordInfo + { + public readonly string Word; + public double Frequency; + + private bool Equals(WordInfo other) + { + return string.Equals(Word, other.Word); + } + + public override bool Equals(object obj) + { + if (ReferenceEquals(null, obj)) return false; + if (ReferenceEquals(this, obj)) return true; + return obj.GetType() == GetType() && Equals((WordInfo) obj); + } + + public override int GetHashCode() + { + return Word?.GetHashCode() ?? 0; + } + + public static bool operator ==(WordInfo left, WordInfo right) + { + return Equals(left, right); + } + + public static bool operator !=(WordInfo left, WordInfo right) + { + return !Equals(left, right); + } + + public WordInfo(string word, double frequency) + { + Word = word; + Frequency = frequency; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs b/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs new file mode 100644 index 000000000..b87df0641 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public static class RectangleExtension + { + public static Point GetCenter(this Rectangle rect) => rect.Location + new Size(rect.Width / 2, rect.Height / 2); + } + + public static class PointExtensions + { + public static Point SnapByX(this Point p) + { + return new Point(p.X / (p.X != 0 ? Math.Abs(p.X) : 1), 0); + } + + public static Point SnapByY(this Point p) + { + return new Point(0, p.Y / (p.Y != 0 ? Math.Abs(p.Y) : 1)); + } + } + + internal class CircularCloudBuilder : ICloudBuilder + { + private Point center; + private readonly Spiral spiral; + private readonly Rectangle cloudBorders; + + private Point Center + { + set + { + if (value.X < 0 || value.Y < 0) + throw new ArgumentException("Center point should be non-negative"); + center = value; + } + } + + private List PlacedRectangles { get; } + + private bool IsInValidPosition(Rectangle checkingRectangle) + { + return !PlacedRectangles.Any(rect => rect.IntersectsWith(checkingRectangle)) && + cloudBorders.Contains(checkingRectangle); + } + + private static Point GetRectangleCenterLocation(Size rectangleSize, Point nextSpiralPoint) + { + return new Point(nextSpiralPoint.X - rectangleSize.Width / 2, nextSpiralPoint.Y - rectangleSize.Height / 2); + } + + public CircularCloudBuilder(Point center) + { + spiral = new Spiral(center); + Center = center; + cloudBorders = new Rectangle(0, 0, center.X * 2, center.Y * 2); + PlacedRectangles = new List(); + } + + private Rectangle PutNextRectangle(Size rectangleSize) + { + if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) + throw new ArgumentException($"Size must be positive {rectangleSize}"); + + var nextRectangle = FindNextRectanglePosition(rectangleSize); + + if (nextRectangle.IsEmpty) return nextRectangle; + + nextRectangle = MoveToCenter(nextRectangle); + PlacedRectangles.Add(nextRectangle); + return nextRectangle; + } + + private Rectangle FindNextRectanglePosition(Size rectangleSize) + { + var nextSpiralPoint = spiral.GetNextSpiralPoint(); + var nextRectangle = new Rectangle(GetRectangleCenterLocation(rectangleSize, nextSpiralPoint), rectangleSize); + + while (!IsInValidPosition(nextRectangle)) + { + nextSpiralPoint = spiral.GetNextSpiralPoint(); + nextRectangle = new Rectangle(GetRectangleCenterLocation(rectangleSize, nextSpiralPoint), rectangleSize); + if (!cloudBorders.Contains(nextSpiralPoint)) + throw new ArgumentException("Can't place rectangle because cloud is too small"); + } + + return nextRectangle; + } + + private Rectangle MoveToCenter(Rectangle rectangle) + { + var newRectangle = Rectangle.Empty; + while (rectangle != newRectangle) + { + if (!newRectangle.IsEmpty) + rectangle = newRectangle; + var vectorToCenter = center - new Size(rectangle.GetCenter()); + newRectangle = TryMove(rectangle, vectorToCenter.SnapByX()); + newRectangle = TryMove(newRectangle, vectorToCenter.SnapByY()); + } + return rectangle; + } + + private Rectangle TryMove(Rectangle rectangle, Point shift) + { + var newRect = new Rectangle(rectangle.Location + new Size(shift), rectangle.Size); + var isInValidPosition = IsInValidPosition(newRect); + if (isInValidPosition) + rectangle = newRect; + return rectangle; + } + + public TagCloud BuildCloud(List cloudItems) + { + Console.WriteLine("end build"); + foreach (var cloudItem in cloudItems) + cloudItem.Rectangle = + PutNextRectangle(new Size(cloudItem.FontSize * cloudItem.WordInfo.Word.Length, cloudItem.FontSize * 3)); + + return new TagCloud(cloudItems, new Size(1000, 1000)); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs b/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs new file mode 100644 index 000000000..cfae3d3ef --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs @@ -0,0 +1,36 @@ +using System.Drawing; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + class PngRenderer : IRenderer + { + private Bitmap image; + + public void RenderImage(TagCloud cloud) + { + image = new Bitmap(cloud.Size.Width, cloud.Size.Height); + var g = Graphics.FromImage(image); + g.FillRectangle(Brushes.Black, new Rectangle(new Point(0, 0), cloud.Size)); + + foreach (var cloudItem in cloud.Items) + { + g.DrawString(cloudItem); + } + } + + public void SaveImageTo(string path) + { + image.Save(path); + } + } + + internal static class GraphicsExtension + { + public static void DrawString(this Graphics g, TagCloudItem item) + { + g.DrawString(item.WordInfo.Word, item.Font, new SolidBrush(item.Color), item.Rectangle); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/SamePriorityGiver.cs b/TagsCloudApp/TagsCloudApp/Implementations/SamePriorityGiver.cs new file mode 100644 index 000000000..83db9d51f --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/SamePriorityGiver.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + class SamePriorityGiver : IPriorityGiver + { + public IEnumerable SetPriorities(List words) + { + var wordInfos = new HashSet(words); + var tagCloudItems = new List(); + foreach (var word in wordInfos) + tagCloudItems.Add(new TagCloudItem(Color.White, word, 10, new Font("Menlo", 10), default(Rectangle))); + return tagCloudItems; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs b/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs new file mode 100644 index 000000000..87f6725c1 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs @@ -0,0 +1,98 @@ +using System.Collections.Generic; +using System.Linq; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + internal class SimpleTextPreprocessor : ITextPreprocessor + { + private static readonly HashSet BoringWords = new HashSet + { + "aboard", + "about", + "above", + "across", + "after", + "against", + "along", + "amid", + "among", + "anti", + "around", + "as", + "at", + "before", + "behind", + "below", + "beneath", + "beside", + "besides", + "between", + "beyond", + "but", + "by", + "concerning", + "considering", + "despite", + "down", + "during", + "except", + "excepting", + "excluding", + "following", + "for", + "from", + "in", + "inside", + "into", + "like", + "minus", + "near", + "of", + "off", + "on", + "onto", + "opposite", + "outside", + "over", + "past", + "per", + "plus", + "regarding", + "round", + "save", + "since", + "than", + "through", + "to", + "toward", + "towards", + "under", + "underneath", + "unlike", + "until", + "up", + "upon", + "versus", + "via", + "with", + "within", + "without" + }; + + public IEnumerable ProcessWords(IEnumerable words) + { + var counter = new Dictionary(); + var c = 0; + foreach (var word in words.Where(word => !BoringWords.Contains(word.ToLowerInvariant()))) + { + if (!counter.ContainsKey(word)) + counter.Add(word, 0); + counter[word]++; + c++; + } + return counter.Select(kv => new WordInfo(kv.Key, kv.Value / c)); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/Spiral.cs b/TagsCloudApp/TagsCloudApp/Implementations/Spiral.cs new file mode 100644 index 000000000..b28b2025b --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/Spiral.cs @@ -0,0 +1,39 @@ +using System; +using System.Drawing; + +namespace TagsCloudApp.Implementations +{ + public class Spiral + { + private readonly Point center; + private readonly double deltaAngle; + private readonly double deltaRadius; + private Point currentPoint; + + private double CurrentAngle { get; set; } + + private double CurrentRadius { get; set; } + + public Spiral(Point center, double deltaAngle = Math.PI / 180, double deltaRadius = 0.001) + { + this.center = center; + this.deltaAngle = deltaAngle; + this.deltaRadius = deltaRadius; + currentPoint = this.center; + CurrentAngle = 0; + CurrentRadius = 0; + } + + public Point GetNextSpiralPoint() + { + var prevPoint = currentPoint; + CurrentAngle += deltaAngle; + CurrentRadius += deltaRadius; + + var newX = (int) (CurrentRadius * Math.Cos(CurrentAngle) + center.X); + var newY = (int) (CurrentRadius * Math.Sin(CurrentAngle) + center.Y); + currentPoint = new Point(newX, newY); + return prevPoint; + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/TxtReader.cs b/TagsCloudApp/TagsCloudApp/Implementations/TxtReader.cs new file mode 100644 index 000000000..8b45701d7 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/TxtReader.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.IO; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public class TxtReader : IFileReader + { + public IEnumerable GetFileContetByWords(string path) + { + return File.ReadAllLines(path); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Program.cs b/TagsCloudApp/TagsCloudApp/Program.cs new file mode 100644 index 000000000..3c59c9e36 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Program.cs @@ -0,0 +1,30 @@ +using System.Drawing; +using System.Linq; +using TagsCloudApp.Implementations; + +namespace TagsCloudApp +{ + internal class Program + { + public static void Main(string[] args) + { +// var builder = new ContainerBuilder(); +// builder.RegisterInstance(new TxtReader()).As(); +// builder.RegisterInstance(new PngRenderer()).As(); +// builder.RegisterInstance(new CircularCloudBuilder(new Point(500,500))).As(); +// builder.RegisterInstance(new SamePriorityGiver()).As(); +// builder.RegisterInstance(new SimpleTextPreprocessor()).As(); +// +// var container = builder.Build(); + var reader = new TxtReader(); + var renderer = new PngRenderer(); + renderer.RenderImage( + new CircularCloudBuilder(new Point(500, 500)) + .BuildCloud(new SamePriorityGiver() + .SetPriorities(new SimpleTextPreprocessor() + .ProcessWords(new TxtReader().GetFileContetByWords("./test")).ToList()) + .ToList())); + renderer.SaveImageTo("./test_res.png"); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Properties/AssemblyInfo.cs b/TagsCloudApp/TagsCloudApp/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..7e753e05e --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Properties/AssemblyInfo.cs @@ -0,0 +1,40 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. + +[assembly: AssemblyTitle("TagsCloudApp")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("TagsCloudApp")] +[assembly: AssemblyCopyright("Copyright © 2016")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. + +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM + +[assembly: Guid("32340528-0E6D-4CA1-8048-545865F527B1")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] + +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj b/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj new file mode 100644 index 000000000..a47c73b7c --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj @@ -0,0 +1,82 @@ + + + + + Debug + AnyCPU + {32340528-0E6D-4CA1-8048-545865F527B1} + {FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + Exe + Properties + TagsCloudApp + TagsCloudApp + v4.5 + 512 + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Autofac.4.2.1\lib\net45\Autofac.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PreserveNewest + + + + + + + + \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/packages.config b/TagsCloudApp/TagsCloudApp/packages.config new file mode 100644 index 000000000..b017b68f8 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/test b/TagsCloudApp/TagsCloudApp/test new file mode 100644 index 000000000..465b3e858 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/test @@ -0,0 +1,8 @@ +qwerty +asdfgh +zxvbnn +rtyuio +fghjkl +bnm,./ +edfbnj +oiuytd \ No newline at end of file diff --git a/di.sln b/di.sln index 9e820827b..638b84521 100644 --- a/di.sln +++ b/di.sln @@ -10,6 +10,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution README.md = README.md EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TagsCloudApp", "TagsCloudApp\TagsCloudApp\TagsCloudApp.csproj", "{32340528-0E6D-4CA1-8048-545865F527B1}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -20,6 +22,10 @@ Global {2A3ACF0E-1D07-4A1A-8320-F99DC2DE791F}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A3ACF0E-1D07-4A1A-8320-F99DC2DE791F}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A3ACF0E-1D07-4A1A-8320-F99DC2DE791F}.Release|Any CPU.Build.0 = Release|Any CPU + {32340528-0E6D-4CA1-8048-545865F527B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {32340528-0E6D-4CA1-8048-545865F527B1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {32340528-0E6D-4CA1-8048-545865F527B1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {32340528-0E6D-4CA1-8048-545865F527B1}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 1f2f48cf13515fc49ba11f5a0d5d902756387ca0 Mon Sep 17 00:00:00 2001 From: Griboedoff Date: Thu, 15 Dec 2016 23:48:30 +0500 Subject: [PATCH 2/8] add di start add vizualizer --- .../Core/Extensions/PointExtensions.cs | 18 +++++++ .../Core/Extensions/RectangleExtension.cs | 9 ++++ .../Core/Interfaces/ICloudBuilder.cs | 3 +- .../Core/Interfaces/IPriorityGiver.cs | 9 ---- .../Core/Interfaces/IPrioritySetter.cs | 9 ++++ .../TagsCloudApp/Core/Interfaces/IRenderer.cs | 1 + .../Core/Interfaces/ITextPreprocessor.cs | 2 +- .../Core/Interfaces/IVizualizer.cs | 7 +++ TagsCloudApp/TagsCloudApp/Core/TagCloud.cs | 49 +++++++++++++++++-- .../TagsCloudApp/Core/TagCloudItem.cs | 16 +++--- .../Implementations/CircularCloudBuilder.cs | 44 ++++++----------- .../Implementations/PngRenderer.cs | 5 ++ .../Implementations/SamePriorityGiver.cs | 20 -------- .../Implementations/SamePrioritySetter.cs | 19 +++++++ .../Implementations/SimpleTextPreprocessor.cs | 6 ++- .../Implementations/WinFormVizualizer.cs | 10 ++++ TagsCloudApp/TagsCloudApp/Program.cs | 41 +++++++++------- TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj | 14 +++--- TagsCloudApp/TagsCloudApp/{test => test.txt} | 0 19 files changed, 183 insertions(+), 99 deletions(-) create mode 100644 TagsCloudApp/TagsCloudApp/Core/Extensions/PointExtensions.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/Extensions/RectangleExtension.cs delete mode 100644 TagsCloudApp/TagsCloudApp/Core/Interfaces/IPriorityGiver.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/Interfaces/IPrioritySetter.cs create mode 100644 TagsCloudApp/TagsCloudApp/Core/Interfaces/IVizualizer.cs delete mode 100644 TagsCloudApp/TagsCloudApp/Implementations/SamePriorityGiver.cs create mode 100644 TagsCloudApp/TagsCloudApp/Implementations/SamePrioritySetter.cs create mode 100644 TagsCloudApp/TagsCloudApp/Implementations/WinFormVizualizer.cs rename TagsCloudApp/TagsCloudApp/{test => test.txt} (100%) diff --git a/TagsCloudApp/TagsCloudApp/Core/Extensions/PointExtensions.cs b/TagsCloudApp/TagsCloudApp/Core/Extensions/PointExtensions.cs new file mode 100644 index 000000000..0f9f4c0c8 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Extensions/PointExtensions.cs @@ -0,0 +1,18 @@ +using System; +using System.Drawing; + +namespace TagsCloudApp.Core.Extensions +{ + public static class PointExtensions + { + public static Point SnapByX(this Point p) + { + return new Point(p.X / (p.X != 0 ? Math.Abs(p.X) : 1), 0); + } + + public static Point SnapByY(this Point p) + { + return new Point(0, p.Y / (p.Y != 0 ? Math.Abs(p.Y) : 1)); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Extensions/RectangleExtension.cs b/TagsCloudApp/TagsCloudApp/Core/Extensions/RectangleExtension.cs new file mode 100644 index 000000000..1939d57b9 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Extensions/RectangleExtension.cs @@ -0,0 +1,9 @@ +using System.Drawing; + +namespace TagsCloudApp.Core.Extensions +{ + public static class RectangleExtension + { + public static Point GetCenter(this Rectangle rect) => rect.Location + new Size(rect.Width / 2, rect.Height / 2); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs index 52370ecfb..1af53567d 100644 --- a/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ICloudBuilder.cs @@ -1,9 +1,10 @@ using System.Collections.Generic; +using System.Drawing; namespace TagsCloudApp.Core.Interfaces { public interface ICloudBuilder { - TagCloud BuildCloud(List cloudItems); + List BuildCloud(List cloudItems, Point newCenter); } } \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPriorityGiver.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPriorityGiver.cs deleted file mode 100644 index 22e1c0a9c..000000000 --- a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPriorityGiver.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace TagsCloudApp.Core.Interfaces -{ - public interface IPriorityGiver - { - IEnumerable SetPriorities(List words); - } -} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPrioritySetter.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPrioritySetter.cs new file mode 100644 index 000000000..65e4fec9a --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IPrioritySetter.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace TagsCloudApp.Core.Interfaces +{ + public interface IPrioritySetter + { + List SetPriorities(IEnumerable words); + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs index 19910e451..43ba960aa 100644 --- a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IRenderer.cs @@ -2,6 +2,7 @@ { public interface IRenderer { + bool HasRendered(); void RenderImage(TagCloud cloud); void SaveImageTo(string path); } diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs index 1374061bd..c5c90a843 100644 --- a/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/ITextPreprocessor.cs @@ -4,6 +4,6 @@ namespace TagsCloudApp.Core.Interfaces { public interface ITextPreprocessor { - IEnumerable ProcessWords(IEnumerable words); + List ProcessWords(IEnumerable words); } } \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/Interfaces/IVizualizer.cs b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IVizualizer.cs new file mode 100644 index 000000000..4b37d5265 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Core/Interfaces/IVizualizer.cs @@ -0,0 +1,7 @@ +namespace TagsCloudApp.Core.Interfaces +{ + public interface IVizualizer + { + + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs b/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs index b3a896c69..61be99f7f 100644 --- a/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs +++ b/TagsCloudApp/TagsCloudApp/Core/TagCloud.cs @@ -1,18 +1,57 @@ using System.Collections.Generic; using System.Drawing; -using System.Linq; +using TagsCloudApp.Core.Interfaces; namespace TagsCloudApp.Core { public class TagCloud { - public readonly List Items; - public Size Size; + private readonly ICloudBuilder cloudBuilder; + private readonly IFileReader reader; + private readonly IPrioritySetter prioritySetter; + private readonly IRenderer renderer; + private readonly ITextPreprocessor textPreprocessor; + private readonly IVizualizer vizualizer; + private List items; + public Size Size { get; private set; } - public TagCloud(IEnumerable items, Size size) + public IEnumerable Items => items.AsReadOnly(); + + public TagCloud(ICloudBuilder cloudBuilder, IFileReader reader, IPrioritySetter prioritySetter, IRenderer renderer, + ITextPreprocessor textPreprocessor, IVizualizer vizualizer) + { + this.cloudBuilder = cloudBuilder; + this.reader = reader; + this.prioritySetter = prioritySetter; + this.renderer = renderer; + this.textPreprocessor = textPreprocessor; + this.vizualizer = vizualizer; + } + + public void Build(string pathToWords, Size size) { - Items = items.ToList(); Size = size; + var words = reader.GetFileContetByWords(pathToWords); + var processedWords = textPreprocessor.ProcessWords(words); + var priorities = prioritySetter.SetPriorities(processedWords); + items = cloudBuilder.BuildCloud(priorities, new Point(size.Width / 2, size.Height / 2)); + } + + public void RenderCloud() + { + renderer.RenderImage(this); + } + + public void Save(string path) + { + if (!renderer.HasRendered()) + renderer.RenderImage(this); + renderer.SaveImageTo(path); + } + + public void Vizualize() + { + } } } \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs b/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs index 51a52ae64..b21024a42 100644 --- a/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs +++ b/TagsCloudApp/TagsCloudApp/Core/TagCloudItem.cs @@ -5,18 +5,22 @@ namespace TagsCloudApp.Core public class TagCloudItem { public readonly WordInfo WordInfo; - public int FontSize; - public Color Color; - public Font Font; - public Rectangle Rectangle; + public readonly Color Color; + public readonly Font Font; + public readonly Rectangle Rectangle; - public TagCloudItem(Color color, WordInfo wordInfo, int fontSize, Font font, Rectangle rectangle) + public TagCloudItem(Color color, WordInfo wordInfo, Font font, Rectangle rectangle) { Color = color; WordInfo = wordInfo; - FontSize = fontSize; Font = font; Rectangle = rectangle; } + + public TagCloudItem SetColor(Color newColor) => new TagCloudItem(newColor, WordInfo, Font, Rectangle); + + public TagCloudItem SetFont(Font newFont) => new TagCloudItem(Color, WordInfo, newFont, Rectangle); + + public TagCloudItem SetRectangle(Rectangle newRectangle) => new TagCloudItem(Color, WordInfo, Font, newRectangle); } } \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs b/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs index b87df0641..99d5af7fc 100644 --- a/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs +++ b/TagsCloudApp/TagsCloudApp/Implementations/CircularCloudBuilder.cs @@ -3,33 +3,16 @@ using System.Drawing; using System.Linq; using TagsCloudApp.Core; +using TagsCloudApp.Core.Extensions; using TagsCloudApp.Core.Interfaces; namespace TagsCloudApp.Implementations { - public static class RectangleExtension - { - public static Point GetCenter(this Rectangle rect) => rect.Location + new Size(rect.Width / 2, rect.Height / 2); - } - - public static class PointExtensions - { - public static Point SnapByX(this Point p) - { - return new Point(p.X / (p.X != 0 ? Math.Abs(p.X) : 1), 0); - } - - public static Point SnapByY(this Point p) - { - return new Point(0, p.Y / (p.Y != 0 ? Math.Abs(p.Y) : 1)); - } - } - internal class CircularCloudBuilder : ICloudBuilder { private Point center; - private readonly Spiral spiral; - private readonly Rectangle cloudBorders; + private Spiral spiral; + private Rectangle cloudBorders; private Point Center { @@ -54,14 +37,18 @@ private static Point GetRectangleCenterLocation(Size rectangleSize, Point nextSp return new Point(nextSpiralPoint.X - rectangleSize.Width / 2, nextSpiralPoint.Y - rectangleSize.Height / 2); } - public CircularCloudBuilder(Point center) + public CircularCloudBuilder() { - spiral = new Spiral(center); - Center = center; - cloudBorders = new Rectangle(0, 0, center.X * 2, center.Y * 2); PlacedRectangles = new List(); } + private void InitCloud(Point newCenter) + { + spiral = new Spiral(newCenter); + Center = newCenter; + cloudBorders = new Rectangle(0, 0, newCenter.X * 2, newCenter.Y * 2); + } + private Rectangle PutNextRectangle(Size rectangleSize) { if (rectangleSize.Height <= 0 || rectangleSize.Width <= 0) @@ -115,14 +102,11 @@ private Rectangle TryMove(Rectangle rectangle, Point shift) return rectangle; } - public TagCloud BuildCloud(List cloudItems) + public List BuildCloud(List cloudItems, Point newCenter) { - Console.WriteLine("end build"); - foreach (var cloudItem in cloudItems) - cloudItem.Rectangle = - PutNextRectangle(new Size(cloudItem.FontSize * cloudItem.WordInfo.Word.Length, cloudItem.FontSize * 3)); + InitCloud(newCenter); - return new TagCloud(cloudItems, new Size(1000, 1000)); + return cloudItems.Select(cloudItem => cloudItem.SetRectangle(PutNextRectangle(cloudItem.Rectangle.Size))).ToList(); } } } \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs b/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs index cfae3d3ef..35c934d2c 100644 --- a/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs +++ b/TagsCloudApp/TagsCloudApp/Implementations/PngRenderer.cs @@ -8,6 +8,11 @@ class PngRenderer : IRenderer { private Bitmap image; + public bool HasRendered() + { + return image != null; + } + public void RenderImage(TagCloud cloud) { image = new Bitmap(cloud.Size.Width, cloud.Size.Height); diff --git a/TagsCloudApp/TagsCloudApp/Implementations/SamePriorityGiver.cs b/TagsCloudApp/TagsCloudApp/Implementations/SamePriorityGiver.cs deleted file mode 100644 index 83db9d51f..000000000 --- a/TagsCloudApp/TagsCloudApp/Implementations/SamePriorityGiver.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Collections.Generic; -using System.Drawing; -using System.Linq; -using TagsCloudApp.Core; -using TagsCloudApp.Core.Interfaces; - -namespace TagsCloudApp.Implementations -{ - class SamePriorityGiver : IPriorityGiver - { - public IEnumerable SetPriorities(List words) - { - var wordInfos = new HashSet(words); - var tagCloudItems = new List(); - foreach (var word in wordInfos) - tagCloudItems.Add(new TagCloudItem(Color.White, word, 10, new Font("Menlo", 10), default(Rectangle))); - return tagCloudItems; - } - } -} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/SamePrioritySetter.cs b/TagsCloudApp/TagsCloudApp/Implementations/SamePrioritySetter.cs new file mode 100644 index 000000000..8abd2b1c1 --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/SamePrioritySetter.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using System.Drawing; +using System.Linq; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + internal class SamePrioritySetter : IPrioritySetter + { + public List SetPriorities(IEnumerable words) + { + var wordInfos = new HashSet(words); + return wordInfos + .Select(word => new TagCloudItem(Color.Red, word, new Font("Menlo", 10), new Rectangle(0, 0, 100, 40))) + .ToList(); + } + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs b/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs index 87f6725c1..306684944 100644 --- a/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs +++ b/TagsCloudApp/TagsCloudApp/Implementations/SimpleTextPreprocessor.cs @@ -81,7 +81,7 @@ internal class SimpleTextPreprocessor : ITextPreprocessor "without" }; - public IEnumerable ProcessWords(IEnumerable words) + public List ProcessWords(IEnumerable words) { var counter = new Dictionary(); var c = 0; @@ -92,7 +92,9 @@ public IEnumerable ProcessWords(IEnumerable words) counter[word]++; c++; } - return counter.Select(kv => new WordInfo(kv.Key, kv.Value / c)); + return counter + .Select(kv => new WordInfo(kv.Key, kv.Value / c)) + .ToList(); } } } \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Implementations/WinFormVizualizer.cs b/TagsCloudApp/TagsCloudApp/Implementations/WinFormVizualizer.cs new file mode 100644 index 000000000..06ff95f8d --- /dev/null +++ b/TagsCloudApp/TagsCloudApp/Implementations/WinFormVizualizer.cs @@ -0,0 +1,10 @@ +using System.Windows.Forms; +using TagsCloudApp.Core.Interfaces; + +namespace TagsCloudApp.Implementations +{ + public class WinFormVizualizer : Form, IVizualizer + { + + } +} \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/Program.cs b/TagsCloudApp/TagsCloudApp/Program.cs index 3c59c9e36..a89b61b4d 100644 --- a/TagsCloudApp/TagsCloudApp/Program.cs +++ b/TagsCloudApp/TagsCloudApp/Program.cs @@ -1,30 +1,33 @@ using System.Drawing; -using System.Linq; +using System.IO; +using Autofac; +using TagsCloudApp.Core; +using TagsCloudApp.Core.Interfaces; using TagsCloudApp.Implementations; namespace TagsCloudApp { - internal class Program + internal static class Program { public static void Main(string[] args) { -// var builder = new ContainerBuilder(); -// builder.RegisterInstance(new TxtReader()).As(); -// builder.RegisterInstance(new PngRenderer()).As(); -// builder.RegisterInstance(new CircularCloudBuilder(new Point(500,500))).As(); -// builder.RegisterInstance(new SamePriorityGiver()).As(); -// builder.RegisterInstance(new SimpleTextPreprocessor()).As(); -// -// var container = builder.Build(); - var reader = new TxtReader(); - var renderer = new PngRenderer(); - renderer.RenderImage( - new CircularCloudBuilder(new Point(500, 500)) - .BuildCloud(new SamePriorityGiver() - .SetPriorities(new SimpleTextPreprocessor() - .ProcessWords(new TxtReader().GetFileContetByWords("./test")).ToList()) - .ToList())); - renderer.SaveImageTo("./test_res.png"); + var builder = new ContainerBuilder(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().As(); + builder.RegisterType().AsSelf(); + + var container = builder.Build(); + + using (var scope = container.BeginLifetimeScope()) + { + var cloud = scope.Resolve(); + cloud.Build(Path.Combine(".", "test.txt"), new Size(1000, 1000)); + cloud.RenderCloud(); + cloud.Save("test"); + } } } } \ No newline at end of file diff --git a/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj b/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj index a47c73b7c..0b3d0f664 100644 --- a/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj +++ b/TagsCloudApp/TagsCloudApp/TagsCloudApp.csproj @@ -39,38 +39,40 @@ + + + - + + - + + - + PreserveNewest - - -