Integrating CytoscapeJs with LeafletJs - javascript

I have made a graph component in CytoscapeJS and want to have a map as an overlay. Basically I want to represent the nodes based on their co-ordinates on Map (using LeafletJs).
I have looked into the plugin (cytoscape-mapbox-gl by zakjan) and cytoscape-leaf extension (using this currently).
I am getting this error:
Uncaught TypeError: obj.attachEvent is not a function
Uncaught TypeError: Cannot read properties of undefined (reading 'lat')
Uncaught Error: Map container is already initialized.
I only want to integrate CytoscapeJs with LeafletJS. I don't want to add any tile layer.
Followed all the steps on the Cytoscape-leaf plugin documentation.
I have registered the function, created the instance, added the co-ordinates in the data object,rendered the Map component alongside cytoscape component, Added the lat,lng field in the data object for cytoscape node(Node Position).
cytoscape.use( leaflet );
const map = useRef();
data: {
id: ele.nodeAddr,
label: `IP-${ele.nodeAddr}`,
icon:Server,
type:'parentNode',
status:ele.status,
lat:19.5,
lng:72.8777,
}
const options = {
container: map.current,
// the data field for latitude
latitude: 'lat',
// the data field for longitude
longitude: 'lng'
};
const leaf = cy.leaflet(options);
<div
ref={divRef}
style={{
border: "1px solid",
backgroundColor: "#f5f6fe",
height: '600px',
}}
>
<div ref={map}></div>

My answer is independent of your code and your intended plugins you want to use with cytoscape. It may not answer your question, but it works to some extent that I consider it a good start to use cytoscapeJS within leaflet.
One issue that I found, it wont work with browsers on iOS or ipadOS. I am sorry about that. Help is welcome to solve the issues why Webkit based browsers on iOS/ipadOS do not handle cytoscape's graph like Chrome browsers on android/windows.
Code:
const base_dc = 0.027589;
const lon_ext = 0.5436;
const lat_ext = 0.5436;
const lonmin = 100.3257;
const latmin = 13.4978;
const lon_cor = lon_ext * base_dc;
const lonmax = lonmin + lon_ext;
const lonmid = (lonmin + lonmax) / 2;
const lonmax2 = lonmax + lon_cor;
const latmax = latmin + lat_ext;
const latmid = (latmin + latmax) / 2;
const latlng = { lat: latmin, lng: lonmin };
const latlng2 = { lat: latmax, lng: lonmax2 };
const clatlng = { lat: latmid, lng: lonmid };
const cbottom = { lat: latmin, lng: lonmid };
var zoom = 9;
const myRenderer = L.canvas({ padding: 0.0 }); //svg or canvas
/* Cytoscape global vars */
// must match SVG viewbox w h.
// and width, height of #cyOnSvg DIV
const cy_size = 1600;
const params = {
width: cy_size,
height: cy_size,
latmin: latmin,
latmax: latmax,
lonmin: lonmin,
lonmax: lonmax2
};
// Update CSS to use new cy_size
let root = document.documentElement;
root.style.setProperty("--svg-width", cy_size + "px");
root.style.setProperty("--svg-height", cy_size + "px");
/* choice of maps */
var mymap = L.map("mapid", {
renderer: myRenderer,
preferCanvas: false
}).setView(clatlng, zoom);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "Map data © OpenStreetMap contributors"
}).addTo(mymap);
const svg_pin =
'<svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M12,11.5A2.5,2.5 0 0,1 9.5,9A2.5,2.5 0 0,1 12,6.5A2.5,2.5 0 0,1 14.5,9A2.5,2.5 0 0,1 12,11.5M12,2A7,7 0 0,0 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9A7,7 0 0,0 12,2Z" fill="firebrick"></path></svg>';
const svgpin_Url = encodeURI("data:image/svg+xml;utf-8," + svg_pin);
const svgpin_Icon = L.icon({
iconUrl: svgpin_Url,
iconSize: [24, 24],
iconAnchor: [12, 24],
popupAnchor: [0, -22]
});
var marker2 = L.marker(latlng2, {
renderer: myRenderer,
icon: svgpin_Icon
//draggable: true,
//autoPan: true
}).addTo(mymap);
marker2.bindPopup("<b>Control_UR</b>").openPopup();
marker2.openPopup();
var marker0 = L.marker(latlng, {
renderer: myRenderer,
icon: svgpin_Icon
}).addTo(mymap);
marker0.bindPopup("<b>Control_LL</b>").openPopup();
marker0.openPopup();
/* Embed SVG Element in the web page */
let svgElem = document.createElementNS("http://www.w3.org/2000/svg", "svg");
svgElem.setAttribute("xmlns", "http://www.w3.org/2000/svg");
svgElem.setAttribute("id", "Svg0");
svgElem.setAttribute("preserveAspectRatio", "xMinYMax slice");
svgElem.setAttribute("viewBox", `0 0 ${cy_size} ${cy_size}`);
/* SVGOverlay with foreignObject-div-text */
svgElem.innerHTML = `<foreignObject x="0" y="0" width="100%" height="100%">
<div id="cyOnSvg" style="background-color:rgba(200,200,200,0.25);padding:0;"></div>
<div id="upperlefttext">Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</div>
</foreignObject>`;
// Note: lonmax2 (=lonmax + correction)
const svgElementBounds = [
[latmin, lonmin],
[latmax, lonmax2]
];
const svgobj = L.svgOverlay(svgElem, svgElementBounds, {
renderer: myRenderer,
zIndex: 15,
opacity: 0.65,
interactive: false
}).addTo(mymap);
//svgobj.bindPopup("SVG vector layer");
//var draggable = new L.Draggable(svgElem);
//draggable.enable(); //make draggable (must set=> interactive: true)
/* SVG OK */
/* set events */
mymap.on("click", onMapClick);
//svgobj.on("click", onSvgClick);
/* other useful settings */
mymap.scrollWheelZoom.disable();
const popup = L.popup(); //leaflet popup object
function onMapClick(e) {
popup.setLatLng(e.latlng).setContent(e.latlng.toString()).openOn(mymap);
}
/* -------cytoscape-------- */
function lnglat2xy(lon, lat, pars) {
//let w = pars.width;
//let h = pars.height;
let L = pars.lonmax - pars.lonmin; //lonmax2-lonmin
let B = pars.latmax - pars.latmin;
let y = ((B - (lat - pars.latmin)) * pars.height) / B;
let x = ((lon - pars.lonmin) * pars.width) / L;
return { x: x, y: y };
}
const lngMidLatMid = lnglat2xy(
(lonmin + lonmax2) / 2,
(latmin + latmax) / 2,
params
);
//console.log("lngMidLatMid: "+lngMidLatMid.x+"; "+lngMidLatMid.y);
const bkk = lnglat2xy(100.5348327, 13.7567441, params);
const bda = lnglat2xy(100.4094999, 13.7108552, params);
const hoc = lnglat2xy(100.6076988, 13.5676449, params);
const han = lnglat2xy(100.7522551, 13.6982529, params);
const nay = lnglat2xy(100.4081876, 13.8923587, params);
var cy = cytoscape({
container: document.querySelector("#cyOnSvg"),
elements: {
nodes: [
{
data: { id: "LL", name: "LowerLeft" },
classes: "controlpoint",
position: { x: 0, y: cy_size }
},
{
data: { id: "UL", name: "UpperLeft" },
classes: "controlpoint",
position: { x: 0, y: 0 }
},
{
data: { id: "UR", name: "UpperRight" },
classes: "controlpoint",
position: { x: cy_size, y: 0 }
},
{
data: { id: "LR", name: "LowerRight" },
classes: "controlpoint",
position: { x: cy_size, y: cy_size }
},
/* Nodes with (long,lat) coordinates */
{ data: { id: "bkk", name: "A8" }, position: { x: bkk.x, y: bkk.y } },
{ data: { id: "bda", name: "BL38" }, position: { x: bda.x, y: bda.y } },
{ data: { id: "hoc", name: "E23" }, position: { x: hoc.x, y: hoc.y } },
{ data: { id: "han", name: "A1" }, position: { x: han.x, y: han.y } },
{ data: { id: "nay", name: "PP01" }, position: { x: nay.x, y: nay.y } },
],
edges: [
{
data: { id: "LLUR", source: "LL", target: "UR" },
classes: "controlline"
},
{
data: { id: "ULLR", source: "UL", target: "LR" },
classes: "controlline"
},
{
data: { id: "bkk_bda", source: "bkk", target: "bda" },
classes: "edge"
},
{
data: { id: "bkk_han", source: "bkk", target: "han" },
classes: "edge"
},
{
data: { id: "bkk_hoc", source: "bkk", target: "hoc" },
classes: "edge"
},
{
data: { id: "bkk_nay", source: "bkk", target: "nay" },
classes: "edge"
},
]
},
style: [
{
selector: "node",
style: {
shape: "hexagon",
width: "50px",
height: "50px",
"background-color": "blue",
label: "data(name)",
opacity: 1,
"text-background-color": "yellow"
}
},
{
selector: ".controlline",
style: {
width: "2px",
"line-color": "black",
opacity: 1
}
},
{
selector: ".edge",
style: {
width: "3px",
"line-color": "red",
opacity: 1
}
},
],
layout: {
name: "preset"
}
});
cy.pan({ x: 0.0, y: 0.0 }); //match TOP-LEFT corner
cy.fit(cy.$("#LLUR"));
:root {
--svg-width: 1600px;
--svg-height: 1600px;
}
#cyOnSvg{
/* foreignObject, and canvas */
position: absolute;
width: 100%; //5%;
height: 100%; //10%;
top: 0;
left: 0;
background-color: lightgray;
overflow: visible;
margin: 0;
padding: 0;
}
#Svg0{
/* svg elem */
position: absolute;
width: var(--svg-width);
height: var(--svg-height);
top: 0;
left: 0;
display: block;
background-color: lightyellow;
/*border: 0.5px solid gray;
border-style: dashed;*/
overflow: visible;
margin: 0;
padding: 0;
}
#mapid {
height: 480px;
width: 480px;
}
#lorem {
width: var(--svg-width);
position: absolute;
background-color: gray;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.7.1/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.9.2/cytoscape.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-browser/0.1.0/jquery.browser.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.5.1/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="" />
<div id="mapid"></div>

Related

How can I render circles around rectangle in Konva js?

I need to render table and chairs like in this picture:
I dont know how to calculate position of circles around rect. I tried some code, but its not working...Anybody knows how to solve it?
Check my code:
let smallCircleRadius = 20
let tableSize = {
width: ((seats-4/2)*(smallCircleRadius)),
height: ((seats-4/2)*(smallCircleRadius))
}
let controlY = 0
let totalCircleSide = (seats-4)/2
let controlX = 0
let distanceY = 0
let distanceX = 0
let table = new Konva.Rect({
width: tableSize.width,
height: tableSize.height,
fill: '#fff',
stroke: '#c3c6cf',//'#b2cfcf',
strokeWidth: 8,
x:150,
y: 150
});
let count = 0
group.add(table)
for (var i = 0; i < seats; i++) {
// let distanceToTable = tableSize.width/2;
// let x = i <= 2 ? table.x() + distanceToTable * i + (smallCircleRadius + 8) : count > totalCircleSide ? distanceToTable + distanceX+smallCircleRadius: controlX
// let y = i < 2 ? table.y() - distanceToTable/2: count > totalCircleSide ? controlY : distanceToTable + distanceY*smallCircleRadius
//let x = table.x()
//let y = table.y()
group.add(new Konva.Circle({ radius: smallCircleRadius, fill: '#d2d6df', stroke: '#c3c6cf',strokeWidth: 3, x, y }));
}
Make yourself a simple model that describes the position of the circles in simple relationship of circles to the table. Something like this can be extended via different models to accommodate other table layouts as the description of the layout is entirely in the model data.
const
// Set up a canvas stage
containerEle = document.getElementById('container'),
stage = new Konva.Stage({
container: "container",
size: {
width: containerEle.offsetWidth,
height: containerEle.offsetHeight
}
}),
layer = new Konva.Layer();
stage.add(layer);
const model = {
table: {
x: 100,
y: 100,
width: 200,
height: 400,
fill: 'black',
stroke: 'silver',
strokeWidth: 5
},
seat: {
radius: 40,
fill: 'white',
stroke: 'silver',
strokeWidth: 5,
gap: 20
},
seats: [{
name: "Seat 1",
x: "25%",
y: "-1r"
},
{
name: "Seat 2",
x: "75%",
y: "-1r"
},
{
name: "Seat 3",
tableX: 1,
tableY: 0,
x: "1r",
y: "16.6%"
},
{
name: "Seat 4",
tableX: 1,
tableY: 0,
x: "1r",
y: "50%"
},
{
name: "Seat 5",
tableX: 1,
tableY: 0,
x: "1r",
y: "83.3%"
},
{
name: "Seat 6",
tableX: 0,
tableY: 1,
x: "75%",
y: "1r"
},
{
name: "Seat 7",
tableX: 0,
tableY: 1,
x: "25%",
y: "1r"
},
]
}
// make the table
const table = new Konva.Rect(model.table);
layer.add(table)
for (const seat of model.seats) {
const seatShape = new Konva.Circle(model.seat);
let tablePos = {
x: seat.tableX && seat.tableX === 1 ? model.table.x + model.table.width : model.table.x,
y: seat.tableY && seat.tableY === 1 ? model.table.y + model.table.height : model.table.y
}
let position = {
x: tablePos.x + getPosComponent(seat.x, model.seat.radius, model.table.width, model.seat.gap),
y: tablePos.y + getPosComponent(seat.y, model.seat.radius, model.table.height, model.seat.gap)
}
seatShape.position(position)
layer.add(seatShape);
}
function getPosComponent(val, radius, size, gap) {
if (val.indexOf('r') > 0) {
let num = parseInt(val),
sign = Math.sign(num);
return sign * ((Math.abs(num) * radius) + gap);
} else if (val.indexOf('%') > 0) {
let num = parseFloat(val),
sign = Math.sign(num);
return sign * (size * num / 100);
}
throw new Error("Unexpected val format " + val);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset=UTF-8>
<script src="https://unpkg.com/konva#8/konva.min.js"></script>
<style>
#container {
width: 800px;
height: 600px;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>

Changing xaxis label from echarts library

var data = [];
var dataCount = 10;
var startTime = +new Date();
var categories = ['categoryA', 'categoryB', 'categoryC'];
var types = [
{name: 'JS Heap', color: '#7b9ce1'},
{name: 'Documents', color: '#bd6d6c'},
{name: 'Nodes', color: '#75d874'},
{name: 'Listeners', color: '#e0bc78'},
{name: 'GPU Memory', color: '#dc77dc'},
{name: 'GPU', color: '#72b362'}
];
// Generate mock data
echarts.util.each(categories, function (category, index) {
var baseTime = startTime;
for (var i = 0; i < dataCount; i++) {
var typeItem = types[Math.round(Math.random() * (types.length - 1))];
var duration = Math.round(Math.random() * 10000);
data.push({
name: typeItem.name,
value: [
index,
baseTime,
baseTime += duration,
duration
],
itemStyle: {
normal: {
color: typeItem.color
}
}
});
baseTime += Math.round(Math.random() * 2000);
}
});
function renderItem(params, api) {
var categoryIndex = api.value(0);
var start = api.coord([api.value(1), categoryIndex]);
var end = api.coord([api.value(2), categoryIndex]);
var height = api.size([0, 1])[1] * 0.6;
var rectShape = echarts.graphic.clipRectByRect({
x: start[0],
y: start[1] - height / 2,
width: end[0] - start[0],
height: height
}, {
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
});
return rectShape && {
type: 'rect',
shape: rectShape,
style: api.style()
};
}
option = {
tooltip: {
formatter: function (params) {
return params.marker + params.name + ': ' + params.value[3] + ' ms';
}
},
title: {
text: 'Profile',
left: 'center'
},
dataZoom: [{
type: 'slider',
filterMode: 'weakFilter',
showDataShadow: false,
top: 400,
height: 10,
borderColor: 'transparent',
backgroundColor: '#e2e2e2',
handleIcon: 'M10.7,11.9H9.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4h1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7v-1.2h6.6z M13.3,22H6.7v-1.2h6.6z M13.3,19.6H6.7v-1.2h6.6z', // jshint ignore:line
handleSize: 20,
handleStyle: {
shadowBlur: 6,
shadowOffsetX: 1,
shadowOffsetY: 2,
shadowColor: '#aaa'
},
labelFormatter: ''
}, {
type: 'inside',
filterMode: 'weakFilter'
}],
grid: {
height:300
},
xAxis: {
min: startTime,
scale: true,
axisLabel: {
formatter: function (val) {
return Math.max(0, val - startTime) + ' ms';
}
}
},
yAxis: {
data: categories
},
series: [{
type: 'custom',
renderItem: renderItem,
itemStyle: {
normal: {
opacity: 0.8
}
},
encode: {
x: [1, 2],
y: 0
},
data: data
}]
};
Hi, everyone!! I am working on the echarts library, the only thing i want to change data is the axisLabel from Xaxis part.
What i mean is, for example, "2019-11-5, 2019-11-6...."and so on. So, i hope someone can help me out, thank you so much!!!
Hi, everyone!! I am working on the echarts library, the only thing i want to change data is the axisLabel from Xaxis part.
What i mean is, for example, "2019-11-5, 2019-11-6...."and so on. So, i hope someone can help me out, thank you so much!!!
First, create an array of dates like
var dates = ['2019-11-5','2019-10-3','2019-2-2','2019-1-4','2019-12-5'];
then in xAxis -> axisLabel return date
axisLabel: {
formatter: function (val,index) {
return dates[index];
}
}

ArcGIS: h {name: "esri.layers.graphics.QueryEngine", message: "Unsupported query", details: undefined} when load data with api request

I'm facing issue with Feature layer. When plot map with local data. But when I'm using hosted data in feature layer then Drawing feature is working fine and query on drawing data is also working perfectly.
But when I'm using my local system data using api request then draw objects on map is working fine but query filtering is not working on feature layer data. Below is the example code.
<link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css">
<style>
#viewDiv {
height: 100%;
}
.popUpMapView {
height: 400px;
border: 1px solid #A8A8A8;
}
#drawActions {
padding: 0 5px;
background: #eee;
border-left: 1px solid #999;
border-right: 1px solid #999;
}
#drawActions ul {
list-style-type: none;
margin: 0;
padding: 0;
}
#drawActions ul li {
display: inline-block;
}
#drawActions ul li .esri-widget--button {
background: #eee;
}
#drawActions ul li .esri-widget--button:hover {
background: #fff;
}
.esri-ui-top-left .esri-component {
margin-bottom: 0;
border-top: solid 1px rgba(50,50,50,0.25);
}
.esri-popup.esri-widget {
max-height: 100%;
}
.esri-view-width-xlarge .esri-popup__main-container {
width: 580px;
}
.esri-view-height-less-than-medium .esri-popup__main-container {
max-height: 500px;
}
.esri-view-height-small .esri-ui-corner .esri-component .esri-expand__content,
.esri-view-width-greater-than-xsmall .esri-expand--auto .esri-expand__content {
margin-left: 0;
white-space: nowrap;
}
.esri-widget--button {
outline: 0;
}
.esri-legend__layer-body {
display: table;
width: 100%;
margin: 0;
}
.color-selection-item-container {
cursor: pointer;
}
.item-selected .color-selection-item-container {
opacity: 0.5;
}
.item-selected .color-selection-item-container.active {
opacity: 1;
}
.item-selected .color-selection-item-container.active .esri-legend__layer-cell--info {
color: #000;
}
</style>
<script>
var dojoConfig = {
has: {
"esri-featurelayer-webgl": 1
}
}
</script>
<script src="https://js.arcgis.com/4.8/"></script>
<script>
let highlight;
let highlightFields = [];
let povLayer;
let plantTypeFilterObj = [];
require([
"esri/Map",
"esri/views/MapView",
"esri/WebMap",
"esri/widgets/Sketch/SketchViewModel",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/layers/FeatureLayer",
"esri/widgets/Home",
"esri/widgets/Legend",
"esri/widgets/Expand",
"esri/geometry/Point",
"esri/config",
"esri/request",
"dojo/domReady!"
], function(
Map, MapView, WebMap, SketchViewModel, Graphic, GraphicsLayer, FeatureLayer, Home, Legend, Expand, Point, erisConfig, Request
) {
const tempGraphicsLayer = new GraphicsLayer();
var map = new Map({
basemap: "dark-gray",
layers: [tempGraphicsLayer]
});
const view = new MapView({
map: map,
container: "viewDiv",
center: [-91.891111, 42.477778],
zoom: 4,
highlightOptions: {
color: "black",
haloOpacity: 0,
fillOpacity: 0.45
},
});
let highlightHandle = null;
view.when(function() {
getData()
.then(createGraphics)
.then(createLayer)
.catch(errback);
});
function getData() {
let url = "http://localhost/arcgis/points-listing";
return Request(url, {
responseType: "json"
});
}
function createGraphics(response) {
let items = response.data.data;
let geojson = items.map(function(item, i) {
return {
geometry: new Point({
x: item.lng,
y: item.lat
}),
attributes: {
ObjectID: item.plant_id,
name: item.name,
address: item.street_address,
city: item.city,
state_code: item.state_code,
zip: item.zip,
county: item.county,
lng: item.lng,
lat: item.lat,
nameplate_capacity: item.nameplate_capacity,
plant_type: item.plant_type
}
};
});
return geojson;
}
function createLayer(graphics) {
let layer = new FeatureLayer({
source: graphics,
fields: getFields(),
objectIdField: "ObjectID",
renderer: getRender(),
geometryType: "point",
popupTemplate: getTemplate(),
elevationInfo: {
mode: "on-the-ground"
}
});
var legend = new Legend({
view: view,
layerInfos: [{
layer: layer,
title: "Plants detail"
}]
});
view.ui.add(legend, "top-right");
map.add(layer);
view.whenLayerView(layer).then(function(layerView) {
sketchGraphics(layerView);
setTimeout(function() {
hideShowPointsOnPlantTypeBasis();
colorSelectionClick();
}, 1000);
});
return layer;
}
function hideShowPointsOnPlantTypeBasis()
{
let legendContainer = document.getElementsByClassName("esri-legend__layer-table--size-ramp")[0];
legendContainer.className += " color-section";
let legendInfoItem = legendContainer.getElementsByClassName("esri-legend__layer-cell--info");
for (let i = 0; i < legendInfoItem.length; i++) {
let element = legendInfoItem[i];
let text = element.innerHTML;
let value = (text.toUpperCase()).replace(" ", "_");
checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
checkbox.setAttribute("class", "plant-type-filtering-checkbox");
checkbox.setAttribute("style", "display:none;");
checkbox.setAttribute("value", value);
element.parentNode.classList.add("color-selection-item-container");
element.parentNode.insertBefore(checkbox, element.parentNode.firstChild);
}
}
function colorSelectionClick() {
$('.esri-expand__content').on('click', '.color-selection-item-container', function(e) {
e.preventDefault();
let $this = $(this);
let $input = $this.find('input.plant-type-filtering-checkbox');
let selectedVal = $input.val();
if(!$input.is(':checked')) {
plantTypeFilterObj.push(selectedVal);
$input.prop('checked', true);
$this.addClass('active');
} else {
$this.removeClass('active');
plantTypeFilterObj = plantTypeFilterObj.filter(function(value, index, arr){
return value != selectedVal;
});
$input.prop('checked', false);
}
let layerViews = view.layerViews;
if(plantTypeFilterObj.length > 0) {
viewLayer.layer.definitionExpression = "nameplate_capacity > 0 AND plant_type IN ('" + plantTypeFilterObj.join("','") + "')";
} else {
viewLayer.layer.definitionExpression = '';
}
let selectedCount = $('.esri-expand__content').find('.color-selection-item-container.active').length;
if(selectedCount > 0) {
$('.esri-expand__content').addClass('item-selected');
} else {
$('.esri-expand__content').removeClass('item-selected');
}
});
}
function sketchGraphics(layer) {
viewLayer = layer;
// create a new sketch view model
const sketchViewModel = new SketchViewModel({
view: view,
layer: tempGraphicsLayer,
pointSymbol: {
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
style: "square",
size: "16px"
}
});
setUpClickHandler(view);
sketchViewModel.on("create", createGraphic);
sketchViewModel.on("create-complete", addGraphic);
// Listen the sketchViewModel's update-complete and update-cancel events
sketchViewModel.on("update-complete", updateGraphic);
sketchViewModel.on("update-cancel", updateGraphic);
var drawCircleButton = document.getElementById("circleButton");
var drawRectangleButton = document.getElementById("rectangleButton");
var drawPolygonButton = document.getElementById("polygonButton");
drawCircleButton.onclick = function() {
resetSketchView();
sketchViewModel.create("circle");
setActiveButton(this);
};
drawRectangleButton.onclick = function() {
resetSketchView();
sketchViewModel.create("rectangle");
setActiveButton(this);
};
drawPolygonButton.onclick = function() {
resetSketchView();
sketchViewModel.create("polygon");
setActiveButton(this);
};
view.on('click', function(event) {
resetSketchView();
});
// reset all the changes from map on btn click.
document.getElementById("resetBtn").onclick = function() {
resetSketchView();
};
function addGraphic(event) {
const graphic = new Graphic({
geometry: event.geometry,
symbol: sketchViewModel.graphic.symbol
});
tempGraphicsLayer.add(graphic);
selectFeatures(event.geometry);
}
function createGraphic(event) {
resetHideShowPoints();
}
function updateGraphic(event) {
event.graphic.geometry = event.geometry;
tempGraphicsLayer.add(event.graphic);
editGraphic = null;
}
function setActiveButton(selectedButton) {
view.focus();
var elements = document.getElementsByClassName("active");
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove("active");
}
if (selectedButton) {
selectedButton.classList.add("active");
}
}
function resetSketchView() {
sketchViewModel.reset();
tempGraphicsLayer.removeAll();
// remove existing highlighted features
if (highlight) {
highlight.remove();
}
}
}
function selectFeatures(geometry) {
view.graphics.removeAll();
if (viewLayer) {
let query = {};
query.returnGeometry = true;
query.outFields = ["*"];
viewLayer.queryFeatures(query).then(function(results) {
const graphics = results.features;
if (graphics.length > 0) {
// remove existing highlighted features
if (highlight) {
highlight.remove();
}
highlight = viewLayer.highlight(graphics);
}
})
.catch(errback);
}
}
function removeUnSelectedPoints(viewLayer, graphics)
{
graphics.forEach(item => {
highlightFields.push(item.attributes.FID);
});
setTimeout(function() {
viewLayer.layer.definitionExpression = "FID IN (" + highlightFields.join(",") + ")";
}, 1000);
}
function resetHideShowPoints() {
if(highlightFields.length > 0) {
highlightFields = [];
viewLayer.layer.definitionExpression = "";
console.log('reset', highlightFields);
}
}
function errback(error) {
console.error(error);
}
function setUpClickHandler(mapview) {
mapview.on("click", function(event) {
event.stopPropagation();
streetView(view, event)
mapview.hitTest(event).then(function(response) {
var results = response.results;
});
});
}
function streetView(mainMapView, event) {
// Make sure that there is a valid latitude/longitude
if (event && event.mapPoint) {
// Create lat/lon vars to display in popup title
var lat = Math.round(event.mapPoint.latitude * 1000) / 1000;
var lon = Math.round(event.mapPoint.longitude * 1000) / 1000;
mainMapView.popup.open({
// Set the popup's title to the coordinates of the location
title: "Map view coordinates: [" + lon + ", " + lat + "]",
location: event.mapPoint, // Set the location of the popup to the clicked location
content: innerMapPopUp(
mainMapView,
mainMapView.center,
mainMapView.scale
)
});
} else {
mainMapView.popup.open({
// Set the popup's title to the coordinates of the location
title: "Invalid point location",
location: event.mapPoint, // Set the location of the popup to the clicked location
content: "Please click on a valid location."
});
}
}
function innerMapPopUp(mainMapView, center, scale) {
var popupDiv = document.createElement("div");
popupDiv.classList.add("popUpMapView");
var popupView = new MapView({
container: popupDiv,
map: new Map({
basemap: "topo"
}),
center: center,
zoom: 8,
ui: {
components: []
}
});
console.log(popupView);
// Return a dom node
return popupView.container;
}
function getFields() {
var fields = [
{
name: "ObjectID",
alias: "ObjectID",
type: "oid"
}, {
name: "name",
alias: "name",
type: "string"
}, {
name: "address",
alias: "address",
type: "string"
}, {
name: "city",
alias: "city",
type: "string"
}, {
name: "state_code",
alias: "state_code",
type: "string"
}, {
name: "zip",
alias: "zip",
type: "string"
}, {
name: "county",
alias: "county",
type: "string"
}, {
name: "plant_type",
alias: "plant_type",
type: "string"
}, {
name: "nameplate_capacity",
alias: "nameplate_capacity",
type: "double"
}
];
return fields;
}
function getTemplate() {
// Set up popup template for the layer
var pTemplate = {
title: "{name}",
content: [{
type: "fields",
fieldInfos: [
{
fieldName: "street_address",
label: "Address",
visible: true
},
{
fieldName: "city",
label: "City",
visible: true
},
{
fieldName: "state_code",
label: "State Code",
visible: true
},
{
fieldName: "zip",
label: "Zip",
visible: true
},
{
fieldName: "county",
label: "County",
visible: true
},
{
fieldName: "plant_type",
label: "Plant Type",
visible: true
},
{
fieldName: "latitude",
label: "Latitude",
visible: true
},
{
fieldName: "longitude",
label: "Longitude",
visible: true
},
{
fieldName: "nameplate_capacity",
label: "Capacity (MW)",
visible: true
}
]
}]
};
return pTemplate;
}
function getRender() {
var renderer = {
type: "unique-value", // autocasts as new SimpleRenderer()
// Define a default marker symbol with a small outline
symbol: {
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
color: "#FFD733"
},
defaultLabel: "Other",
field: "plant_type",
label: "Plant Type",
uniqueValueInfos: [
{
value: "HYDRO",
symbol: {
type: "simple-marker",
color: "hsla(345,80%, 65%, 1)"
},
label: "Hydro"
},
{
value: "NATURAL_GAS",
symbol: {
type: "simple-marker",
color: "hsla(213,80%, 65%, 1)"
},
label: "Natural Gas"
},
{
value: "BIOMASS",
symbol: {
type: "simple-marker",
color: "hsla(195,80%, 65%, 1)"
},
label: "Biomass"
},
{
value: "COAL",
symbol: {
type: "simple-marker",
color: "hsla(336,80%, 65%, 1)"
},
label: "Coal"
},
{
value: "NUCLEAR",
symbol: {
type: "simple-marker",
color: "hsla(224,80%, 65%, 1)"
},
label: "Nuclear"
},
{
value: "PETROLIUM",
symbol: {
type: "simple-marker",
color: "hsla(264,80%, 65%, 1)"
},
label: "Petrolium"
},
{
value: "SOLAR",
symbol: {
type: "simple-marker",
color: "hsla(287,80%, 65%, 1)"
},
label: "Solar"
},
{
value: "WIND",
symbol: {
type: "simple-marker",
color: "hsla(344,80%, 65%, 1)"
},
label: "Wind"
}
],
visualVariables: [
{
type: "size",
field: "nameplate_capacity",
valueUnit: "unknown",
legendOptions: {
title: "Nameplate Capacity (MW)"
},
stops: [
{
value: 500,
size: 10,
label: "<500"
},
{
value: 2000,
size: 15,
label: "1000"
},
{
value: 3000,
size: 20,
label: "4000"
},
{
value: 5000,
size: 35,
label: "< 10000"
}]
}
]
};
return renderer;
}
// Set up a home button for resetting the viewpoint to the intial extent
var homeBtn = new Home({
view: view
}, "homeDiv");
// Instructions expand widget
const drawIcons = document.getElementById("drawActions");
instructionsExpand = new Expand({
expandIconClass: "esri-icon-expand",
expandTooltip: "Draw Actions",
expanded: false,
view: view,
iconNumber: 4,
content: drawIcons
});
view.ui.add(homeBtn, "top-left");
view.ui.add(instructionsExpand, "top-left");
// hide the instructions expand widget when the view becomes focused
view.watch("focused", function(newValue, oldValue, property, object) {
if (newValue) {
instructionsExpand.expanded = false;
}
});
});
</script>
And below is the screen-shot what issue I'm getting.
I spend my too much time to research on that. But unfortunately I'm not finding any way how to resolve this issue.
Please give a clue what I'm missing.
It looks like you are not setting up the query correctly. You have:
let query = {};
query.returnGeometry = true;
query.outFields = ["*"];
viewLayer.queryFeatures(query)
You need to use the featureLayer's createQuery method to create a query object:
let query = layer.createQuery();
query.returnGeometry = true;
query.outFields = ["*"];
viewLayer.queryFeatures(query)
Also, WebGL rendering is only supported for layers hosted on ArcGIS Online, or on ArcGIS Server 10.6.1 so highlight and other functionality will not work on layers that do not meet these requirements.

How to generate Canvas layer with on click button

i have a question - how to draw canvas layer (for example just simple square) with event on click on button in Vue.js? I have stage and on that stage with position x:0, y:0 i want after click on button to generate that square and with drag and drop to position it on that stage? I'm using Konvajs for creating Canvas
Can somebody help me?
<template>
<div id="main">
<h1></h1>
<div id="obszarroboczy" style="width: 500px; height: 600px;">
<v-stage ref="stage"
:config="configKonva"
#dragstart="handleDragstart"
#dragend="handleDragend">
<v-layer ref="layer">
<v-star
v-for="item in list"
:key="item.id"
:config="item"></v-star>
</v-layer>
<v-layer ref="dragLayer"></v-layer>
</v-stage>
</div>
<div class="col-md-6">
<button v-on:click="handleClick" id="more_canvas">More</button>
</div>
</div>
</template>
<script>
import Vue from "vue";
import axios from "axios";
import draggable from "vuedraggable";
import swal from "sweetalert2";
import VueKonva from "vue-konva";
export default {
name: "EnumCurrencyIndex",
$mount: "#main",
components: {
draggable
},
data() {
return {
model: [],
editable: true,
isDragging: false,
delayedDragging: false,
type: "currency",
editedElement: null,
newElement: "",
list: [],
configKonva: {
width: 400,
height: 400
},
configCircle: {
x: 100,
y: 100,
radius: 70,
fill: 'red',
stroke: 'black',
strokeWidth: 4
},
vm: {}
};
},
beforeMount() {
this.fetchData();
},
computed: {
dragOptions() {
return {
animation: 0,
group: "description",
disabled: !this.editable,
ghostClass: "ghost"
};
},
listString() {
return this.model;
},
dragCanvas() {
return this.model;
}
},
watch: {
$route: "fetchData",
isDragging(newValue) {
if (newValue) {
this.delayedDragging = true;
return;
}
this.$nextTick(() => {
this.delayedDragging = false;
});
}
},
methods: {
handleDragstart(starComponent) {
var vm = this;
const shape = starComponent.getStage();
const dragLayer = vm.$refs.dragLayer.getStage();
const stage = vm.$refs.stage.getStage();
// moving to another layer will improve dragging performance
shape.moveTo(dragLayer);
stage.draw();
starComponent.config.shadowOffsetX = 15;
starComponent.config.shadowOffsetY = 15;
starComponent.config.scaleX = starComponent.config.startScale * 1.2;
starComponent.config.scaleY = starComponent.config.startScale * 1.2;
},
handleDragend(starComponent) {
var vm = this;
const shape = starComponent.getStage();
const layer = vm.$refs.layer.getStage();
const stage = vm.$refs.stage.getStage();
shape.moveTo(layer);
stage.draw();
shape.to({
duration: 0.5,
easing: Konva.Easings.ElasticEaseOut,
scaleX: starComponent.config.startScale,
scaleY: starComponent.config.startScale,
shadowOffsetX: 5,
shadowOffsetY: 5
});
},
handleClick(configCircle) {
var vm = this;
const shape = vm.$refs.layer.getStage();
const layer = vm.$refs.layer.getStage();
const stage = vm.$refs.stage.getStage();
console.log(1);
layer.add(configCircle);
stage.add(layer);
},
haveIntersection(r1, r2) {
return !(
r2.x > r1.x + r1.width ||
r2.x + r2.width < r1.x ||
r2.y > r1.y + r1.height ||
r2.y + r2.height < r1.y
);
},
orderList() {
this.model = this.model.sort((one, two) => {
return one.position - two.position;
});
},
onMove({ relatedContext, draggedContext }) {
const relatedElement = relatedContext.element;
const draggedElement = draggedContext.element;
return (
(!relatedElement || !relatedElement.fixed) && !draggedElement.fixed
);
},
fetchData() {
var vm = this;
axios
.get(`/api/${this.resource}?type=${this.type}`)
.then(function(response) {
Vue.set(vm.$data, "model", response.data.model);
})
.catch(function(error) {
console.log(error);
});
}
},
mounted() {
var box = document.getElementById("obszarroboczy");
this.configKonva.width = box.offsetWidth;
this.configKonva.height = box.offsetHeight;
var vm = this;
for (let n = 0; n < 30; n++) {
const scale = Math.random();
const stage = vm.$refs.stage.getStage();
vm.list.push({
x: Math.random() * stage.getWidth(),
y: Math.random() * stage.getHeight(),
rotation: Math.random() * 180,
numPoints: 5,
innerRadius: 30,
outerRadius: 50,
fill: "#89b717",
opacity: 0.8,
draggable: true,
scaleX: scale,
scaleY: scale,
shadowColor: "black",
shadowBlur: 10,
shadowOffsetX: 5,
shadowOffsetY: 5,
shadowOpacity: 0.6,
startScale: scale
});
};
},
directives: {
"element-focus": function(el, binding) {
if (binding.value) {
el.focus();
}
}
}
};
</script>
<style>
#obszarroboczy {
width: 100px;
height: 300px;
}
.normal {
background-color: grey;
}
.table td {
width: 100px;
height: 100px;
background: white;
border: 2px dotted black;
max-width: 100px;
padding: 5px;
}
.drag {
display: flex;
flex-direction: row;
}
.list {
flex-grow: 1;
max-width: 47%;
margin-right: 40px;
}
.name {
width: 50%;
display: inline-block;
height: 50px;
background: pink;
border: 5px green solid;
box-sizing: border-box;
padding: 5px;
}
.name.large {
width: 100%;
}
.dragArea {
min-height: 100px;
}
.dragArea img {
margin: 3px;
cursor: pointer;
}
</style>
var mainCanvas = new Vue({
el: '#main', // the element where the method wil lrender the canvas to
data: {
name: 'Vue.js'
},
methods: {
handleClick: function (event) { // handleClick is the method name for the button
var stage = new Konva.Stage({ // this line till the stage.add() line renders the draggable square
container: 'obszarroboczy',
width: 500,
height: 500
});
var layer = new Konva.Layer();
var rect = new Konva.Rect({
x: 0,
y: 0,
width: 100,
height: 100,
fill: 'green',
stroke: 'black',
strokeWidth: 4,
draggable: true
});
layer.add(rect);
stage.add(layer);
}
}
});
I added comments to explain what certain important lines does but you can check out the official KonvaJS Docs in GitHub for a more detailed explanation on what each line above does.

I want joint.js library to read my JSON and display it as a cell: rect and circle

I have a json data structure like this for example :
var json1 = {
"places": [ { "id":0, "x":0.0, "y":0.0, "width":10.0, "height":10.0 },
{ "id":1, "x":50.0, "y":0, "width":10.0, "height":10.0 },
{ "id":2, "x":0.0, "y":30.0, "width":10.0, "height":10.0 },
{ "id":3, "x":50.0, "y":30.0, "width":10.0, "height":10.0 } ],
"transitions": [ { "id":0, "x":20.0, "y":20.0, "width":20.0, "height":10.0, "label":"Hello" } ],
"ptlinks": [ { "src":0, "dst":0, "expr":"x=0" },
{ "src":1, "dst":0, "expr":"y=0" } ],
"tplinks": [ { "src":0, "dst":1 },
{ "src":0, "dst":3 } ],
"name"": "Client"
}
I want to use these data to draw a graph with element transition as a rectangle and place as a circle with the links ....
<script language="javascript">
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: $('#main_petri'),
width: 960,
height: 500,
model: graph
});
var rect = new joint.shapes.basic.Rect({
position: { x: 100, y: 30 },
size: { width: 100, height: 30 },
attrs: { rect: { fill: '#FFFFFF' }, text: { text: '#', fill: '#000000' } }
});
var rect2 = rect.clone();
rect2.translate(0,50);
var link = new joint.dia.Link({
source: { id: rect.id },
target: { id: rect2.id }
});
graph.addCells([rect, rect2, link]);
How can I use JSON (position, size ...) into jointjs ?
You can just loop over your places/transitions and links and create JointJS elements/links. Something like:
_.each(json1.places, function(p) {
graph.addCell(new joint.shapes.pn.Place({
id: 'place' + p.id,
position: { x: p.x, y: p.y },
size: { width: p.width, height: p.height }
}));
});
_.each(json1.transitions, function(t) {
graph.addCell(new joint.shapes.pn.Transition({
id: 'transition' + t.id,
position: { x: t.x, y: t.y },
size: { width: t.width, height: t.height },
attrs: { '.label': { text: t.label } }
}));
});
_.each(json1.ptlinks, function(l) {
graph.addCell(new joint.dia.Link({
source: { id: 'place' + l.src },
target: { id: 'transition' + l.dst },
labels: [ { position: .5, attrs: { text: { text: l.expr } } } ]
}));
});
_.each(json1.tplinks, function(l) {
graph.addCell(new joint.dia.Link({
source: { id: 'transition' + l.src },
target: { id: 'place' + l.dst },
labels: [ { position: .5 } ]
}));
});

Categories

Resources