Skip to content

Commit

Permalink
Merge pull request #234 from dymaptic/feature/231_text_symbol_offsets
Browse files Browse the repository at this point in the history
Implemented all properties on TextSymbol, unit tests and Label sample
  • Loading branch information
TimPurdum authored Oct 6, 2023
2 parents cbc472f + f43b845 commit 3411b82
Show file tree
Hide file tree
Showing 12 changed files with 457 additions and 19 deletions.
35 changes: 35 additions & 0 deletions samples/dymaptic.GeoBlazor.Core.Sample.Shared/Pages/Labels.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
@page "/labels"
<PageTitle>Labels</PageTitle>
<h1>Labels</h1>

<div class="links-div">
<a class="btn btn-secondary" target="_blank" href="https://developers.arcgis.com/javascript/latest/sample-code/labels-basic/">ArcGIS API for JavaScript Reference</a>
<a class="btn btn-primary" target="_blank" href="https://www.arcgis.com/home/item.html?id=372b7caa8fe340b0a6300df93ef18a7e">Labels BaseMap</a>
</div>
<p class="instructions">
Demonstrates how to add labels to a map.
</p>

<MapView Center="@(new Point(-116.925, 34.2501))" Zoom="12" Class="map-view">
<WebMap>
<PortalItem Id="372b7caa8fe340b0a6300df93ef18a7e" />
<FeatureLayer>
<PortalItem Id="6012738cd1c74582a5f98ea30ae9876f" />
<Label LabelPlacement="above-center">
<TextSymbol Color="@(new MapColor("green"))"
BackgroundColor="@(new MapColor(213, 184, 255, 0.75))"
BorderLineColor="@(new MapColor("green"))"
BorderLineSize="1"
YOffset="5">
<MapFont Family="Playfair Display" Size="12" Weight="bold" />
</TextSymbol>
<LabelExpressionInfo Expression="$feature.MARKER_ACTIVITY" />
</Label>
<SimpleRenderer>
<SimpleMarkerSymbol Color="@(new MapColor(0, 100, 0, 0.6))" Size="3">
<Outline Color="@(new MapColor(0, 0, 0, 0.1))" Width="0.5" />
</SimpleMarkerSymbol>
</SimpleRenderer>
</FeatureLayer>
</WebMap>
</MapView>
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
new("widgets", "Widgets", "oi-location"),
new("basemaps", "Basemaps", "oi-map"),
new("feature-layers", "Feature Layers", "oi-layers"),
new("labels", "Labels", "oi-text"),
new("popups", "Popups", "oi-chat"),
new("popup-actions", "Popup Actions", "oi-bullhorn"),
new("bookmarks", "Bookmarks", "oi-bookmark"),
Expand Down
32 changes: 31 additions & 1 deletion src/dymaptic.GeoBlazor.Core/Components/Layers/Label.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components;
using dymaptic.GeoBlazor.Core.Components.Symbols;
using Microsoft.AspNetCore.Components;


namespace dymaptic.GeoBlazor.Core.Components.Layers;
Expand All @@ -13,6 +14,35 @@ namespace dymaptic.GeoBlazor.Core.Components.Layers;
/// </summary>
public class Label : LayerObject
{
/// <summary>
/// Parameterless constructor for use as a Blazor component.
/// </summary>
public Label()
{
}

/// <summary>
/// Constructor for generating in code.
/// </summary>
/// <param name="labelPlacement">
/// The position of the label.
/// </param>
/// <param name="labelExpression">
/// Defines the labels for a MapImageLayer.
/// </param>
/// <param name="labelExpressionInfo">
/// Defines the labels for a <see cref="FeatureLayer" />.
/// </param>
public Label(string? labelPlacement = null, string? labelExpression = null,
LabelExpressionInfo? labelExpressionInfo = null)
{
#pragma warning disable BL0005 // Component parameter should not be set outside of its component.
LabelPlacement = labelPlacement;
LabelExpression = labelExpression;
LabelExpressionInfo = labelExpressionInfo;
#pragma warning restore BL0005
}

/// <summary>
/// The position of the label.
/// </summary>
Expand Down
201 changes: 200 additions & 1 deletion src/dymaptic.GeoBlazor.Core/Components/Symbols/TextSymbol.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using dymaptic.GeoBlazor.Core.Objects;
using dymaptic.GeoBlazor.Core.Serialization;
using Microsoft.AspNetCore.Components;
using System.Text.Json.Serialization;

Expand Down Expand Up @@ -42,8 +43,47 @@ public TextSymbol()
/// <param name="font">
/// The <see cref="MapFont" /> used to style the text.
/// </param>
/// <param name="angle">
/// The angle of the text. 0 is horizontal and the angle moves clockwise.
/// </param>
/// <param name="backgroundColor">
/// The background color of the label's bounding box.
/// </param>
/// <param name="borderLineColor">
/// The border color of the label's bounding box.
/// </param>
/// <param name="borderLineSize">
/// The border size or width of the label's bounding box.
/// </param>
/// <param name="horizontalAlignment">
/// Adjusts the horizontal alignment of the text in multi-lines. Default value is Center.
/// </param>
/// <param name="kerning">
/// Determines whether to adjust the spacing between characters in the text string. Default value is true.
/// </param>
/// <param name="lineHeight">
/// The height of the space between each line of text. Only applies to multiline text.
/// </param>
/// <param name="lineWidth">
/// The maximum length in points for each line of text. This value is a string expressing size in points or pixels (e.g.
/// </param>
/// <param name="rotated">
/// Determines whether every character in the text string is rotated. Default value is false.
/// </param>
/// <param name="verticalAlignment">
/// Adjusts the vertical alignment of the text. Default value is Baseline.
/// </param>
/// <param name="xOffset">
/// The offset on the x-axis in points. This value is a string expressing size in points or pixels (e.g. "12px", "12pt"),
/// </param>
/// <param name="yOffset">
/// The offset on the y-axis in points. This value is a string expressing size in points or pixels (e.g. "12px", "12pt"),
/// </param>
public TextSymbol(string text, MapColor? color = null, MapColor? haloColor = null, int? haloSize = null,
MapFont? font = null)
MapFont? font = null, double? angle = null, MapColor? backgroundColor = null, MapColor? borderLineColor = null,
double? borderLineSize = null, HorizontalAlignment? horizontalAlignment = null, bool? kerning = null,
double? lineHeight = null, string? lineWidth = null, bool? rotated = null,
VerticalAlignment? verticalAlignment = null, string? xOffset = null, string? yOffset = null)
{
AllowRender = false;
#pragma warning disable BL0005
Expand All @@ -52,11 +92,63 @@ public TextSymbol(string text, MapColor? color = null, MapColor? haloColor = nul
HaloColor = haloColor;
HaloSize = haloSize;
Font = font;
Angle = angle;
BackgroundColor = backgroundColor;
BorderLineColor = borderLineColor;
BorderLineSize = borderLineSize;
HorizontalAlignment = horizontalAlignment;
Kerning = kerning;
LineHeight = lineHeight;
LineWidth = lineWidth;
Rotated = rotated;
VerticalAlignment = verticalAlignment;
XOffset = xOffset;
YOffset = yOffset;
#pragma warning restore BL0005
}

/// <inheritdoc />
public override string Type => "text";

/// <summary>
/// The angle of the text. 0 is horizontal and the angle moves clockwise.
/// </summary>
/// <remarks>
/// This property is currently not supported in 3D SceneViews.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public double? Angle { get; set; }

/// <summary>
/// The background color of the label's bounding box.
/// </summary>
/// <remarks>
/// This property is currently not supported when labelling a FeatureLayer polyline with a "curved" labelPosition.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public MapColor? BackgroundColor { get; set; }

/// <summary>
/// The border color of the label's bounding box.
/// </summary>
/// <remarks>
/// This property is currently not supported when labelling a FeatureLayer polyline with a "curved" labelPosition.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public MapColor? BorderLineColor { get; set; }

/// <summary>
/// The border size or width of the label's bounding box.
/// </summary>
/// <remarks>
/// This property is currently not supported when labelling a FeatureLayer polyline with a "curved" labelPosition.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public double? BorderLineSize { get; set; }

/// <summary>
/// The color of the text symbol's halo.
Expand All @@ -71,13 +163,93 @@ public TextSymbol(string text, MapColor? color = null, MapColor? haloColor = nul
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public int? HaloSize { get; set; }

/// <summary>
/// Adjusts the horizontal alignment of the text in multi-lines. Default value is Center.
/// </summary>
/// <remarks>
/// This property only applies when TextSymbol is not used for labeling purposes. The horizontalAlignment for labels is inferred from the labelPlacement value.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public HorizontalAlignment? HorizontalAlignment { get; set; }

/// <summary>
/// Determines whether to adjust the spacing between characters in the text string. Default value is true.
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? Kerning { get; set; }

/// <summary>
/// The height of the space between each line of text. Only applies to multiline text.
/// This property can be considered as a multiplier of the default value of 1.0 (e.g. a value of 2.0 will be two times the height of the default height). The range of possible values is: 0.1 - 4.0. If a value of 0 is specified, the default value of 1.0 will be used.
/// Default Value: 1.0
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public double? LineHeight { get; set; }

/// <summary>
/// The maximum length in points for each line of text. This value is a string expressing size in points or pixels (e.g. "12px", "12pt"), which defaults to points.
/// The default value is 192 points. The range of possible values is: 32px - 512px.
/// If text extends farther than the lineWidth value, then the line will break at the whitespace before the text that extends past the limit if possible, and a new line will be created.
/// </summary>
/// <remarks>
/// Known Limitations:
/// - This property is currently not supported in 3D SceneViews.
/// - The default value is subject to change in future releases.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? LineWidth { get; set; }

/// <summary>
/// Determines whether every character in the text string is rotated. Default value is false.
/// </summary>
/// <remarks>
/// This property is currently not supported in 3D SceneViews.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public bool? Rotated { get; set; }

/// <summary>
/// The text string to display in the view.
/// </summary>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? Text { get; set; }

/// <summary>
/// Adjusts the vertical alignment of the text. Default value is Baseline.
/// </summary>
/// <remarks>
/// This property only applies when TextSymbol is not used for labeling purposes. The verticalAlignment for labels is inferred from the labelPlacement value.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public VerticalAlignment? VerticalAlignment { get; set; }

/// <summary>
/// The offset on the x-axis in points. This value is a string expressing size in points or pixels (e.g. "12px", "12pt"), which defaults to points.
/// </summary>
/// <remarks>
/// This property is currently not supported in 3D SceneViews.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? XOffset { get; set; }

/// <summary>
/// The offset on the y-axis in points. This value is a string expressing size in points or pixels (e.g. "12px", "12pt"), which defaults to points.
/// </summary>
/// <remarks>
/// This property is currently not supported in 3D SceneViews.
/// </remarks>
[Parameter]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public string? YOffset { get; set; }

/// <summary>
/// The <see cref="MapFont" /> used to style the text.
Expand Down Expand Up @@ -134,4 +306,31 @@ internal override SymbolSerializationRecord ToSerializationRecord()
Text = Text, HaloColor = HaloColor, HaloSize = HaloSize, MapFont = Font
};
}
}

/// <summary>
/// The horizontal alignment for a text symbol's text.
/// </summary>
[JsonConverter(typeof(EnumToKebabCaseStringConverter<HorizontalAlignment>))]
public enum HorizontalAlignment
{
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
Left,
Right,
Center
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}

/// <summary>
/// The vertical alignment for a text symbol's text.
/// </summary>
[JsonConverter(typeof(EnumToKebabCaseStringConverter<VerticalAlignment>))]
public enum VerticalAlignment
{
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
Baseline,
Top,
Middle,
Bottom
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
}
7 changes: 4 additions & 3 deletions src/dymaptic.GeoBlazor.Core/Scripts/arcGisJsInterop.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,13 +124,14 @@ import ColorRamp from "@arcgis/core/rest/support/ColorRamp";
import MultipartColorRamp from "@arcgis/core/rest/support/MultipartColorRamp";
import AlgorithmicColorRamp from "@arcgis/core/rest/support/AlgorithmicColorRamp";
import Renderer from "@arcgis/core/renderers/Renderer";
import Color from "@arcgis/core/Color";

export let arcGisObjectRefs: Record<string, Accessor> = {};
export let graphicsRefs: Record<string, Graphic> = {};
export let dotNetRefs = {};
export let queryLayer: FeatureLayer;
export let blazorServer: boolean = false;
export { projection, geometryEngine, Graphic };
export { projection, geometryEngine, Graphic, Color };
let notifyExtentChanged: boolean = true;
let uploadingLayers: Array<string> = [];

Expand Down Expand Up @@ -1099,9 +1100,9 @@ export async function openPopup(viewId: string, options: any | null): Promise<vo
jsOptions.content = widgetContent as Widget;
}
}
view.popup.open(jsOptions);
await view.openPopup(jsOptions);
} else {
view.popup.open();
await view.openPopup();
}
} catch (error) {
logError(error, options.viewId);
Expand Down
18 changes: 15 additions & 3 deletions src/dymaptic.GeoBlazor.Core/Scripts/jsBuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -444,10 +444,22 @@ export function buildJsSymbol(symbol: DotNetSymbol | null): Symbol | null {
case "text":
let dotNetTextSymbol = symbol as DotNetTextSymbol;
let jsTextSymbol = new TextSymbol({
color: buildJsColor(dotNetTextSymbol.color) ?? "black",
angle: dotNetTextSymbol.angle ?? undefined,
backgroundColor: buildJsColor(dotNetTextSymbol.backgroundColor) ?? undefined,
borderLineColor: buildJsColor(dotNetTextSymbol.borderLineColor) ?? undefined,
borderLineSize: dotNetTextSymbol.borderLineSize ?? undefined,
color: buildJsColor(dotNetTextSymbol.color) ?? undefined,
haloColor: buildJsColor(dotNetTextSymbol.haloColor) ?? undefined,
haloSize: dotNetTextSymbol.haloSize ?? undefined,
text: dotNetTextSymbol.text ?? undefined
horizontalAlignment: dotNetTextSymbol.horizontalAlignment as any ?? undefined,
kerning: dotNetTextSymbol.kerning ?? undefined,
lineHeight: dotNetTextSymbol.lineHeight ?? undefined,
lineWidth: dotNetTextSymbol.lineWidth ?? undefined,
rotated: dotNetTextSymbol.rotated ?? undefined,
text: dotNetTextSymbol.text ?? undefined,
verticalAlignment: dotNetTextSymbol.verticalAlignment as any ?? undefined,
xoffset: dotNetTextSymbol.xOffset ?? undefined,
yoffset: dotNetTextSymbol.yOffset ?? undefined
});
if (hasValue(dotNetTextSymbol.font)) {
jsTextSymbol.font = buildJsFont(dotNetTextSymbol.font);
Expand Down Expand Up @@ -589,7 +601,7 @@ export function buildJsRasterStretchRenderer(dotNetRasterStretchRenderer: DotNet
rasterStretchRenderer.outputMin = dotNetRasterStretchRenderer.outputMin;
}
if (hasValue(dotNetRasterStretchRenderer.stretchType)) {
rasterStretchRenderer.stretchType = dotNetRasterStretchRenderer.stretchType;
rasterStretchRenderer.stretchType = dotNetRasterStretchRenderer.stretchType as any;
}
if (hasValue(dotNetRasterStretchRenderer.statistics)) {
rasterStretchRenderer.statistics = dotNetRasterStretchRenderer.statistics;
Expand Down
Loading

0 comments on commit 3411b82

Please sign in to comment.