Feature Navigation for PopupTemplate attached to overlapping Graphic - arcgis

I have a MapView with two point graphics with identical lat/long:
var view = new MapView(...)
view.graphics.add(new Graphic({
geometry: {
type: "point",
longitude: "-90",
latitude: "40"
},
symbol: { type: "simple-marker", ... },
popupTemplate: { title: "some title" }
});
view.graphics.add(new Graphic({
geometry: {
type: "point",
longitude: "-90",
latitude: "40"
},
symbol: { type: "simple-marker", ... },
popupTemplate: { title: "some title" }
});
What I want is to be able to toggle between popups of the two graphics with navigation controls. I had previously been able to do this in API version up to 4.9, but since upgrading to 4.10+ this behavior is no longer there. Below are pictures of the issue:
(version 4.6 https://i.stack.imgur.com/ve5AZ.png )
(version 4.12 https://i.stack.imgur.com/vQ4Gg.png )
Simply changing API versions resulted in these differences in navigation controls being displayed.

Related

Is it possible to substitute Vue.extend with new Vue?

I am working on a Quasar project and I am having a problem. I need to access from external javascript to the properties and methods of the Vue component.
const vue = Vue.extend({
name: 'PageIndex',
data() {
return {
accessToken:
'myToken',
mapStyle: 'mapbox://styles/mapbox/streets-v11',
coordinates: { lng: -82.42642875898966, lat: 23.11975881338755 },
barbershopsSource: {
type: 'FeatureCollection',
features: [
{
type: 'Feature',
properties: {
title: 'Foo'
},
geometry: {
type: 'Point',
coordinates: [-82.42644475189455, 23.119620627441506]
}
},
{
type: 'Feature',
properties: {
title: 'Bar'
},
geometry: {
type: 'Point',
coordinates: [-82.42193696725194, 23.124402891576594]
}
},
{
type: 'Feature',
properties: {
title: 'Baz'
},
geometry: {
type: 'Point',
coordinates: [-82.43414198682088, 23.115900071933567]
}
}
]
}
};
},
components: {},
methods: {
createMap() {
mapboxgl.accessToken = this.accessToken;
const map = new mapboxgl.Map({
container: 'map',
style: this.mapStyle, // stylesheet location
center: this.coordinates, // starting position [lng, lat]
zoom: 15 // starting zoom
});
const source = this.barbershopsSource;
map.on('load', function() {
console.log('Map loaded');
//I want to have access to the component properties here
});
map.on('click', 'barbershops', function(e) {
console.log('Barbershop clicked:', e.lngLat);
});
}
},
mounted() {
this.createMap();
}
});
export default vue;
I know that access to properties is pretty simple, but the thing is that by default and I don't know why, Quasar uses Vue.extend to create the components. If I substitute
const vue = Vue.extend
by
const vue = new Vue
I can access to properties, but the component view isn't loaded.
Any help would be greatly appreciated
The way it works is, quasar takes App.vue as the entry point and loads the generated compiled javascript. The app is created there.
There is only one app running.
You add functionality to your vue app by extend the app.
You create app once in App.vue and add functionality to it by extending.

ArcGIS JS API: make circle not zoom

I have a ArcGIS JavaScript API map. On map click I want to display a circle and highlight all the points within that circle.
However, when I create the circle and zoom in the map, the circle zooms in as well. How can I get the circle to stay the same pixel radius no matter what the zoom level of the map?
<script>
require([
"esri/Map",
"esri/layers/GeoJSONLayer",
"esri/views/MapView",
"esri/widgets/Zoom",
"esri/core/watchUtils",
"esri/geometry/geometryEngine"
], function (Map, GeoJSONLayer, MapView, Zoom, watchUtils, {buffer}) {
const url =
"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson";
const template = {
title: "Earthquake Info",
content: "Magnitude {mag} {type} hit {place} on {time}",
fieldInfos: [
{
fieldName: "time",
format: {
dateFormat: "short-date-short-time"
}
}
]
};
const renderer = {
type: "simple",
field: "mag",
symbol: {
type: "simple-marker",
color: "orange",
outline: {
color: "white"
}
},
visualVariables: [
{
type: "size",
field: "mag",
stops: [
{
value: 2.5,
size: "4px"
},
{
value: 8,
size: "40px"
}
]
}
]
};
const geojsonLayer = new GeoJSONLayer({
url: url,
copyright: "USGS Earthquakes",
popupTemplate: template,
renderer: renderer //optional
});
const map = new Map({
basemap: "gray",
layers: [geojsonLayer]
});
const view = new MapView({
container: "viewDiv",
center: [-168, 46],
zoom: 3,
map: map
});
let csvLayerView;
let highlight;
let resultFeatures;
view.whenLayerView(geojsonLayer).then(layerView => {
csvLayerView = layerView;
});
view.on("click", ({mapPoint}) => {
const geom = buffer(mapPoint, 500, "miles");
view.graphics.removeAll();
view.graphics.add({
geometry: geom,
symbol: {
type: "simple-fill",
color: [51, 51, 204, 0.2],
style: "solid",
outline: {
color: "white",
width: 1
}
}
});
const query = geojsonLayer.createQuery();
query.geometry = geom;
csvLayerView.queryObjectIds(query).then(oids => {
if (highlight) {
highlight.remove();
}
highlight = csvLayerView.highlight(oids);
return csvLayerView.queryFeatures(query);
}).then(({features}) => {
resultFeatures = features;
});
});
});
</script>
The circle that you create, using a 500 miles buffer of the click point, is a polygon. So naturally will be the same one no matter what zoom level you have. In other words, represent a geographic area so it can not change based on the zoom level.
On contrary, in the same example you have the points that represent the earthquakes, that are represented with a orange circle. Because it is a symbol that represents a geographic place, it keeps the size in pixels for all zoom levels.
Resuming, you can not make the 500 miles buffer area, represented by the polygon, to change with the zoom levels, because it is an area.

ReactMapGL add points from geoJSON

I'm trying to add geoJSON points to my ReactMapGL but it doesn't seem to be rendering...there aren't any errors from console either
my code is as follows
const Map = ({ question, updateCurrent }) => {
const [viewport, setViewport] = useState({
width: 400,
height: 400,
latitude: -41.189,
longitude: 175.309,
zoom: 4.49,
})
const mapData = {
features: [
{
type: 'Feature',
properties: {
name: 'Canterbury',
},
geometry: {
coordinates: [172.479644, -43.475418],
type: 'Point',
},
id: '28682b312c41375af64f65b452c4c32c',
},
{
type: 'Feature',
properties: {
name: 'Southland',
},
geometry: {
coordinates: [167.905597, -45.838703],
type: 'Point',
},
id: '317db867d0fc3c2f629cf4cea1df3077',
},
{
type: 'Feature',
properties: {
name: 'Gisborne',
},
geometry: {
coordinates: [177.926385, -38.53651],
type: 'Point',
},
id: '3b30468c228e2ee576cc1943f86dfe75',
},
{
type: 'Feature',
properties: {
name: 'Manawatu - Wanganui',
},
geometry: {
coordinates: [175.434562, -39.524608],
type: 'Point',
},
id: '79df70a0e4371c7eb0d7db4db9a86b06',
},
{
type: 'Feature',
properties: {
name: 'West Coast',
},
geometry: {
coordinates: [172.185093, -41.514477],
type: 'Point',
},
id: '7f471be1cdfe51a2b5d7ca0c5c826c64',
},
{
type: 'Feature',
properties: {
name: 'Nelson / Tasman / Marlborough',
},
geometry: {
coordinates: [172.981906, -41.267511],
type: 'Point',
},
id: '806c715276e1ef82edd796e5934f8e4a',
},
{
type: 'Feature',
properties: {
name: 'Wellington - Wairarapa',
},
geometry: {
coordinates: [175.486838, -41.197457],
type: 'Point',
},
id: '9768592cef2eee2dc7f6e874e1944084',
},
],
type: 'FeatureCollection',
}
return (
<Container>
<ReactMapGL
{...viewport}
width="80vw"
height="70vh"
mapStyle="mapbox://styles/mapbox/light-v9"
onViewportChange={nextViewport => setViewport(nextViewport)}
mapboxApiAccessToken={MAPBOX_TOKEN}
>
<Source id="New Zealand" type="geojson" data={mapData} />
<Layer
id="anything"
type="fill"
source="New Zealand"
paint={{ 'fill-color': '#228b22', 'fill-opacity': 0.4 }}
/>
</ReactMapGL>
</Container>
)
}
My current output is
And my expected output is this (From mapbox Studio)
Could someone help me out please? I can't seem to find too much info about this
Your source data consists of only points yet in your Layer you've set type="fill". Fill type only applies to polygons not points or lines. You'll want to add either a circle or symbol layer instead for points.

cytoscape.js: How to prevent adjacent taxi edges from overlapping

I'm attempting to use a Dagre layout and taxi edges in cytoscape.js to show how nodes connect to other nodes. However, in some cases, due to how the corners of the edges can overlap, it appears that a node has multiple parents, where it actually has only one.
I've tried changing some of the taxi style settings for the edges, but since those are applied to all edges, I still experience the same issue (just in a different spot). Is there a configuration setting I'm missing that will prevent these unrelated edges from overlapping? Barring that, is there a way to change, say, the taxi-turn setting for only some edges? (To make it more complex, this will need to work with arbitrary nodes/edges provided by a user, so I'm unable to handle specific, one-off issues.)
I've reproduced the issue here: https://stackblitz.com/edit/react-rj7ln4?file=index.js
Specifically, the edges in question are from the last two nodes in the first column.
Styles, including configuration for taxi settings
const styles = [
// disable the visible selector when clicking to pan
{
selector: "core",
style: {
"active-bg-opacity": 0
}
},
// basic styling for nodes
{
selector: "node",
style: {
"background-clip": "none",
shape: "rectangle",
"background-opacity": 0,
"font-family": "serif"
}
},
// disable overlay when clicking on nodes or edges
{
selector: "node, edge",
style: {
"overlay-opacity": 0.1
}
},
// basic styles for edges
{
selector: "edge, edge:selected",
style: {
"line-color": "rgb(143,156,173)",
"curve-style": "taxi",
"edge-distances": "node-position",
"taxi-direction": "horizontal",
"taxi-turn": "75%",
"taxi-turn-min-distance": "30px",
"target-endpoint": "outside-to-node",
"target-arrow-shape": "triangle",
"target-arrow-color": "rgb(143,156,173)",
"target-distance-from-node": 15
}
},
// hide the boundary around compound nodes
{
selector: "node:parent",
style: {
opacity: 0.91
}
}
];
Array of nodes and edges used to reproduce
const elements = [
{
data: {
id: "A",
title: "A"
}
},
{
data: {
id: "B",
title: "B"
}
},
{
data: {
id: "C",
title: "C"
}
},
{
data: {
id: "D",
title: "D"
}
},
{
data: {
id: "E",
title: "E"
}
},
{
data: {
id: "F",
title: "F"
}
},
{
data: {
id: "AD",
source: "A",
target: "D"
}
},
{
data: {
id: "BD",
source: "B",
target: "D"
}
},
{
data: {
id: "CE",
source: "C",
target: "E"
}
},
{
data: {
id: "DF",
source: "D",
target: "F"
}
},
{
data: {
id: "EF",
source: "E",
target: "F"
}
}
];
Cytoscape.js version: 3.10.0
Browsers & versions: Firefox 70.0.1 / Chrome 78.0.3904.97 on macOS 10.14.6

Refreshing a rallychart

I have a Rally SDK 2.0p5 app that displays a chart. When the user selects an option, the data will be updated and I would like to refresh the chart. But instead of redrawing, it will place a new chart beneath. What is the proper syntax?
// Configure and Add the chart
this.add(
{
xtype: 'rallychart',
height: 400,
id: 'chart',
chartConfig: {
chart: {
},
title: {
text: 'My Chart',
align: 'center'
},
xAxis: [
{
categories: ['M0','M1','M2','M3','M4','M5'],
title: {
text: 'Interval'
}
}
],
yAxis: {
title: {
text: yText
}
},
series: [ { type: 'column',
name: yText,
data: mCount } ],
plotOptions : {
column: {
color: '#F00'
},
series : {
animation : {
duration : 2000,
easing : 'swing'
}
}
}
}
}
);
You need to remove the 1st chart before adding the new one.
redrawChart: function() {
this.remove('#chart');
this.add({...});
}
It's often better to just update the chart in place. HighCharts is the charting library that's included in the App SDK. HighCharts will even animate your changes. Cool!!! Look here for the list of methods that operate on charts. You can add series, change data, change axis limits, control the zoom, etc.