I am new to Arcgis maps and using ArcGIS Javascript 4.2 library. Currently the features are showing up on the map and I am trying to go to feature and open it's popup programmatically. below is my code to query the features which is working fine.
var query = layer.createQuery();
query.where = "key= " + dataItem.key+ "";
query.returnGeometry = true;
query.returnCentroid = true;
query.returnQueryGeometry = true;
layer.queryFeatures(query).then(function (results) {
//I am getting the feature results here.
//trying to navigate to feature and open popup
});
Note: I tried using the following code from documentation which is working fine but I don't have the center as the features are polylines in my case.
view.goTo({center: [-126, 49]})
First, View goTo method has several options, including just using a geometry wich I think would be a better option for your case, zoom to a polyline.
Second to open the popup you just need to use the open method and you can pass there the features to show.
Check this example I put for you, has both suggestions,
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>ArcGIS API for JavaScript Hello World App</title>
<style>
html,
body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#selectDiv {
height: 30px;
width: 100%;
margin: 5px;
}
#cableNameSelect {
height: 30px;
width: 300px;
}
#cableGoToButton {
height: 30px;
width: 100px;
}
#viewDiv {
height: 500px;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.15/esri/css/main.css">
</head>
<body>
<div id="selectDiv">
<select id="cableNameSelect"></select>
<button id="cableGoToButton">GO TO</button>
</div>
<div id="viewDiv">
</div>
<script src="https://js.arcgis.com/4.15/"></script>
<script>
require([
'esri/Map',
'esri/views/MapView',
'esri/layers/FeatureLayer'
], function (Map, MapView, FeatureLayer) {
const cableNameSelect = document.getElementById("cableNameSelect");
const cableGoToButton = document.getElementById("cableGoToButton");
const map = new Map({
basemap: 'hybrid'
});
const view = new MapView({
container: 'viewDiv',
map: map,
zoom: 10,
center: {
latitude: 47.4452,
longitude: -121.4234
}
});
view.popup.set("dockOptions", {
buttonEnabled: false,
position: "top-right"
});
const layer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/cables/FeatureServer/0",
popupTemplate: {
title: "{NAME}",
outFields: ["*"],
content: [{
type: 'fields',
fieldInfos: [
{
fieldName: "length"
},
{
fieldName: "owners"
},
{
fieldName: "rfs"
}
]
}],
}
});
map.add(layer);
layer.queryFeatures({
where: "1=1",
outFields: ["Name"],
returnGeometry: false
}).then(function(results) {
for(const graphic of results.features) {
cableNameSelect.appendChild(new Option(graphic.attributes.Name, graphic.attributes.Name));
}
});
cableGoToButton.onclick = function() {
if (!cableNameSelect.value) {
return;
}
cableGoToButton.disabled = true;
layer.queryFeatures({
where: `Name='${cableNameSelect.value}'`,
outFields: ["*"],
returnGeometry: true
}).then(function (results) {
cableGoToButton.disabled = false;
if (!results.features) {
return;
}
view.goTo(results.features[0].geometry);
view.popup.open({
features: [results.features[0]]
})
})
};
});
</script>
</body>
</html>
Related
I am using webview to show the videos but the issue I am facing that in IOS the the html video tag is detected by navigator.mediaSession but in android the video tag works but the navigator.mediaSession does works. I am using navigator.mediaseesion to show the video notification. the video tag is embedded in wistia.
Has anyone face that issue.
<WebView
ref={ref}
style={style}
javaScriptEnabled={true}
mediaPlaybackRequiresUserAction={false}
builtInZoomControls={false}
allowsInlineMediaPlayback={true}
scalesPageToFit={false}
scrollEnabled={false}
bounces={false}
contentMode='mobile'
onMessage={onMessage}
source={{
html: WistiaWebPlayer(
videoId,
receiver,
isMiniPlayer,
autoPlay,
playFrom,
title,
showThankYouMessage,
type,
thumbnail,
description
),
baseUrl: 'https://wistia.com',
}}
/>
Html code
export default (videoId, receiver, miniPlayer, autoPlay, playFrom, title, showThankYouMessage, type, thumbnail, description) => `
<!DOCTYPE html>
<html style="height: 100%; width: 100%; padding: 0; margin:0;">
<head>
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1"
/>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<style>
html,
body {
overflow-x: hidden;
overflow-y: hidden;
padding: 0;
margin: 0;
}
body {
position: relative;
padding: 0;
margin: 0;
background-color: black;
}
</style>
<title>${title}</title>
<script>
alert(JSON.stringify(navigator.mediaDevices))
if ("mediaSession" in navigator) {
navigator.mediaSession.metadata = new MediaMetadata({
title: "${title}",
artist: "",
album: "${description}",
artwork: [
{ src: "${thumbnail}" ,sizes: '1028x128', type: 'image/png' },
]
});
}else{
alert('gg')
let a= navigator
console.log('kk123',navigator)
navigator.mediaSession.metadata = new MediaMetadata({
title: "${title}",
artist: "",
album: "${description}",
artwork: [
{ src: "${thumbnail}" ,sizes: '1028x128', type: 'image/png' },
]
});
}
</script>
</head>
<body>
<script
src="https://fast.wistia.com/embed/medias/${videoId}.jsonp"
async
></script>
<script
src="https://fast.wistia.com/assets/external/E-v1.js"
async
></script>
<div
class="wistia_responsive_padding"
style="padding:56.25% 0 0 0;position:relative;"
>
<div
class="wistia_responsive_wrapper"
style="height:100%;left:0;position:absolute;top:0;width:100%;"
>
<div
class="wistia_embed wistia_async_${videoId} playerColor=red seo=true videoFoam=true"
style="height:100%;position:relative;width:100%"
allowfullscreen mozallowfullscreen webkitallowfullscreen oallowfullscreen msallowfullscreen
>
<div
class="wistia_swatch"
style="height:100%;left:0;opacity:0;overflow:hidden;position:absolute;top:0;transition:opacity 200ms;width:100%;"
>
<img
src="https://fast.wistia.com/embed/medias/${videoId}/swatch"
style="filter:blur(5px);height:100%;object-fit:contain;width:100%;"
alt=""
onload="this.parentNode.style.opacity=1;"
/>
</div>
</div>
</div>
</div>
<script>
window._wq = window._wq || [];
var playerOptions = {
}
if(${type == "meditation"}){
var playerOptions = {
endVideoBehavior: "loop"
};
}
if(${miniPlayer} == true){
playerOptions = {
controlsVisibleOnLoad: false,
playButton: false,
smallPlayButton: false,
volumeControl:false,
fullscreenButton:false,
playbar:false,
settingsControl:false
}
}
playerOptions.autoPlay = ${autoPlay};
if (${showThankYouMessage}) {
playerOptions.plugin = {
"postRoll-v1": {
text: "Thank you for watching",
rewatch: true
}
}
}
_wq.push({
id: "${videoId}",
options: playerOptions,
onReady: function(video) {
video.time(${playFrom});
${receiver}.addEventListener('message', function(data) {
let command = data.data;
let speed = 1;
if (command.includes("speed")) {
speed = Number(command.split(":")[1]) || 1;
command = "speed";
}
switch (command) {
case "play":
video.play();
break;
case "pause":
video.pause();
break;
case "speed":
video.playbackRate(speed);
break;
}
});
video.bind("cancelfullscreen", function() {
video.play();
});
video.bind('secondchange', function(s) {
window.ReactNativeWebView.postMessage(JSON.stringify({seconds:s, percentage:video.percentWatched(),completed:false}));
});
video.bind("end", function() {
window.ReactNativeWebView.postMessage(JSON.stringify({seconds:video.secondsWatched(), percentage:video.percentWatched(),completed:true}));
});
video.bind("play", function() {
window.ReactNativeWebView.postMessage(JSON.stringify({isPlaying:true}));
});
video.bind("pause", function() {
window.ReactNativeWebView.postMessage(JSON.stringify({isPaused:true}));
});
}
});
</script>
</body>
</html>
`;
Currently working on showing a popup in the map using ESRI ArcGIS API for JavaScript 4.15.
But that is missing the Maximize button which was available with ArcGIS API for JavaScript 3.35
Is there any config to be set to show the same.
As far as I know the new API does not have that capability out of the box. But no worries, you can implement it by adding a custom action to the popup.
See the example I made for you to get an idea.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>Popup actions | ArcGIS API for JavaScript 4.18</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.18/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.18/"></script>
<script>
require(["esri/Map", "esri/layers/FeatureLayer", "esri/views/MapView"], function (
Map,
FeatureLayer,
MapView
) {
const map = new Map({
basemap: "gray-vector"
});
const view = new MapView({
container: "viewDiv",
map: map,
center: [-117.08, 34.1],
zoom: 11
});
const toggleFullScreenAction = {
type: "toggle",
title: "Full Screen",
id: "toggle-full-screen",
className: "esri-icon-maximize"
};
view.popup.actions.add(toggleFullScreenAction);
const template = {
title: "Trail run",
content: "{name}"
};
featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/TrailRuns/FeatureServer/0",
outFields: ["*"],
popupTemplate: template
});
map.add(featureLayer);
function toggleFullScreen() {
if (!document.fullscreenElement) {
document.getElementsByClassName('esri-popup__main-container')[0].requestFullscreen()
.catch(err => {
alert(`Error attempting to enable full-screen mode: ${err.message} (${err.name})`);
});
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
}
}
}
view.popup.on("trigger-action", function (event) {
if (event.action.id === "toggle-full-screen") {
toggleFullScreen();
}
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
To run the snippet, copy and save as an html file. The full screen action does not work in the snippet, I guess because it is embedded, not sure though.
I am working on a cytoscape.js graph in browser. I want to show some information of nodes (e.g. node label) as the mouse hovers over the nodes in a cytoscape graph. The following code is working for console.log() but I want to show the information in the browser:
cy.on('mouseover', 'node', function(evt){
var node = evt.target;
console.log( 'mouse on node' + node.data('label') );
});
Please help !
Cytoscape.js has popper.js with tippy. I can give you a working exapmle for popper.js:
popper with tippy:
document.addEventListener("DOMContentLoaded", function() {
var cy = (window.cy = cytoscape({
container: document.getElementById("cy"),
style: [{
selector: "node",
style: {
content: "data(id)"
}
},
{
selector: "edge",
style: {
"curve-style": "bezier",
"target-arrow-shape": "triangle"
}
}
],
elements: {
nodes: [{
data: {
id: "a"
}
}, {
data: {
id: "b"
}
}],
edges: [{
data: {
id: "ab",
source: "a",
target: "b"
}
}]
},
layout: {
name: "grid"
}
}));
function makePopper(ele) {
let ref = ele.popperRef(); // used only for positioning
ele.tippy = tippy(ref, { // tippy options:
content: () => {
let content = document.createElement('div');
content.innerHTML = ele.id();
return content;
},
trigger: 'manual' // probably want manual mode
});
}
cy.ready(function() {
cy.elements().forEach(function(ele) {
makePopper(ele);
});
});
cy.elements().unbind('mouseover');
cy.elements().bind('mouseover', (event) => event.target.tippy.show());
cy.elements().unbind('mouseout');
cy.elements().bind('mouseout', (event) => event.target.tippy.hide());
});
body {
font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
font-size: 14px
}
#cy {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 1;
}
h1 {
opacity: 0.5;
font-size: 1em;
font-weight: bold;
}
<head>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://unpkg.com/popper.js#1.14.7/dist/umd/popper.js"></script>
<script src="https://cdn.jsdelivr.net/npm/cytoscape-popper#1.0.4/cytoscape-popper.min.js"></script>
<script src="https://unpkg.com/tippy.js#4.0.1/umd/index.all.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/tippy.js#4.0.1/index.css" />
</head>
<body>
<div id="cy"></div>
</body>
Hi guys the Stephan's answer won't work using module based code like in React.js so I'm giving you an alternative without tippy
popper.css // popper style
.popper-div { // fill free to modify as you prefer
position: relative;
background-color: #333;
color: #fff;
border-radius: 4px;
font-size: 14px;
line-height: 1.4;
outline: 0;
padding: 5px 9px;
}
App.js
import cytoscape from "cytoscape";
import popper from "cytoscape-popper"; // you have to install it
import "./popper.css";
cytoscape.use(popper);
const cy = cytoscape({....});
cy.elements().unbind("mouseover");
cy.elements().bind("mouseover", (event) => {
event.target.popperRefObj = event.target.popper({
content: () => {
let content = document.createElement("div");
content.classList.add("popper-div");
content.innerHTML = event.target.id();
document.body.appendChild(content);
return content;
},
});
});
cy.elements().unbind("mouseout");
cy.elements().bind("mouseout", (event) => {
if (event.target.popper) {
event.target.popperRefObj.state.elements.popper.remove();
event.target.popperRefObj.destroy();
}
});
I'm looking for a way of getting QTip to concurrently display tooltips for each node in a Cytoscape.js graph, such that they are always displayed and anchored to the nodes in the graph without the user having to click or mouseover the node.
I got close with the code below:
$(document).ready(function(){
cy.nodes().qtip({
content: function(){ return 'Station: ' + this.id() +
'</br> Next Train: ' + this.data('nextTrain') +
'</br> Connections: ' + this.degree();
},
hide: false,
show: {
when: false,
ready: true
}
})
})
The above code displays tooltips on $(document).ready, but they are all located at one node in the Cytoscape graph and they disappear when I zoom in or pan at all.
The goal is to have tooltips anchored to each node in my graph such that when I zoom in and pan around they remain fixed to that node. I'm not sure if there is an easier way to do this just using Cytoscape (i.e., multi-feature labelling).
I'm using Qtip2, jQuery-2.0.3 and the most recent release of cytoscape.js
Any help is much appreciated.
EDIT: If you want to create these elements automatically, use a function and a loop to iterate over cy.nodes():
var makeTippy = function (nodeTemp, node) {
return tippy(node.popperRef(), {
html: (function () {
let div = document.createElement('div');
// do things in div
return div;
})(),
trigger: 'manual',
arrow: true,
placement: 'right',
hideOnClick: false,
multiple: true,
sticky: true
}).tooltips[0];
};
var nodes = cy.nodes();
for (var i = 0; i < nodes.length; i++) {
var tippy = makeTippy(nodes[i]);
tippy.show();
}
If you want a sticky qTip, I would instead recommend the cytoscape extension for popper.js and specificly the tippy version (sticky divs):
document.addEventListener('DOMContentLoaded', function() {
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
style: [{
selector: 'node',
style: {
'content': 'data(id)'
}
},
{
selector: 'edge',
style: {
'curve-style': 'bezier',
'target-arrow-shape': 'triangle'
}
}
],
elements: {
nodes: [{
data: {
id: 'a'
}
},
{
data: {
id: 'b'
}
}
],
edges: [{
data: {
source: 'a',
target: 'b'
}
}]
},
layout: {
name: 'grid'
}
});
var a = cy.getElementById('a');
var b = cy.getElementById('b');
var makeTippy = function(node, text) {
return tippy(node.popperRef(), {
html: (function() {
var div = document.createElement('div');
div.innerHTML = text;
return div;
})(),
trigger: 'manual',
arrow: true,
placement: 'bottom',
hideOnClick: false,
multiple: true,
sticky: true
}).tooltips[0];
};
var tippyA = makeTippy(a, 'foo');
tippyA.show();
var tippyB = makeTippy(b, 'bar');
tippyB.show();
});
body {
font-family: helvetica neue, helvetica, liberation sans, arial, sans-serif;
font-size: 14px
}
#cy {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
z-index: 1;
}
h1 {
opacity: 0.5;
font-size: 1em;
font-weight: bold;
}
/* makes sticky faster; disable if you want animated tippies */
.tippy-popper {
transition: none !important;
}
<!DOCTYPE>
<html>
<head>
<title>Tippy > qTip</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<script src="https://unpkg.com/popper.js"></script>
<script src="cytoscape-popper.js"></script>
<script src="https://unpkg.com/tippy.js#2.0.9/dist/tippy.all.js"></script>
<link rel="stylesheet" href="https://unpkg.com/tippy.js#2.0.9/dist/tippy.css" />
<script src="https://cdn.jsdelivr.net/npm/cytoscape-popper#1.0.2/cytoscape-popper.js"></script>
</head>
<body>
<h1>cytoscape-popper tippy demo</h1>
<div id="cy"></div>
</body>
</html>
I think popper is just easier to handle when having the divs 'stick around'
I have the following code of a map using api google, I have tested the code in several html editor and its work perfectly, but when i upload in my web page doesn’t work. The map appears all zoomed in some random point in the ocean. I create an article in Joomla 1.5.20, paste the code. Its shows right in the preview but not in the web page. I disable filtering and use none editor and still won’t work. Thanks for the help.
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { height: 100% }
</style>
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?key=AIzaSyBInlv7FuwtKGhzBP0oISDoB2Iu79HNrPU&sensor=false">
</script>
<script type="text/javascript">
var map;
// lets define some vars to make things easier later
var kml = {
a: {
name: "Productor",
url: "https://maps.google.hn/maps/ms?authuser=0&vps=2&hl=es&ie=UTF8&msa=0&output=kml&msid=200984447026903306654.0004c934a224eca7c3ad4"
},
b: {
name: "A&S",
url: "https://maps.google.hn/maps/ms?ie=UTF8&authuser=0&msa=0&output=kml&msid=200984447026903306654.0004c94bac74cf2304c71"
}
// keep adding more if ye like
};
// initialize our goo
function initializeMap() {
var options = {
center: new google.maps.LatLng(13.324182,-87.080071),
zoom: 9,
mapTypeId: google.maps.MapTypeId.TERRAIN
}
map = new google.maps.Map(document.getElementById("map_canvas"), options);
var ctaLayer = new google.maps.KmlLayer('https://maps.google.hn/maps/ms?authuser=0&vps=5&hl=es&ie=UTF8&oe=UTF8&msa=0&output=kml&msid=200984447026903306654.0004c94bc3bce6f638aa1');
ctaLayer.setMap(map);
var ctaLayer = new google.maps.KmlLayer('https://maps.google.hn/maps/ms?authuser=0&vps=2&ie=UTF8&msa=0&output=kml&msid=200984447026903306654.0004c94ec7e838242b67d');
ctaLayer.setMap(map);
createTogglers();
};
google.maps.event.addDomListener(window, 'load', initializeMap);
// the important function... kml[id].xxxxx refers back to the top
function toggleKML(checked, id) {
if (checked) {
var layer = new google.maps.KmlLayer(kml[id].url, {
preserveViewport: true,
suppressInfoWindows: true
});
google.maps.event.addListener(layer, 'click', function(kmlEvent) {
var text = kmlEvent.featureData.description;
showInContentWindow(text);
});
function showInContentWindow(text) {
var sidediv = document.getElementById('content_window');
sidediv.innerHTML = text;
}
// store kml as obj
kml[id].obj = layer;
kml[id].obj.setMap(map);
}
else {
kml[id].obj.setMap(null);
delete kml[id].obj;
}
};
// create the controls dynamically because it's easier, really
function createTogglers() {
var html = "<form><ul>";
for (var prop in kml) {
html += "<li id=\"selector-" + prop + "\"><input type='checkbox' id='" + prop + "'" +
" onclick='highlight(this,\"selector-" + prop + "\"); toggleKML(this.checked, this.id)' \/>" +
kml[prop].name + "<\/li>";
}
html += "<li class='control'><a href='#' onclick='removeAll();return false;'>" +
"Limpiar el Mapa<\/a><\/li>" +
"<\/ul><\/form>";
document.getElementById("toggle_box").innerHTML = html;
};
// easy way to remove all objects
function removeAll() {
for (var prop in kml) {
if (kml[prop].obj) {
kml[prop].obj.setMap(null);
delete kml[prop].obj;
}
}
};
// Append Class on Select
function highlight(box, listitem) {
var selected = 'selected';
var normal = 'normal';
document.getElementById(listitem).className = (box.checked ? selected: normal);
};
</script>
<style type="text/css">
.selected { font-weight: bold; }
</style>
</head>
<body>
<div id="map_canvas" style="width: 80%; height: 400px; float:left"></div>
<div id="toggle_box" style="position: absolute; top: 100px; right: 640px; padding: 10px; background: #fff; z-index: 5; "></div>
<div id="content_window" style="width:10%; height:10%; float:left"></div>
</body>
</html>
The problem was solve using dropbox to host the KML files insted google maps.