There are some polylines here. I want to click it to highlight it and make it wider. I have found a method to highlight it, but I don't know how to make this polyline wider
https://codepen.io/zhedream/pen/WNMdMOW?editors=1000
// 渲染器
let renderer = jsonUtils.fromJSON({
"type": "classBreaks",
"field": "Name",
"defaultSymbol": {
"type": "esriSLS",
"color": [0, 0, 0, 255],
"width": 6
},
"visualVariables": [
{
"type": "color",
"field": "value",
"stops": [
{
width: 10,
"color": [0, 255, 0, 255],
"value": 0
},
{
width: 20,
"color": [163, 255, 52, 255],
"value": 20
},
{
width: 30,
"color": [236, 255, 18, 255],
"value": 30
}
]
}
]
});
// generate polyline
let data = [
{ value: 1, width: 6, active: 1 },
{ value: 10, width: 6, active: 0 },
{ value: 20, width: 6, active: 0 },
{ value: 30, width: 6, active: 0 }
];
let firstCoor = [-111.3, 52.68];
let polylineList = [];
data.forEach((v, index) => {
let nextCoor = [firstCoor[0] + 1, firstCoor[1] + 1];
polylineList.push({
geometry: {
type: "polyline", // autocasts as new Polyline()
paths: [
firstCoor,
nextCoor
]
},
// symbol: lineSymbol, // i think this is the symbol should override the renderer symbol, but not
attributes: {
value: v.value,
width: v.width,
active: v.active
}
});
firstCoor = nextCoor.slice(0);
});
// 图层
let fLayer = new FeatureLayer({
fields: fields,
objectIdField: "objectId",
source: polylineList,
geometryType: "polyline",
title: "layerId",
id: "layerId",
spatialReference: {
wkid: 4326
},
renderer: renderer
});
I tried applyEdits.updateFeatures to modify it, but it didn't work
// is ok
map.layers.items[0].source.items[0].geometry = {
type: "polyline",
paths: [
[-111.3, 52.68],
[-120, 49.5]
]
};
// width not work
graphic = map.layers.items[0].source.items[0];
graphic.symbol = {
type: "simple-line", // autocasts as SimpleLineSymbol()
width: 40
};
Solved! Go to Solution.
I'm not sure if you can mess with what's already there, but you could add a temporary graphic over the top, and remove it if the click is anywhere else. This works but could use some help in making it the same color scheme:
<html>
<head>
<meta charset="utf-8" />
<meta
content="initial-scale=1,maximum-scale=1,user-scalable=no"
name="viewport"
/>
<title>Intro to graphics | Sample | ArcGIS API for JavaScript 4.23</title>
<link
href="https://js.arcgis.com/4.23/esri/themes/light/main.css"
rel="stylesheet"
/>
<script src="https://js.arcgis.com/4.23/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
var liness;
require([
"esri/Map",
"esri/views/MapView",
"esri/Graphic",
"esri/layers/FeatureLayer",
"esri/renderers/support/jsonUtils",
"dojo/_base/connect"
], (Map, MapView, Graphic, FeatureLayer, jsonUtils, dc) => {
window.map = new Map({
basemap: "hybrid"
});
window.view = new MapView({
center: [-80, 35],
container: "viewDiv",
map: map,
zoom: 3
});
/****************************
* Create a polyline graphic
****************************/
const polyline = {
type: "polyline", // autocasts as new Polyline()
paths: [
[-111.3, 52.68],
[-98, 49.5]
]
};
// 样式符号
var lineSymbol = {
type: "simple-line", // autocasts as SimpleLineSymbol()
color: [226, 119, 40],
width: 20
};
liness = lineSymbol;
console.log(lineSymbol);
// generate polyline
let data = [
{ value: 1, width: 6, active: 1 },
{ value: 10, width: 6, active: 0 },
{ value: 20, width: 6, active: 0 },
{ value: 30, width: 6, active: 0 }
];
let firstCoor = [-111.3, 52.68];
let polylineList = [];
data.forEach((v, index) => {
let nextCoor = [firstCoor[0] + 1, firstCoor[1] + 1];
polylineList.push({
geometry: {
type: "polyline", // autocasts as new Polyline()
paths: [
firstCoor,
nextCoor
]
},
// symbol: lineSymbol, // i think this is the symbol should override the renderer symbol, but not
attributes: {
value: v.value,
width: v.width,
active: v.active
}
});
firstCoor = nextCoor.slice(0);
});
// 渲染器 style
let renderer = jsonUtils.fromJSON({
"type": "classBreaks",
"field": "Name",
"defaultSymbol": {
"type": "esriSLS",
"color": [0, 0, 0, 255],
"width": 6
},
"visualVariables": [
{
"type": "color",
"field": "value",
"stops": [
{
width: 10,
"color": [0, 255, 0, 255],
"value": 0
},
{
width: 20,
"color": [163, 255, 52, 255],
"value": 20
},
{
width: 30,
"color": [236, 255, 18, 255],
"value": 30
}
]
}
]
});
// 属性字段
let fields = [
{
name: "objectId",
alias: "objectId",
type: "oid"
},
{
name: "value",
alias: "value",
type: "double"
},
{
name: "active",
alias: "active",
type: "integer"
}
];
// 图层
let fLayer = new FeatureLayer({
fields: fields,
objectIdField: "objectId",
source: polylineList,
geometryType: "polyline",
title: "layerId",
id: "layerId",
spatialReference: {
wkid: 4326
},
renderer: renderer
});
let polylineHighlightSymbol = {
type: "simple-line", // autocasts as SimpleLineSymbol()
color: [226, 119, 40],
width: 10
};
map.add(fLayer);
// dc.connect(fLayer, "onMouseOver", () => {
// console.log("asdasd");
// });
let unHighLight = null;
var highlightGraphic;
view.on("click", (e) => {
if (unHighLight && unHighLight.remove) {
unHighLight.remove();
}
view.hitTest(e).then(function(response) {
let results = response.results;
console.log("results", results);
if (highlightGraphic != null) {
view.graphics.remove(highlightGraphic);
}
if (results.length > 0) {
let graphic = results[0].graphic;
highlightGraphic = new Graphic({
geometry: graphic.geometry,
symbol: polylineHighlightSymbol
});
view.graphics.add(highlightGraphic);
view.whenLayerView(graphic.layer).then(function(viewLayer) {
unHighLight = viewLayer.highlight(graphic);
});
console.log(graphic.attributes);
}
else {
view.graphics.remove(highlightGraphic);
}
});
});
fLayer.when(() => {
console.log("loaded");
});
});
</script>
</head>
<body>
<div id="viewDiv" style="height: calc(100vh - 100px)"></div>
<button onclick="change()">change first polyline</button>
<script>
function change() {
map.layers.items[0].source.items[0].setAttribute("value", 19);
map.layers.items[0].source.items[0].setAttribute("width", 20);
map.layers.items[0].source.items[0].setAttribute("active", 1);
map.layers.items[0].source.items[0].visible = false;
// is ok
map.layers.items[0].source.items[0].geometry = {
type: "polyline",
paths: [
[-111.3, 52.68],
[-120, 49.5]
]
};
// not work
graphic = map.layers.items[0].source.items[0];
graphic.symbol = {
type: "simple-line", // autocasts as SimpleLineSymbol()
width: 40
};
map.layers.items[0].applyEdits({
// deleteFeatures: [
// {
// objectId: 1
// }
// ]
updateFeatures: map.layers.items[0].source.items
// updateFeatures: [
// {
// objectId: 1,
// geometry: {
// type: "polyline",
// paths: [
// [-111.3, 52.68],
// [-100, 49.5]
// ]
// }
// }
// ]
});
}
</script>
</body>
</html>
I'm not sure if you can mess with what's already there, but you could add a temporary graphic over the top, and remove it if the click is anywhere else. This works but could use some help in making it the same color scheme:
<html>
<head>
<meta charset="utf-8" />
<meta
content="initial-scale=1,maximum-scale=1,user-scalable=no"
name="viewport"
/>
<title>Intro to graphics | Sample | ArcGIS API for JavaScript 4.23</title>
<link
href="https://js.arcgis.com/4.23/esri/themes/light/main.css"
rel="stylesheet"
/>
<script src="https://js.arcgis.com/4.23/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<script>
var liness;
require([
"esri/Map",
"esri/views/MapView",
"esri/Graphic",
"esri/layers/FeatureLayer",
"esri/renderers/support/jsonUtils",
"dojo/_base/connect"
], (Map, MapView, Graphic, FeatureLayer, jsonUtils, dc) => {
window.map = new Map({
basemap: "hybrid"
});
window.view = new MapView({
center: [-80, 35],
container: "viewDiv",
map: map,
zoom: 3
});
/****************************
* Create a polyline graphic
****************************/
const polyline = {
type: "polyline", // autocasts as new Polyline()
paths: [
[-111.3, 52.68],
[-98, 49.5]
]
};
// 样式符号
var lineSymbol = {
type: "simple-line", // autocasts as SimpleLineSymbol()
color: [226, 119, 40],
width: 20
};
liness = lineSymbol;
console.log(lineSymbol);
// generate polyline
let data = [
{ value: 1, width: 6, active: 1 },
{ value: 10, width: 6, active: 0 },
{ value: 20, width: 6, active: 0 },
{ value: 30, width: 6, active: 0 }
];
let firstCoor = [-111.3, 52.68];
let polylineList = [];
data.forEach((v, index) => {
let nextCoor = [firstCoor[0] + 1, firstCoor[1] + 1];
polylineList.push({
geometry: {
type: "polyline", // autocasts as new Polyline()
paths: [
firstCoor,
nextCoor
]
},
// symbol: lineSymbol, // i think this is the symbol should override the renderer symbol, but not
attributes: {
value: v.value,
width: v.width,
active: v.active
}
});
firstCoor = nextCoor.slice(0);
});
// 渲染器 style
let renderer = jsonUtils.fromJSON({
"type": "classBreaks",
"field": "Name",
"defaultSymbol": {
"type": "esriSLS",
"color": [0, 0, 0, 255],
"width": 6
},
"visualVariables": [
{
"type": "color",
"field": "value",
"stops": [
{
width: 10,
"color": [0, 255, 0, 255],
"value": 0
},
{
width: 20,
"color": [163, 255, 52, 255],
"value": 20
},
{
width: 30,
"color": [236, 255, 18, 255],
"value": 30
}
]
}
]
});
// 属性字段
let fields = [
{
name: "objectId",
alias: "objectId",
type: "oid"
},
{
name: "value",
alias: "value",
type: "double"
},
{
name: "active",
alias: "active",
type: "integer"
}
];
// 图层
let fLayer = new FeatureLayer({
fields: fields,
objectIdField: "objectId",
source: polylineList,
geometryType: "polyline",
title: "layerId",
id: "layerId",
spatialReference: {
wkid: 4326
},
renderer: renderer
});
let polylineHighlightSymbol = {
type: "simple-line", // autocasts as SimpleLineSymbol()
color: [226, 119, 40],
width: 10
};
map.add(fLayer);
// dc.connect(fLayer, "onMouseOver", () => {
// console.log("asdasd");
// });
let unHighLight = null;
var highlightGraphic;
view.on("click", (e) => {
if (unHighLight && unHighLight.remove) {
unHighLight.remove();
}
view.hitTest(e).then(function(response) {
let results = response.results;
console.log("results", results);
if (highlightGraphic != null) {
view.graphics.remove(highlightGraphic);
}
if (results.length > 0) {
let graphic = results[0].graphic;
highlightGraphic = new Graphic({
geometry: graphic.geometry,
symbol: polylineHighlightSymbol
});
view.graphics.add(highlightGraphic);
view.whenLayerView(graphic.layer).then(function(viewLayer) {
unHighLight = viewLayer.highlight(graphic);
});
console.log(graphic.attributes);
}
else {
view.graphics.remove(highlightGraphic);
}
});
});
fLayer.when(() => {
console.log("loaded");
});
});
</script>
</head>
<body>
<div id="viewDiv" style="height: calc(100vh - 100px)"></div>
<button onclick="change()">change first polyline</button>
<script>
function change() {
map.layers.items[0].source.items[0].setAttribute("value", 19);
map.layers.items[0].source.items[0].setAttribute("width", 20);
map.layers.items[0].source.items[0].setAttribute("active", 1);
map.layers.items[0].source.items[0].visible = false;
// is ok
map.layers.items[0].source.items[0].geometry = {
type: "polyline",
paths: [
[-111.3, 52.68],
[-120, 49.5]
]
};
// not work
graphic = map.layers.items[0].source.items[0];
graphic.symbol = {
type: "simple-line", // autocasts as SimpleLineSymbol()
width: 40
};
map.layers.items[0].applyEdits({
// deleteFeatures: [
// {
// objectId: 1
// }
// ]
updateFeatures: map.layers.items[0].source.items
// updateFeatures: [
// {
// objectId: 1,
// geometry: {
// type: "polyline",
// paths: [
// [-111.3, 52.68],
// [-100, 49.5]
// ]
// }
// }
// ]
});
}
</script>
</body>
</html>
view.on("click", (e) => {
if (unHighLight) {
unHighLight();
unHighLight = null;
}
view.hitTest(e).then(function(response) {
let results = response.results;
let graphics = results.filter(function(result) {
// check if the graphic belongs to the layer of interest
return result.graphic.layer === fLayer;
})
if (graphics.length > 0) {
let graphic = graphics[0].graphic;
highlightGraphic = new Graphic({
geometry: graphic.geometry,
symbol: polylineHighlightSymbol
});
view.graphics.add(highlightGraphic);
view.whenLayerView(graphic.layer).then(function(viewLayer) {
// let highLight = viewLayer.highlight(graphic);
unHighLight = () => {
// highLight.remove();
if (highlightGraphic) {
view.graphics.remove(highlightGraphic);
highlightGraphic = null;
}
}
});
} else {}
});
});
This is a very good idea. It can basically achieve the effect I want - to overwrite the original figure with a new figure
There's a little problem. I don't know how to highlight the new graphics. It would be perfect if I could