Skip to content

Commit 13f5818

Browse files
committed
Add specific colorizer
1 parent 500897a commit 13f5818

File tree

13 files changed

+216
-71
lines changed

13 files changed

+216
-71
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@
4343
var wcg = new WordCloudGenerator<SKBitmap>(wordCloud, engine, layout, colorizer);
4444
```
4545

46+
You can also use `SpecificColorizer` to colorize specific words with chosen colors:
47+
48+
```cs
49+
var colorizer = new SpecificColorizer(
50+
new Dictionary<string, Color>
51+
{
52+
["KnowledgePicker"] = Color.FromArgb(0x0f3057),
53+
["WordCloud"] = Color.FromArgb(0xe25a5a)
54+
},
55+
fallback: new RandomColorizer()); // fallback argument is optional
56+
```
57+
4658
5. Now we can *arrange* the topic cloud:
4759

4860
```cs
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
1+
using KnowledgePicker.WordCloud.Primitives;
2+
using System.Drawing;
3+
14
namespace KnowledgePicker.WordCloud.Coloring
25
{
36
public interface IColorizer
47
{
58
/// <summary>
6-
/// Gets the hex string color for text.
9+
/// Gets color for the specified <paramref name="item"/>.
710
/// </summary>
8-
/// <returns>Hex string color in format #RRGGBB.</returns>
9-
string GetColorAsHex();
11+
/// <param name="item">The item being colored.</param>
12+
/// <returns>
13+
/// Can return <see langword="null"/> to use the default color
14+
/// (<see cref="WordCloudInput.TextColor"/>).
15+
/// </returns>
16+
Color? GetColor(LayoutItem item);
1017
}
1118
}
Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
using KnowledgePicker.WordCloud.Primitives;
12
using System;
2-
using System.Diagnostics.CodeAnalysis;
33
using System.Drawing;
44

55
namespace KnowledgePicker.WordCloud.Coloring
@@ -11,38 +11,22 @@ public class RandomColorizer : IColorizer
1111
{
1212
private readonly Random random;
1313

14-
public RandomColorizer() : this(Environment.TickCount) { }
15-
16-
public RandomColorizer(int seed)
14+
public RandomColorizer()
1715
{
18-
random = new Random(seed);
16+
random = new Random();
1917
}
2018

21-
/// <summary>
22-
/// Gets a random color.
23-
/// </summary>
24-
[SuppressMessage("Security", "CA5394:Do not use insecure randomness")]
25-
private Color GetRandomColor()
26-
{
27-
return Color.FromArgb(random.Next(0, 255), random.Next(0, 255), random.Next(0, 255));
28-
}
29-
30-
/// <summary>
31-
/// Converts Color to hex string.
32-
/// </summary>
33-
private static string ConvertToHexString(Color c)
19+
public RandomColorizer(int seed)
3420
{
35-
return $"#{c.R:X2}{c.G:X2}{c.B:X2}";
21+
random = new Random(seed);
3622
}
3723

38-
/// <summary>
39-
/// Gets the randon RGB color as a hex string.
40-
/// </summary>
41-
public string GetColorAsHex()
24+
public Color? GetColor(LayoutItem item)
4225
{
43-
Color c = GetRandomColor();
44-
return ConvertToHexString(c);
26+
return Color.FromArgb(
27+
random.Next(0, 255),
28+
random.Next(0, 255),
29+
random.Next(0, 255));
4530
}
46-
4731
}
4832
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using KnowledgePicker.WordCloud.Primitives;
2+
using System.Collections.Generic;
3+
using System.Drawing;
4+
5+
namespace KnowledgePicker.WordCloud.Coloring
6+
{
7+
/// <summary>
8+
/// Colors specific words with provided colors.
9+
/// </summary>
10+
public class SpecificColorizer : IColorizer
11+
{
12+
private readonly IReadOnlyDictionary<string, Color> mapping;
13+
private readonly IColorizer? fallback;
14+
15+
public SpecificColorizer(
16+
IReadOnlyDictionary<string, Color> mapping,
17+
IColorizer? fallback = null)
18+
{
19+
this.mapping = mapping;
20+
this.fallback = fallback;
21+
}
22+
23+
public Color? GetColor(LayoutItem item)
24+
{
25+
if (mapping.TryGetValue(item.Entry.Word, out var color))
26+
{
27+
return color;
28+
}
29+
return fallback?.GetColor(item);
30+
}
31+
}
32+
}

src/KnowledgePicker.WordCloud/Drawing/SkGraphicEngine.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,17 @@ namespace KnowledgePicker.WordCloud.Drawing
1010
public sealed class SkGraphicEngine : IGraphicEngine<SKBitmap>
1111
{
1212
private readonly SKCanvas canvas;
13+
private readonly SKColor defaultColor;
1314
private readonly SKPaint textPaint;
1415
private readonly WordCloudInput wordCloud;
15-
private readonly bool ownsTextPaint;
1616
private bool bitmapExtracted;
1717

1818
private SkGraphicEngine(ISizer sizer, WordCloudInput wordCloud,
1919
SKPaint textPaint)
2020
{
2121
Sizer = sizer;
2222
this.wordCloud = wordCloud;
23+
defaultColor = textPaint.Color;
2324
this.textPaint = textPaint;
2425
Bitmap = new SKBitmap(wordCloud.Width, wordCloud.Height);
2526
canvas = new SKCanvas(Bitmap);
@@ -31,13 +32,13 @@ public SkGraphicEngine(ISizer sizer, WordCloudInput wordCloud,
3132
Sizer = sizer;
3233
Bitmap = new SKBitmap(wordCloud.Width, wordCloud.Height);
3334
canvas = new SKCanvas(Bitmap);
35+
defaultColor = SKColor.Parse(wordCloud.TextColor);
3436
textPaint = new SKPaint
3537
{
36-
Color = SKColor.Parse(wordCloud.TextColor),
38+
Color = defaultColor,
3739
Typeface = font,
3840
IsAntialias = antialias
3941
};
40-
ownsTextPaint = true;
4142
this.wordCloud = wordCloud;
4243
}
4344

@@ -60,14 +61,22 @@ public void Draw(PointD location, RectangleD measured, string text, int count, s
6061
// https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/graphics/skiasharp/basics/text.
6162
textPaint.TextSize = (float)Sizer.GetFontSize(count);
6263
if (colorHex != null)
64+
{
6365
textPaint.Color = SKColor.Parse(colorHex);
66+
}
67+
else
68+
{
69+
textPaint.Color = defaultColor;
70+
}
6471
canvas.DrawText(text, (float)(location.X - measured.Left),
6572
(float)(location.Y - measured.Top), textPaint);
6673
}
6774

6875
public IGraphicEngine<SKBitmap> Clone()
6976
{
70-
return new SkGraphicEngine(Sizer, wordCloud, textPaint);
77+
var clonedTextPaint = textPaint.Clone();
78+
clonedTextPaint.Color = defaultColor;
79+
return new SkGraphicEngine(Sizer, wordCloud, clonedTextPaint);
7180
}
7281

7382
public SKBitmap ExtractBitmap()
@@ -78,10 +87,7 @@ public SKBitmap ExtractBitmap()
7887

7988
public void Dispose()
8089
{
81-
if (ownsTextPaint)
82-
{
83-
textPaint.Dispose();
84-
}
90+
textPaint.Dispose();
8591
canvas.Dispose();
8692
if (!bitmapExtracted)
8793
{

src/KnowledgePicker.WordCloud/KnowledgePicker.WordCloud.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,8 @@
3030
<PackageReference Include="SkiaSharp" Version="2.88.3" />
3131
</ItemGroup>
3232

33+
<ItemGroup>
34+
<InternalsVisibleTo Include="KnowledgePicker.WordCloud.Tests" />
35+
</ItemGroup>
36+
3337
</Project>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System.Drawing;
2+
3+
namespace KnowledgePicker.WordCloud.Utilities
4+
{
5+
internal static class ColorUtil
6+
{
7+
/// <summary>
8+
/// Converts <see cref="Color"/> to hex string.
9+
/// </summary>
10+
public static string ToHexString(this Color c)
11+
{
12+
return $"#{c.R:X2}{c.G:X2}{c.B:X2}";
13+
}
14+
}
15+
}

src/KnowledgePicker.WordCloud/WordCloudGenerator.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using KnowledgePicker.WordCloud.Drawing;
33
using KnowledgePicker.WordCloud.Layouts;
44
using KnowledgePicker.WordCloud.Primitives;
5+
using KnowledgePicker.WordCloud.Utilities;
56
using System;
67
using System.Collections.Generic;
78
using System.Linq;
@@ -76,7 +77,14 @@ public TBitmap Draw()
7677
{
7778
// Draw words.
7879
foreach (var item in items)
79-
engine.Draw(item.Location, item.Measured, item.Entry.Word, item.Entry.Count, colorizer?.GetColorAsHex());
80+
{
81+
engine.Draw(
82+
item.Location,
83+
item.Measured,
84+
item.Entry.Word,
85+
item.Entry.Count,
86+
colorizer?.GetColor(item)?.ToHexString());
87+
}
8088
return engine.ExtractBitmap();
8189
});
8290
}
509 KB
Loading
486 KB
Loading

0 commit comments

Comments
 (0)