Select to view content in your preferred language

Sketch Widget keep Tooltip after graphic is created

279
4
Jump to solution
05-22-2024 01:57 PM
SebastianKrings
Occasional Contributor

Hi,

I included the sketch widget into my app enabling SketchTooltipOptions.
The shown label is great. Unfortunately this label will be gone after the graphic is created (doubleclick on last point).

Is it somehow possible to keep this label or to add a custom label to these graphics?
Until now I only find samples on how to for features but not for graphics on a graphicslayer as the sketch widget produces them.

Hope someone can help me.

0 Kudos
1 Solution

Accepted Solutions
AndreV
by
Occasional Contributor

Hi,

here is our workaround:

  1. create new GraphicLayer for text symbols
  2. catch the following events: "create": ev.state === "complete" || ev.state === "cancel", "update" ev.state === "active", "undo", "redo", "delete"
  3. in event callback remove all graphics from text symbol layer and create every text symbol for all graphics in sketch graphic layer

3 can be achieved with this code:

const textLayer = new GraphicsLayer({
	id: "sketch1",
	title: "text symbols",
	internal: true,
});

export const defaultTextSymbol = {
	type: "text", // autocasts as new TextSymbol()
	color: "white",
	haloColor: "black",
	haloSize: "1px",
	font: {
		size: 10,
		weight: "bold",
	},
};

const drawLabel = (text, labelAnchor, symbolProps = null) => {
	const labelSymbol = { ...defaultTextSymbol, text: text };
	const label = new Graphic({
		geometry: labelAnchor,
		symbol: symbolProps ? { ...labelSymbol, ...symbolProps } : labelSymbol,
	});
	textLayer.graphics.add(label);
};


export const redrawTextLayer = () => {
	textLayer.graphics.removeAll();
	sketchLayer.graphics.forEach((graphic) => {
		redrawLabel(graphic);
	});
};


const redrawLabel = (graphic) => {
	let labelAnchor;
	let geom = graphic.geometry;
	let attr = graphic.attributes;
	if (geom.type === "point") {
		labelAnchor = geom;
	} else if (geom.type === "polyline") {
		labelAnchor = geom.extent.center;
	} else if (geom.type === "polygon") {
		labelAnchor = geom.centroid;
	}

	drawLabel(text, labelAnchor);
};

 

 

gdi-hohenlohekreis.de

View solution in original post

4 Replies
AndreV
by
Occasional Contributor

Hi,

here is our workaround:

  1. create new GraphicLayer for text symbols
  2. catch the following events: "create": ev.state === "complete" || ev.state === "cancel", "update" ev.state === "active", "undo", "redo", "delete"
  3. in event callback remove all graphics from text symbol layer and create every text symbol for all graphics in sketch graphic layer

3 can be achieved with this code:

const textLayer = new GraphicsLayer({
	id: "sketch1",
	title: "text symbols",
	internal: true,
});

export const defaultTextSymbol = {
	type: "text", // autocasts as new TextSymbol()
	color: "white",
	haloColor: "black",
	haloSize: "1px",
	font: {
		size: 10,
		weight: "bold",
	},
};

const drawLabel = (text, labelAnchor, symbolProps = null) => {
	const labelSymbol = { ...defaultTextSymbol, text: text };
	const label = new Graphic({
		geometry: labelAnchor,
		symbol: symbolProps ? { ...labelSymbol, ...symbolProps } : labelSymbol,
	});
	textLayer.graphics.add(label);
};


export const redrawTextLayer = () => {
	textLayer.graphics.removeAll();
	sketchLayer.graphics.forEach((graphic) => {
		redrawLabel(graphic);
	});
};


const redrawLabel = (graphic) => {
	let labelAnchor;
	let geom = graphic.geometry;
	let attr = graphic.attributes;
	if (geom.type === "point") {
		labelAnchor = geom;
	} else if (geom.type === "polyline") {
		labelAnchor = geom.extent.center;
	} else if (geom.type === "polygon") {
		labelAnchor = geom.centroid;
	}

	drawLabel(text, labelAnchor);
};

 

 

gdi-hohenlohekreis.de
DavidDrennan
New Contributor II
catch the following events: "create": ev.state === "complete" || ev.state === "cancel", "update" ev.state === "active", "undo", "redo", "delete"

Hey AndreV! We're trying to do the same thing as the OP, but when you say the above, is this on the actual Sketch widget instance?

https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Sketch.html#events-summar...

EDIT: Also, part of the example you gave doesn't work as text is undefined:

 

const redrawLabel = (graphic) => {
	let labelAnchor;
	let geom = graphic.geometry;
	let attr = graphic.attributes;
	if (geom.type === "point") {
		labelAnchor = geom;
	} else if (geom.type === "polyline") {
		labelAnchor = geom.extent.center;
	} else if (geom.type === "polygon") {
		labelAnchor = geom.centroid;
	}
      // won't work since text is never defined
	drawLabel(text, labelAnchor);
}
0 Kudos
SebastianKrings
Occasional Contributor

hm unfortunately my reply wasnt sent, but luckily esri drafted it for me.

Heres my original post:

 

this is awesome. Thank you very much.

Just did some small changes. Possibly due to api changes of methods one parameter wasnt there any more and may got a default now in the newest api version. I just removed it.
I also added map.add(textLayer); to make the lextlayer visible.

As text of course I put my thing:

const length = geometryEngine.geodesicLength(riverGeometry, "miles");
AndreV
by
Occasional Contributor

Hi David,

yes we took the events from SketchWidget instance, as you described in your link. Alternatively, there are the same events on the SketchWidgetViewModel

https://developers.arcgis.com/javascript/latest/api-reference/esri-widgets-Sketch-SketchViewModel.ht...

your right, the code snippet I provided, doesn't work from scratch. I took our code and deleted many lines for this post. You can define text by yourself and assign it to graphic's attributes, something like this:

const redrawLabel = (graphic) => {
	let labelAnchor;
	let geom = graphic.geometry;
	let attr = graphic.attributes;
	if (geom.type === "point") {
		labelAnchor = geom;
	} else if (geom.type === "polyline") {
		labelAnchor = geom.extent.center;
	} else if (geom.type === "polygon") {
		labelAnchor = geom.centroid;
	}
        let text = attr.userInputText 
        //or any other attribute you defined and filled in ev.create (ev.state === "complete") 
	drawLabel(text, labelAnchor);
}

 

gdi-hohenlohekreis.de
0 Kudos