Skip to content

Commit

Permalink
Add specific colorizer (#21)
Browse files Browse the repository at this point in the history
  • Loading branch information
jjonescz authored Dec 22, 2022
2 parents 500897a + 13f5818 commit 35dfd09
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 71 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@
var wcg = new WordCloudGenerator<SKBitmap>(wordCloud, engine, layout, colorizer);
```

You can also use `SpecificColorizer` to colorize specific words with chosen colors:

```cs
var colorizer = new SpecificColorizer(
new Dictionary<string, Color>
{
["KnowledgePicker"] = Color.FromArgb(0x0f3057),
["WordCloud"] = Color.FromArgb(0xe25a5a)
},
fallback: new RandomColorizer()); // fallback argument is optional
```

5. Now we can *arrange* the topic cloud:

```cs
Expand Down
13 changes: 10 additions & 3 deletions src/KnowledgePicker.WordCloud/Coloring/IColorizer.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
using KnowledgePicker.WordCloud.Primitives;
using System.Drawing;

namespace KnowledgePicker.WordCloud.Coloring
{
public interface IColorizer
{
/// <summary>
/// Gets the hex string color for text.
/// Gets color for the specified <paramref name="item"/>.
/// </summary>
/// <returns>Hex string color in format #RRGGBB.</returns>
string GetColorAsHex();
/// <param name="item">The item being colored.</param>
/// <returns>
/// Can return <see langword="null"/> to use the default color
/// (<see cref="WordCloudInput.TextColor"/>).
/// </returns>
Color? GetColor(LayoutItem item);
}
}
36 changes: 10 additions & 26 deletions src/KnowledgePicker.WordCloud/Coloring/RandomColorizer.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
using KnowledgePicker.WordCloud.Primitives;
using System;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;

namespace KnowledgePicker.WordCloud.Coloring
Expand All @@ -11,38 +11,22 @@ public class RandomColorizer : IColorizer
{
private readonly Random random;

public RandomColorizer() : this(Environment.TickCount) { }

public RandomColorizer(int seed)
public RandomColorizer()
{
random = new Random(seed);
random = new Random();
}

/// <summary>
/// Gets a random color.
/// </summary>
[SuppressMessage("Security", "CA5394:Do not use insecure randomness")]
private Color GetRandomColor()
{
return Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));
}

/// <summary>
/// Converts Color to hex string.
/// </summary>
private static string ConvertToHexString(Color c)
public RandomColorizer(int seed)
{
return $"#{c.R:X2}{c.G:X2}{c.B:X2}";
random = new Random(seed);
}

/// <summary>
/// Gets the randon RGB color as a hex string.
/// </summary>
public string GetColorAsHex()
public Color? GetColor(LayoutItem item)
{
Color c = GetRandomColor();
return ConvertToHexString(c);
return Color.FromArgb(
random.Next(0, 255),
random.Next(0, 255),
random.Next(0, 255));
}

}
}
32 changes: 32 additions & 0 deletions src/KnowledgePicker.WordCloud/Coloring/SpecificColorizer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using KnowledgePicker.WordCloud.Primitives;
using System.Collections.Generic;
using System.Drawing;

namespace KnowledgePicker.WordCloud.Coloring
{
/// <summary>
/// Colors specific words with provided colors.
/// </summary>
public class SpecificColorizer : IColorizer
{
private readonly IReadOnlyDictionary<string, Color> mapping;
private readonly IColorizer? fallback;

public SpecificColorizer(
IReadOnlyDictionary<string, Color> mapping,
IColorizer? fallback = null)
{
this.mapping = mapping;
this.fallback = fallback;
}

public Color? GetColor(LayoutItem item)
{
if (mapping.TryGetValue(item.Entry.Word, out var color))
{
return color;
}
return fallback?.GetColor(item);
}
}
}
22 changes: 14 additions & 8 deletions src/KnowledgePicker.WordCloud/Drawing/SkGraphicEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ namespace KnowledgePicker.WordCloud.Drawing
public sealed class SkGraphicEngine : IGraphicEngine<SKBitmap>
{
private readonly SKCanvas canvas;
private readonly SKColor defaultColor;
private readonly SKPaint textPaint;
private readonly WordCloudInput wordCloud;
private readonly bool ownsTextPaint;
private bool bitmapExtracted;

private SkGraphicEngine(ISizer sizer, WordCloudInput wordCloud,
SKPaint textPaint)
{
Sizer = sizer;
this.wordCloud = wordCloud;
defaultColor = textPaint.Color;
this.textPaint = textPaint;
Bitmap = new SKBitmap(wordCloud.Width, wordCloud.Height);
canvas = new SKCanvas(Bitmap);
Expand All @@ -31,13 +32,13 @@ public SkGraphicEngine(ISizer sizer, WordCloudInput wordCloud,
Sizer = sizer;
Bitmap = new SKBitmap(wordCloud.Width, wordCloud.Height);
canvas = new SKCanvas(Bitmap);
defaultColor = SKColor.Parse(wordCloud.TextColor);
textPaint = new SKPaint
{
Color = SKColor.Parse(wordCloud.TextColor),
Color = defaultColor,
Typeface = font,
IsAntialias = antialias
};
ownsTextPaint = true;
this.wordCloud = wordCloud;
}

Expand All @@ -60,14 +61,22 @@ public void Draw(PointD location, RectangleD measured, string text, int count, s
// https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/text.
textPaint.TextSize = (float)Sizer.GetFontSize(count);
if (colorHex != null)
{
textPaint.Color = SKColor.Parse(colorHex);
}
else
{
textPaint.Color = defaultColor;
}
canvas.DrawText(text, (float)(location.X - measured.Left),
(float)(location.Y - measured.Top), textPaint);
}

public IGraphicEngine<SKBitmap> Clone()
{
return new SkGraphicEngine(Sizer, wordCloud, textPaint);
var clonedTextPaint = textPaint.Clone();
clonedTextPaint.Color = defaultColor;
return new SkGraphicEngine(Sizer, wordCloud, clonedTextPaint);
}

public SKBitmap ExtractBitmap()
Expand All @@ -78,10 +87,7 @@ public SKBitmap ExtractBitmap()

public void Dispose()
{
if (ownsTextPaint)
{
textPaint.Dispose();
}
textPaint.Dispose();
canvas.Dispose();
if (!bitmapExtracted)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@
<PackageReference Include="SkiaSharp" Version="2.88.3" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="KnowledgePicker.WordCloud.Tests" />
</ItemGroup>

</Project>
15 changes: 15 additions & 0 deletions src/KnowledgePicker.WordCloud/Utilities/ColorUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Drawing;

namespace KnowledgePicker.WordCloud.Utilities
{
internal static class ColorUtil
{
/// <summary>
/// Converts <see cref="Color"/> to hex string.
/// </summary>
public static string ToHexString(this Color c)
{
return $"#{c.R:X2}{c.G:X2}{c.B:X2}";
}
}
}
10 changes: 9 additions & 1 deletion src/KnowledgePicker.WordCloud/WordCloudGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using KnowledgePicker.WordCloud.Drawing;
using KnowledgePicker.WordCloud.Layouts;
using KnowledgePicker.WordCloud.Primitives;
using KnowledgePicker.WordCloud.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
Expand Down Expand Up @@ -76,7 +77,14 @@ public TBitmap Draw()
{
// Draw words.
foreach (var item in items)
engine.Draw(item.Location, item.Measured, item.Entry.Word, item.Entry.Count, colorizer?.GetColorAsHex());
{
engine.Draw(
item.Location,
item.Measured,
item.Entry.Word,
item.Entry.Count,
colorizer?.GetColor(item)?.ToHexString());
}
return engine.ExtractBitmap();
});
}
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 35dfd09

Please sign in to comment.