Select to view content in your preferred language

Change a Point Symbol's Size by a Relative Amount

133
2
Jump to solution
Friday
DavidSolari
MVP Regular Contributor

I need to take the 2D symbol of an arbitrary point Graphic and multiply the size by 1.5. Is there a sensible way to do this for all potential symbol types? I have simple and picture markers down but I have no idea where to begin with CIM Symbols, and I assume the 3D symbols need shader stuff to scale properly. I have the option of shoving this symbol in a separate layer and applying the scaling there if that works better.

const scale = 1.5
let baseSize: number;
if (pointGraphic.symbol.size != null) {
  baseSize = pointGraphic.symbol.size * scale;
  pointGraphic.symbol.size = baseSize;
} else if ((pointGraphic.symbol as any)?.width != null) {
  const baseWidth = (pointGraphic.symbol as any).width * scale;
  const baseHeight = (pointGraphic.symbol as any).height * scale;
  baseSize = baseWidth > baseHeight ? baseWidth : baseHeight;
  (pointGraphic.symbol as any).width = baseWidth;
  (pointGraphic.symbol as any).height = baseHeight;
} else if ((pointGraphic.symbol as any)?.font != null) {
  baseSize = (pointGraphic.symbol as any).font.size * scale;
  (pointGraphic.symbol as any).font.size = baseSize;
} else {
  // TODO: Scale CIM point
}

 

0 Kudos
1 Solution

Accepted Solutions
AnneFitz
Esri Regular Contributor

For CIMSymbol, check out the cimSymbolUtils module - specifically the getCIMSymbolSize and scaleCIMSymbolTo functions. Use these together to get the size of the symbol, then multiple the size by 1.5, and reapply it using scaleCIMSymbolTo.

View solution in original post

2 Replies
AnneFitz
Esri Regular Contributor

For CIMSymbol, check out the cimSymbolUtils module - specifically the getCIMSymbolSize and scaleCIMSymbolTo functions. Use these together to get the size of the symbol, then multiple the size by 1.5, and reapply it using scaleCIMSymbolTo.

DavidSolari
MVP Regular Contributor

Ah, there's always something buried in the support code! I'll have to test this later but I think this does the trick:

/** Scale a point symbol and return the original and new sizes. */
export async function scalePointSymbol(point: Graphic, to?: number, by?: number): Promise<[number, number]> {
    if (!to && !by) {
        throw new Error("Must provide at least one of \"to\" or \"by\"");
    }
    let prevSize: number;
    let newSize: number = to ?? undefined;
    switch (point.symbol.type) {
        case "simple-marker":
        case "point-3d":
            prevSize = point.symbol.size;
            newSize ||= prevSize * by;
            point.symbol.size = newSize;
            break;
        case "text":
            prevSize = point.symbol.font.size;
            newSize ||= prevSize * by;
            point.symbol.font.size = newSize;
            break;
        case "picture-marker":
            const w = point.symbol.width;
            const h = point.symbol.height;
            const isWider = w > h;
            prevSize = isWider ? w : h;
            if (newSize) {
                point.symbol.width = isWider ? newSize : newSize * (w / h);
                point.symbol.height = isWider ? newSize * (h / w) : newSize;
            } else {
                point.symbol.width *= by;
                point.symbol.height *= by;
                newSize = prevSize * by;
            }
            break;
        case "web-style":
            point.symbol = await point.symbol.fetchCIMSymbol();
        case "cim":
            prevSize = getCIMSymbolSize(point.symbol);
            newSize ||= prevSize * by;
            scaleCIMSymbolTo(point.symbol, newSize, { preserveOutlineWidth: false });
            break;
        default:
            throw new Error(`Graphic does not have a point symbol (${point.symbol.type})`);
    }
    return [prevSize, newSize]
}
0 Kudos