How can i modify the popupTemplate in esri? is it possible for me to modify the popupTemplate according to my design?
I have a popupTemplate
popupTemplate: {
content: [{
type: "fields",
fieldInfos: [{
fieldName: "Name"
}, {
fieldName: "Owner"
}, {
fieldName: "Length"
}]
}]
}
this is the result
what i want design
resource https://totalapis.github.io/sample-code/popup-custom-action/index.html
Update, I am having trouble on my react , when i clicked the icon there is no popup template show
useEffect(() => {
if (mapDiv.current) {
esriConfig.apiKey = process.env.ARCGIS_API;
const map = new Map({
basemap: 'arcgis-light-gray'
});
const view = new MapView({
center: [123.5504, 12.3574], // Longitude, latitude
container: mapDiv.current,
map: map,
zoom: 13, // Zoom level
});
view
.when((r) => {})
.then(() => {
mapDiv.current = view;
setMapView(view);
});
var list= [{
type: "fields",
fieldInfos: [{
fieldName: "Name "
}, {
fieldName: "Owner"
}, {
fieldName: "Length"
}]
},
{
type: "text",
text: "<div class=\"icontain\"></><a class=\"ic\"><i class=\"bi bi-star\"></i></a><a class=\"ic\"><i class=\"bi bi-geo-alt-fill\"></i></a></div>"
}]
var Stack= {
content: list
}
var featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Beverly%20Hills%20Trees%20By%20Block/FeatureServer/0",
popupTemplate: Stack,
outFields: ["*"]
});
map.add(featureLayer);
}
}, []);
const displayLocation = (locations) => {
mapView.center = [
locations.data[0].geoCode.longitude,
locations.data[0].geoCode.latitude,
];
locations.data.map((location) => {
const point = new Graphic({
geometry: {
latitude: location.geoCode.latitude,
longitude: location.geoCode.longitude,
type: 'point',
},
symbol: LocationPin,
});
mapView.graphics.add(point);
});
};
return <div className="mapDiv layers" ref={mapDiv}></div>;
}
Hello, a quick solution to modify the Popup template is to add another object with text and text type properties to the template array. the text value will be html code where we will create a div that will show the icons, these with their respective css classes. The most is CSS. Here is an example of the Popup template:
popupTemplate: {[{
type: "fields",
fieldInfos: [{
fieldName: "Name "
}, {
fieldName: "Owner"
}, {
fieldName: "Length"
}]
},
{
type: "text",
text: "<div class=\"icontain\"></><a class=\"ic\"><i class=\"bi bi-star\"></i></a><a class=\"ic\"><i class=\"bi bi-geo-alt-fill\"></i></a></div>"
}]
}
I put an example of this code in operation already with the css, for a better compression. Your remaining task is to play with CSS to make the icon div responsive. For a better visualization of the example, run it in full screen. Another detail is that the example takes time to load due to the multiple CDNs that it needs
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"dojo/domReady!"
], function(Map, MapView, FeatureLayer) {
// Create the Map
var map = new Map({
basemap: "streets-navigation-vector"
});
var view = new MapView({
container: "mapDiv",
map: map,
center: [-118.399400711028, 34.08713590709093],
zoom: 16,
// Since there are many elements, it is best to dock the popup so
// the elements display better rather than have to scroll through them all.
popup: {
dockEnabled: true,
dockOptions: {
buttonEnabled: false,
breakpoint: false
}
}
});
var list= [{
type: "fields",
fieldInfos: [{
fieldName: "Name "
}, {
fieldName: "Owner"
}, {
fieldName: "Length"
}]
},
{
type: "text",
text: "<div class=\"icontain\"></><a class=\"ic\"><i class=\"bi bi-star\"></i></a><a class=\"ic\"><i class=\"bi bi-geo-alt-fill\"></i></a></div>"
}]
var Stack= {
content: list
}
var featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/ArcGIS/rest/services/Beverly%20Hills%20Trees%20By%20Block/FeatureServer/0",
popupTemplate: Stack,
outFields: ["*"]
});
map.add(featureLayer);
});
html,
body,
#mapDiv {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
.esri-popup__main-container{
border: solid 1px gray;
border-radius: 10px;
}
.icontain{
position: absolute;
top: 0;
height: 100%;
left: -17px;
display: flex;
flex-direction: column;
/* margin-top: auto; */
/* margin-bottom: auto; */
/* align-items: center; */
justify-content: center;
}
.ic{
border: solid 1px gray;
border-radius: 50%;
width: 33px;
height: 33px;
display: flex;
justify-content: center;
align-items: center;
background: white;
margin-top: 4px;
margin-bottom: 4px;
}
<!DOCTYPE html>
<html dir="ltr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no"
/><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.7.2/font/bootstrap-icons.css">
<title>Multiple popup elements - 4.4</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.4/esri/css/main.css">
<link rel="stylesheet" href="https://js.arcgis.com/4.4/dijit/themes/claro/claro.css">
<script src="https://js.arcgis.com/4.4/"></script></head>
<body>
<div id="mapDiv"></div>
</body>
</html>
Update
run this code in your environment. The popup should appear, you should only add the styles
useEffect(() => {
if (mapDiv.current) {
esriConfig.apiKey = process.env.ARCGIS_API_KEY;
const map = new Map({
basemap: 'arcgis-light-gray', // Basemap layer service
// portalItem:{
// id: "2d11c8164ce04843a38bfde68e00e6e7"
// }
});
const view = new MapView({
center: [123.5504, 12.3574], // Longitude, latitude
container: mapDiv.current,
map: map,
zoom: 13, // Zoom level
});
view
.when((r) => {})
.then(() => {
mapDiv.current = view;
setMapView(view);
});
}
}, []);
const displayLocation = (locations) => {
mapView.center = [
locations.data[0].geoCode.longitude,
locations.data[0].geoCode.latitude,
];
locations.data.map((location) => {
const point = new Graphic({
geometry: {
latitude: location.geoCode.latitude,
longitude: location.geoCode.longitude,
type: 'point',
},
symbol: LocationPin,
popupTemplate: {
title: "Sample",
content: [{
type: "fields",
fieldInfos: [{
fieldName: "Name"
}, {
fieldName: "Owner"
}, {
fieldName: "Length"
}]
},{
type: "text",
text: "<div class=\"icontain\"></><a class=\"ic\"><i class=\"bi bi-star\"></i></a><a class=\"ic\"><i class=\"bi bi-geo-alt-fill\"></i></a></div>"
}]
}
});
mapView.graphics.add(point);
});
};
update css for button close
.esri-popup__header-buttons{
position: absolute;
top: 100px;
margin: 0;
left: -17px;
padding: 0;
background: white;
border-radius: 50%;
border: solid 1px;
width: 32px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
}
.esri-popup__button {
z-index: 10;
}
try with this class and styles, to customize the close button
Related
I’m working with Arcgis version 4.25 (javascript) and using cluster. I used the sample https://developers.arcgis.com/javascript/latest/sample-code/sandbox/?sample=featurereduction-cluster and want to show Browse Features content window on opening popup instead of showing summary.
How can I do that programmatically?
enter image description here
Basically, you have to query the layer view with the aggregatedId. The aggregated id is the objectId of the selected cluster feature.
Here I put an example for you using the esri sample you use as base. The key part, is when the CustomContent is render (the creator method).
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<title>
Point clustering - basic configuration | Sample | ArcGIS Maps SDK for
JavaScript 4.25
</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
background: rgba(50, 50, 50);
}
#infoDiv {
padding: 10px;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.25/esri/themes/dark/main.css" />
<script src="https://js.arcgis.com/4.25/"></script>
<script>
require([
"esri/Map",
"esri/layers/FeatureLayer",
"esri/layers/GeoJSONLayer",
"esri/views/MapView",
"esri/widgets/Legend",
"esri/widgets/Expand",
"esri/widgets/Home",
"esri/popup/content/CustomContent"
], (Map, FeatureLayer, GeoJSONLayer, MapView, Legend, Expand, Home, CustomContent) => {
const layer = new GeoJSONLayer({
title: "Earthquakes from the last month",
url: "https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson",
copyright: "USGS Earthquakes",
outFields: ["*"],
popupTemplate: {
title: "Magnitude {mag} {type}",
content: "Magnitude {mag} {type} hit {place} on {time}"
},
renderer: {
type: "simple",
field: "mag",
symbol: {
type: "simple-marker",
size: 4,
color: "#69dcff",
outline: {
color: "rgba(0, 139, 174, 0.5)",
width: 5
}
}
}
});
const baseLayer = new FeatureLayer({
portalItem: {
id: "2b93b06dc0dc4e809d3c8db5cb96ba69"
},
legendEnabled: false,
popupEnabled: false,
renderer: {
type: "simple",
symbol: {
type: "simple-fill",
color: [65, 65, 65, 1],
outline: {
color: [50, 50, 50, 0.75],
width: 0.5
}
}
},
spatialReference: {
wkid: 5936
}
});
const map = new Map({
layers: [baseLayer, layer]
});
const view = new MapView({
container: "viewDiv",
extent: {
spatialReference: {
wkid: 5936
},
xmin: 1270382,
ymin: -1729511,
xmax: 2461436,
ymax: -953893
},
spatialReference: {
// WGS_1984_EPSG_Alaska_Polar_Stereographic
wkid: 5936
},
constraints: {
minScale: 15469455
},
map: map
});
view.popup.viewModel.includeDefaultActions = false;
view.whenLayerView(layer).then(lv => {
const layerView = lv;
const customContentPromise = new CustomContent({
outFields: ["*"],
creator: (event) => {
const query = layerView.createQuery();
query.aggregateIds = [event.graphic.getObjectId()];
console.log(query);
return layerView.queryFeatures(query).then(result => {
console.log(result.features);
const contentDiv = document.createElement("div");
const featuresUl = document.createElement("ul");
let featureLi;
for (const feature of result.features) {
featureLi = document.createElement("li");
featureLi.innerText = `Magnitude ${feature.attributes.mag} ${feature.attributes.type} hit ${feature.attributes.place} on ${feature.attributes.time}`;
featuresUl.appendChild(featureLi);
}
contentDiv.appendChild(featuresUl);
return contentDiv
});
}
});
const clusterConfig = {
type: "cluster",
clusterRadius: "100px",
popupTemplate: {
title: "Cluster summary",
outFields: ["*"],
content: [customContentPromise],
actions: []
},
clusterMinSize: "24px",
clusterMaxSize: "60px",
labelingInfo: [
{
deconflictionStrategy: "none",
labelExpressionInfo: {
expression: "Text($feature.cluster_count, '#,###')"
},
symbol: {
type: "text",
color: "#004a5d",
font: {
weight: "bold",
family: "Noto Sans",
size: "12px"
}
},
labelPlacement: "center-center"
}
]
};
layer.featureReduction = clusterConfig;
const toggleButton = document.getElementById("cluster");
toggleButton.addEventListener("click", () => {
let fr = layer.featureReduction;
layer.featureReduction =
fr && fr.type === "cluster" ? null : clusterConfig;
toggleButton.innerText =
toggleButton.innerText === "Enable Clustering"
? "Disable Clustering"
: "Enable Clustering";
});
});
view.ui.add(
new Home({
view: view
}),
"top-left"
);
const legend = new Legend({
view: view,
container: "legendDiv"
});
const infoDiv = document.getElementById("infoDiv");
view.ui.add(
new Expand({
view: view,
content: infoDiv,
expandIconClass: "esri-icon-layer-list",
expanded: false
}),
"top-left"
);
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div id="infoDiv" class="esri-widget">
<button id="cluster" class="esri-button">Disable Clustering</button>
<div id="legendDiv"></div>
</div>
</body>
</html>
I have noticed that using Cola.js (with Cytoscape.js) most of my layouts tend to form in a square layout and not using up my bounding box which is more wide than tall.
I've been looking around and found d3-force which has this option of forceY that transform a square layout (https://bl.ocks.org/steveharoz/8c3e2524079a8c440df60c1ab72b5d03):
To this more wide layout:
I would really like to do the same for Cola.js, however I have been struggling to do it and tried all possible options like setting the bounding box, disabling zoom and etc. Is this possible at all?
I've found a demo for Cola.js that provides somewhat what I need, but unable to make it work in Cytoscape.js: https://ialab.it.monash.edu/webcola/examples/pageBoundsConstraints.html
Based on the link you provide, you can apply a similar functionality with cola.js. You need to have two dummy nodes locked (one for top-left and one for bottom-right) and then add constraints for all other nodes appropriately. You can disable the visibility of dummy nodes (I left them as visible so we can see the top-left and bottom-right of the bounding box.). You can play with the position of dummy nodes to adjust your bounding box.
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
style: [{
selector: 'node',
css: {
'content': 'data(id)',
'text-valign': 'center',
'text-halign': 'center'
}
},
{
selector: 'edge',
css: {
'curve-style': 'straight',
}
}
],
layout: {
name: 'preset'
},
elements: {
nodes: [{
data: {
id: 'n0'
}
},
{
data: {
id: 'n1'
}
},
{
data: {
id: 'n2'
}
},
{
data: {
id: 'n3'
}
},
{
data: {
id: 'n4'
}
},
{
data: {
id: 'd0'
},
position: {x: 0, y:0}
},
{
data: {
id: 'd1'
},
position: {x: 400, y:150}
}
],
edges: [{
data: {
id: 'n0n1',
source: 'n0',
target: 'n1'
}
},
{
data: {
id: 'n1n2',
source: 'n1',
target: 'n2'
}
},
{
data: {
id: 'n2n3',
source: 'n2',
target: 'n3'
}
},
{
data: {
id: 'n4n1',
source: 'n4',
target: 'n1'
}
}
]
}
});
var tl = cy.getElementById('d0');
var br = cy.getElementById('d1');
tl.lock();
br.lock();
var realGraphNodes = cy.nodes().difference(tl.union(br));
var constraints = [];
for (var i = 0; i < realGraphNodes.length; i++) {
constraints.push({ axis: 'x', left: tl, right: realGraphNodes[i], gap: 100 });
constraints.push({ axis: 'y', left: tl, right: realGraphNodes[i], gap: 100 });
constraints.push({ axis: 'x', left: realGraphNodes[i], right: br, gap: 100 });
constraints.push({ axis: 'y', left: realGraphNodes[i], right: br, gap: 100 });
}
cy.layout({name: 'cola', randomize: true, animate: false, gapInequalities: constraints}).run();
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
#cy {
height: 95%;
width: 95%;
left: 0;
top: 0;
position: absolute;
}
<html>
<head>
<meta charset=utf-8 />
<meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
<script src="https://unpkg.com/cytoscape#3.10.0/dist/cytoscape.min.js"></script>
<script src="https://unpkg.com/webcola/WebCola/cola.min.js"></script>
<script src="https://unpkg.com/cytoscape-cola/cytoscape-cola.js"></script>
</head>
<body>
<div id="cy"></div>
</body>
</html>
I am using the following code to calculate the extent of as KMLfile. How do I do this with a GeoJSON file?
let layer=new KMLLayer({ url:url });
map.add(app.layer);
app.mapView.whenLayerView(layer).then(function(layerView) {
watchUtils.whenFalseOnce(layerView, "updating", function() {
let polygons=layerView.allVisiblePolygons;
let lines=layerView.allVisiblePolylines;
let points=layerView.allVisiblePoints;
let images=layerView.allVisibleMapImages;
let extent=polygons.concat(lines).concat(points).concat(images)
.map(graphic => (graphic.extent ? graphic.extent : graphic.geometry.extent))
.reduce((previous, current) => previous.union(current));
});
You just need to use queryExtent of the GeoJSONLayerView. Take a look the example I made for you based on one of ArcGIS.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>GeoJSONLayer - 4.15</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
p {
font: 1rem 'Fira Sans', sans-serif;
}
#extentSpan {
color:crimson;
font-style: italic;
}
</style>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
/>
</head>
<body>
<p>Extent: <span id="extentSpan">...</span></p>
<div id="viewDiv"></div>
<script src="https://js.arcgis.com/4.15/"></script>
<script>
require([
"esri/Map",
"esri/layers/GeoJSONLayer",
"esri/views/MapView"
], function(Map, GeoJSONLayer, MapView) {
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:
"https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_month.geojson",
copyright: "USGS Earthquakes",
renderer: renderer
});
const map = new Map({
basemap: "gray",
layers: [geojsonLayer]
});
const view = new MapView({
container: "viewDiv",
center: [-168, 46],
zoom: 3,
map: map
});
view.whenLayerView(geojsonLayer).then(function(layerView) {
layerView.watch("updating", function(val) {
if (!val) {
layerView.queryExtent().then(function(response) {
const e = response.extent;
view.goTo(e);
document.querySelector('#extentSpan').textContent =
`${e.xmin} ${e.ymin} ${e.xmax} ${e.ymax}`;
});
}
});
});
});
</script>
</body>
</html>
I use highmaps with "Rich information on click" in a json format. For this I used a previously existing example. However, there are a few parts that I would like to add.
Separate container in which the extra information (countryChart) is
displayed instead of a single container in which both the map and
the extra information are shown Solution given by ppotaczek
Is it possible to display the total per category if no country is selected. In the example below, this means that in (Countrychart)
graph, cat1: 14, cat2: 3 and cat3: 15 (Canada, US and India added
together) are shown. Solution given by ppotaczek
The flags are not displayed, I cannot figure out why this is. Solution given by Emad
In this example I have made a start on the graph hopefully this is a good basis for the extra functionality.
$.ajax({
url: 'https://cdn.rawgit.com/highcharts/highcharts/v6.0.4/samples/data/world-population-history.csv',
success: function() {
var jsondata = {
"data": [{
"value": "8",
"code": "in",
"name": "india",
"testdata": [{
"vcount": "3"
}, {
"vcount": null
}, {
"vcount": "5"
}]
}, {
"value": "15",
"code": "us",
"name": "united states",
"testdata": [{
"vcount": "9"
}, {
"vcount": "2"
}, {
"vcount": "4"
}]
}, {
"value": "9",
"code": "ca",
"name": "canada",
"testdata": [{
"vcount": "2"
}, {
"vcount": "1"
}, {
"vcount": "6"
}]
}]
}
var mapChart;
var countryChart;
var graphdata = [];
var graphdataf = [];
var valuecount;
var countries = {};
$.each(jsondata.data, function(i, item) {
var graphval = [];
var value = item.value;
var code = item.code;
var name = item.name;
graphval.push(code);
graphval.push(value);
graphdata.push(graphval);
$.each(item.testdata, function(j, itemval) {});
countries[item.code] = {
name: item.name,
code3: item.code,
data: item.testdata
};
});
var data = [];
for (var code3 in countries) {
if (countries.hasOwnProperty(code3)) {
$.each(countries[code3].data, function(j, itemval) {
//var graphvaldata = [];
var value = itemval.vcount;
data.push({
name: countries[code3].name,
code3: code3,
value: value,
});
});
}
}
// Wrap point.select to get to the total selected points
Highcharts.wrap(Highcharts.Point.prototype, 'select', function(proceed) {
proceed.apply(this, Array.prototype.slice.call(arguments, 1));
var points = mapChart.getSelectedPoints();
if (points.length) {
if (points.length === 1) {
$('#info #flag').attr('class', 'flag ' + points[0].flag);
$('#info h2').html(points[0].name);
} else {
$('#info #flag').attr('class', 'flag');
$('#info h2').html('Comparing countries');
}
$('#info .subheader').html('<h4>Historical population</h4><small><em>Shift + Click on map to compare countries</em></small>');
if (!countryChart) {
countryChart = Highcharts.chart('country-chart', {
chart: {
height: 250,
spacingLeft: 0
},
credits: {
enabled: false
},
title: {
text: null
},
subtitle: {
text: null
},
xAxis: {
tickPixelInterval: 50,
crosshair: true,
categories: ['cat1', 'cat2', 'cat3']
},
yAxis: {
title: null,
opposite: true
},
tooltip: {
split: true
},
plotOptions: {
series: {
animation: {
duration: 500
},
marker: {
enabled: false
}
}
}
});
}
$.each(points, function(i, point) {
var data,
dataRaw = countries[point['hc-key']].data;
if (dataRaw) {
data = dataRaw.map((p) => parseInt(p.vcount));
}
// Update
if (countryChart.series[i]) {
countryChart.series[i].update({
name: this.name,
data: data,
type: points.length > 1 ? 'column' : 'column'
}, false);
} else {
countryChart.addSeries({
name: this.name,
data: data,
type: points.length > 1 ? 'column' : 'column'
}, false);
}
});
while (countryChart.series.length > points.length) {
countryChart.series[countryChart.series.length - 1].remove(false);
}
countryChart.redraw();
} else {
$('#info #flag').attr('class', '');
$('#info h2').html('');
$('#info .subheader').html('');
if (countryChart) {
countryChart = countryChart.destroy();
}
}
});
// Initiate the map chart
mapChart = Highcharts.mapChart('container', {
title: {
text: 'Population history by country'
},
subtitle: {
text: 'Source: The World Bank'
},
mapNavigation: {
enabled: true,
buttonOptions: {
verticalAlign: 'bottom'
}
},
colorAxis: {
type: 'logarithmic',
endOnTick: false,
startOnTick: false,
minColor: '#fff',
maxColor: '#3D1C5C',
min: 5,
max: 15,
},
tooltip: {
footerFormat: '<span style="font-size: 10px">(Click for details)</span>'
},
credits: {
enabled: false
},
series: [{
data: graphdata,
mapData: Highcharts.maps['custom/world'],
joinBy: 'hc-key',
name: 'Total Play',
allowPointSelect: true,
cursor: 'pointer',
states: {
select: {
color: '#a4edba',
borderColor: 'black',
dashStyle: 'shortdot'
}
}
}]
});
}
});
* {
font-family: sans-serif;
}
#wrapper {
height: 500px;
width: 1000px;
margin: 0 auto;
padding: 0;
overflow: visible;
}
#container {
float: left;
height: 500px;
width: 700px;
margin: 0;
}
#info {
float: left;
width: 270px;
padding-left: 20px;
margin: 100px 0 0 0;
border-left: 1px solid silver;
}
#info h2 {
display: inline;
font-size: 13pt;
}
#info .f32 .flag {
vertical-align: bottom !important;
}
#info h4 {
margin: 1em 0 0 0;
}
#media screen and (max-width: 920px) {
#wrapper,
#container,
#info {
float: none;
width: 100%;
height: auto;
margin: 0.5em 0;
padding: 0;
border: none;
}
}
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/maps/modules/map.js"></script>
<script src="https://code.highcharts.com/mapdata/custom/world.js"></script>
<!-- Flag sprites service provided by Martijn Lafeber, https://github.com/lafeber/world-flags-sprite/blob/master/LICENSE -->
<link rel="stylesheet" type="text/css" href="//github.com/downloads/lafeber/world-flags-sprite/flags32.css" />
<div id="wrapper">
<div id="container"></div>
<div id="info">
<span class="f32"><span id="flag"></span></span>
<h2></h2>
<div class="subheader">Click countries to view history</div>
<div id="country-chart"></div>
</div>
</div>
Thanks in advance for your help!
I can aswer to your third question : The flags are not displayed, I cannot figure out why this is.
The problem is with this line :
$('#info #flag').attr('class', 'flag ' + points[0].flag);
There is no flag property in points object, you can change it to this :
$('#info #flag').attr('class', 'flag ' + points[0]["hc-key"]);
And you will have the flag now.
https://jsfiddle.net/vq26m8nb/7/
As to your questions:
Both charts are already in separate containers. You can remove the div with 'wrapper' id to split them so that they do not appear side by side. Check this example: https://jsfiddle.net/BlackLabel/8jo7vzty/
Yes, for example you can call select on some point with an additional argument and sum the data in the wrapped select method (depending on that additional argument).
if (points.length) {
...
if (arguments[3]) {
totalData = [];
Highcharts.objectEach(countries, function(el){
el.data.forEach(function(val, i){
if (totalData[i]) {
totalData[i] += parseInt(val.vcount)
} else {
totalData[i] = parseInt(val.vcount);
}
});
});
$('#info h2').html('Total data');
countryChart.series[0].setData(totalData);
mapChart.series[0].points[0].select(false, false, true);
}
} else if (!arguments[3]) {
$('#info #flag').attr('class', '');
$('#info h2').html('');
$('#info .subheader').html('');
if (countryChart) {
countryChart = countryChart.destroy();
}
}
...
mapChart = Highcharts.mapChart('container', ...);
mapChart.series[0].points[0].select(true, false, true);
Live demo: https://jsfiddle.net/BlackLabel/mg7x3kje/
The flags are not displayed because your points do not have flag property. You can add them in the way as #Emad Dehnavi suggested.
With laravel i created Highcharts from consumed Rest API Link(Spring app) (http://85614a50.ngrok.io/api/devices) with 2 series(axes)
First series do a visualization of Memory in time so object contains(Memory usage, timestamp)
Second series do a visualization of CPU in time and object contains(CPU Usage,timestamp)
This all results are shown statically, now i want to visualise dynamically on charts.
I created a function which do a call of rest api within every 5 second, and event function inside Chart refreshing every 5 second.
It work but axes does not shows me a data from Series(it shows some random numbers because x and y variables are declare as current time and random numbers).
So i know that i must call a Series inside x,y variables.But didn't figure how. Did someone maybe know how to solve this problem ?
P.S.
In case you declare variables and chart(data) is not updated probably it will happen because i didn't turn on java client application so it showing just same data.I not able to keep application truned on because lack of memory on my harddisk. Only monitoring app is truned on so link is working!
My code Example: https://codepen.io/anon/pen/eLERGG (If you open this link it takes 5 seconds for charts to appear)
Home..blade.php
#extends('layouts.app')
#section('content')
<style type="text/css">
#container{
width: 100%;
margin: 0 auto;
}
.col-lg-4 {
margin-bottom: 10%;
min-width: 40%;
max-width: 100%;
margin: 1em auto;
height: 400px;
}
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1; /* Sit on top */
padding-top: 10%; /* Location of the box */
padding-right: 10%;
padding-left: 10%;
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgb(0,0,0); /* Fallback color */
background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}
#container.modal{
position: fixed;
width: 100%;
height: 100%;
top: 0;
left: 0;
background: rgba(0, 0, 0, 0.5);
display:block;
}
</style>
<h2 class="text-center" >{{$user->first_name}} Charts </h2>
<div id="container">
<div class="row">
</div>
</div>
<script type="text/javascript">
$(function () {
setInterval(getHighChart, 10000); //30 seconds onload="getHighChart()"
});
function getHighChart() {
$.getJSON( "http://localhost:8000/api/devices", function( data ) {
console.log(data);
var mappedClientsAllias = _.map(_.uniqBy(data, "clientName"), "clientName");
var mappedClients = _.map(_.uniqBy(data, "Id_client"), "Id_client");
var clients = [];
_.forEach(mappedClients, function(Id_client, clientName) {
var tempClient = {
Allias: mappedClientsAllias[clientName],
name: Id_client,
data: [],
memory:[]
};
tempClient2=tempClient;
_.forEach(data, function(tempData) {
if (Id_client=== tempData.Id_client**strong text**) {
_.forEach(tempData.clientData, function(clientData) {
tempClient.data.push([
clientData.timestamp,
clientData.cpuUsage,
]);
tempClient.memory.push([
clientData.timestamp,
clientData.memoryUsage,
]);
});
}
});
clients.push(tempClient);
});
console.log("clients", clients);
var chart = _.forEach(clients, function(client) {
$('<div class="col-lg-4">')
.css("position", "relative")
.appendTo("#container")
.highcharts("StockChart", {
marker: {
states: {
enabled: true
}
},
time: {
timezoneOffset: -2 * 60
},
exporting: {
buttons: {
customButton3: {
text: 'Zooming',
//make fullscreen of chart with size change
onclick: function(e) {
var w = $(window).width();
var h = $(window).height();
$(e.target).closest('#container').toggleClass('modal');
if($(e.target).closest('#container').hasClass('modal')) {
$('.col-lg-4').hide();
$(e.target).closest('.col-lg-4').show();
$('.col-lg-4').css({
'width': w * .9,
'height': h * .9
});
} else {
$('.col-lg-4').show();
$('.col-lg-4').css({
'width': '',
'height': ''
});
}
$(e.target).closest('.col-lg-4').highcharts().reflow();
}
}
}
},
rangeSelector: {
y: 15,
buttons: [
{
count: 1,
type: "minute",
text: "Sec"
},
{
count: 1,
type: "hour",
text: "Min"
},
{
count: 1,
type: "day",
text: "Hours"
},
{
type: "all",
text: "All"
}
],
title: "hours",
inputEnabled: true,
_selected: 1
},
title: {
text: client.Allias
},
yAxis: [{
labels: {
enabled: true,
align: 'right',
x: -3
},
title: {
text: 'CPU'
},
height: '50%',
lineWidth: 2,
color: 'red'
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Memory'
},
top: '70%',
height: '50%',
offset: 0,
lineWidth: 2,
}],
xAxis: {
tickInterval: 1,
title: {
enabled: true,
text: "Client usage"
},
top: '20%',
type: "datetime",
dateTimeLabelFormats: {
second: "%H:%M:%S",
minute: "%H:%M",
hour: "%H:%M",
day: "%e. %b",
week: "%e. %b",
day: "%Y<br/>%b-%d"
}
},
plotOptions: {
series: {
marker: {
enabled: false,
}
}
},
series: [{
name: "Memory USAGE",
data: client.memory.sort()
}, // Add a new series
{
name: "Cpu USAGE",
yAxis: 1,
color: 'red',
data: client.data.sort()
}],
chart: {
renderTo: "container",
height:400,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = Math.round(Math.random() * 100);
series.addPoint([x, y], false, true);
}, 1000);
}
}
},
});
});
});
}
</script>
#endsection
Layouts.app
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Master thesis application</title>
<!-- Jquery -->
<script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/js/bootstrap.min.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css">
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<!-- Import css file-->
<link href="{{asset('css/style.css')}}" rel="stylesheet" type="text/css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous">
</script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<script src="https://code.highcharts.com/stock/modules/exporting.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
</head>
<script type="text/javascript">
</script>
<body>
#include('doc.header')
#include('doc.nav')
<script>
window.onscroll = function() {myFunction()};
var navbar = document.getElementById("navbar");
var sticky = navbar.offsetTop;
function myFunction() {
if (window.pageYOffset >= sticky) {
navbar.classList.add("sticky")
} else {
navbar.classList.remove("sticky");
}
}
</script>
<div class="container">
#include('doc.ifno')
#yield('main')
</div> <!-- /container -->
#include('doc.Navfoot')
</body>
</html>