Getting county from click on OSM - leaflet

Is it possible to detect state and county based on coordinates from a click on OSM map (US only)?
I can get the coordinated using click event in Leaflet JS:
map.on('click', function(ev) {
console.log(ev.latlng);
});
I can also get location data by doing something l;like this:
map.on("click", function(ev) {
var ln = ev.latlng["lng"],
lt = ev.latlng["lat"];
pt = "https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat="+lt+"&lon="+ln;
});
Which will return json data that looks like this:
https://nominatim.openstreetmap.org/reverse?format=jsonv2&lat=28.964162684075685&lon=-98.29776763916017
But I can't seem to be able to figure out what to do next... How do I get the county and state values from it?

You can just fetch, Ajax from jquery or use axios.
let config = {
minZoom: 2,
maxZoom: 18,
};
const zoom = 5;
const lat = 28.964162684075685;
const lng = -98.29776763916017;
const map = L.map("map", config).setView([lat, lng], zoom);
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: '© OpenStreetMap contributors',
}).addTo(map);
map.on("click", function(e) {
const { lat, lng } = e.latlng;
const api = `https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lng}&zoom=18&addressdetails=1`;
fetchData(api).then((data) => {
const { county, state } = data.address;
console.log(county, state);
});
});
async function fetchData(url) {
try {
const response = await fetch(url);
const data = await response.json();
return data;
} catch (err) {
console.error(err);
}
}
*,
:after,
:before {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html {
height: 100%;
}
body,
html,
#map {
width: 100%;
height: 100%;
}
body {
position: relative;
min-height: 100%;
margin: 0;
padding: 0;
background-color: #f1f1f1;
}
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" rel="stylesheet" />
<div id="map"></div>

Related

Bound popup removed when layer changed in control

I have a map with a layer control that has overlays specified in the baselayer parameter:
var overlays = {
'Layer 1': mylayer1,
'Layer 2': mylayer2
};
L.control.layers( overlays, null, { collapsed: false } ).addTo( map );
I specify my layers as follows:
var mylayer1 = L.esri.featureLayer({
url: 'https://.../MapServer/5'
}).on( 'load', function ( e ) {
...
}).on( 'loading', function ( e ) {
...
}).bindPopup( function ( layer ) {
return L.Util.template( '<p>{_score}</p>', layer.feature.properties );
});
The issue is that when I change layers in the control the bindPopup event no longer gets called.
It's almost like the layer z-index is not updated. Would appreciate any insight on how I can address this.
See: https://codepen.io/jvanulde/pen/LYyOWZo
I see no one has given an answer.
A little around, but it works.
You add the id: x to each layer. Later in the loop you check which layer is active, and all the rest of the layers you add the style display: none.
window.addEventListener('DOMContentLoaded', () => {
let tiles = L.tileLayer('//{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors, Points &copy 2012 LINZ'
});
let l1 = L.esri.featureLayer({
url: 'https://maps-cartes.services.geo.ca/server_serveur/rest/services/NRCan/nhsl_en/MapServer/1',
id: 0, // required
simplifyFactor: 0.25,
precision: 5,
fields: ['OBJECTID'],
renderer: L.canvas()
}).bindPopup(function(layer) {
return L.Util.template('<p>Layer 1: <strong>{OBJECTID}</strong></p>', layer.feature.properties);
});
let l2 = L.esri.featureLayer({
url: 'https://maps-cartes.services.geo.ca/server_serveur/rest/services/NRCan/nhsl_en/MapServer/2',
id: 1, // required
simplifyFactor: 0.25,
precision: 5,
fields: ['OBJECTID'],
renderer: L.canvas()
}).bindPopup(function(layer) {
return L.Util.template('<p>Layer 2: <strong>{OBJECTID}</strong></p>', layer.feature.properties);
});
let map = L.map('map', {
center: [49.2827, -123.1207],
zoom: 12,
layers: [tiles]
});
let overlays = {
'Layer 1': l1,
'Layer 2': l2
};
L.control.layers(overlays, null, {
collapsed: false
}).addTo(map);
l1.addTo(map);
map.on('baselayerchange', function(e) {
const layersCanvas = document.querySelectorAll('.leaflet-overlay-pane > canvas');
layersCanvas.forEach((layer, index) => {
layer.style.display = '';
if (index !== e.layer.options.id) {
layer.style.display = 'none';
}
});
});
});
html {
height: 100%;
}
body {
min-height: 100%;
margin: 0;
padding: 0;
}
#map {
width: 100%;
height: 100vh;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"></script>
<script src="https://unpkg.com/esri-leaflet#3.0.2/dist/esri-leaflet.js"></script>
<div id="map"></div>

Color intersection leaflet circle

I have a question about leaflet/folium. I have multiple circles on a map.
All these circles does have some overlap with each other.
Wat I want to do is to draw a line/Polygon in a different color, where all circles meet (intersection).
This is an example of what I want to achieve. The blue line is the intersection and need a different color. Is this possible in folium or in pure leaflet? If so, how do I do that?
You can use the turfjs library and the turf.intersect method for this
/* eslint-disable no-undef */
/**
* intersection with turfjs
*/
// config map
let config = {
minZoom: 7,
maxZomm: 18,
};
// magnification with which the map will start
const zoom = 18;
// co-ordinates
const lat = 52.22977;
const lng = 21.01178;
// calling map
const map = L.map('map', config).setView([lat, lng], zoom);
// Used to load and display tile layers on the map
// Most tile servers require attribution, which you can set under `Layer`
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors',
}).addTo(map);
// three coordinate
const centers = [{
lat: 52.22990558765487,
lng: 21.01168513298035
},
{
lat: 52.22962958994604,
lng: 21.011593937873844
},
{
lat: 52.2297445891999,
lng: 21.012012362480167
}
]
// turf.circle option
const options = {
steps: 64,
units: 'meters',
options: {}
}
// circle radius
const radius = 30;
// array polygons
let polygons = [];
// set marker, add
centers.map(({
lat,
lng
}) => {
const polygon = turf.circle([lng, lat], radius, options);
// add cirkle polygon to map
L.geoJSON(polygon, {
color: "red",
weight: 2
}).addTo(map);
// add object to array
polygons.push(polygon);
})
// get intersection
const intersection = turf.intersect(...polygons);
// style intersection
const intersectionColor = {
color: "yellow",
weight: 2,
opacity: 1,
fillColor: "yellow",
fillOpacity: 0.7
};
// adding an intersection to the map
// and styling to this element
L.geoJSON(intersection, {
style: intersectionColor
}).addTo(map);
*,
:after,
:before {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html {
height: 100%;
}
body,
html,
#map {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/#turf/turf#5/turf.min.js"></script>
<div id="map"></div>

why isn't leaflet demo working on jsfiddle?

https://terrafrost.com/leaflet/demo01.html works as expected when ran it's own but when ran on jsfiddle at https://jsfiddle.net/x2f05eov/ all I get is a blank page. There are no errors that I'm seeing in the console.
Any ideas?
The JS code is as follows:
function layerParams(id)
{
return {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: id,
tileSize: 512,
zoomOffset: -1
};
}
var mapboxUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
var light = L.tileLayer(mapboxUrl, layerParams('mapbox/light-v10'));
var streets = L.tileLayer(mapboxUrl, layerParams('mapbox/streets-v11'));
var satellite = L.tileLayer(mapboxUrl, layerParams('mapbox/satellite-streets-v11'));
var mymap = L.map('mapid', {
center: [30.267222, -97.743056],
zoom: 13,
layers: [light]
});
var baseMaps = {
"Light": light,
"Streets" :streets,
"Satellite": satellite
};
lightLines = L.layerGroup();
streetsLines = L.layerGroup();
satelliteLines = L.layerGroup();
var params = {
color: 'blue',
opacity: 0.75,
smoothFactor: 1
};
var latlngs = [[30.267222, -97.743056],[31.267222, -96.743056]];
tempParams = Object.assign(params, {weight: 10});
satelliteLines.addLayer(L.polyline(latlngs, tempParams));
tempParams = Object.assign(params, {weight: 3});
lightLines.addLayer(L.polyline(latlngs, tempParams));
tempParams = Object.assign(params, {weight: 5});
streetsLines.addLayer(L.polyline(latlngs, tempParams));
var hasOverlay = false;
mymap.on('baselayerchange', function(e) {
switch (e.name) {
case 'Light':
if (hasOverlay) {
lightLines.addTo(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.removeFrom(mymap);
}
break;
case 'Streets':
if (hasOverlay) {
lightLines.removeFrom(mymap);
streetsLines.addTo(mymap);
satelliteLines.removeFrom(mymap);
}
break;
case 'Satellite':
if (hasOverlay) {
lightLines.removeFrom(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.addTo(mymap);
}
}
});
mymap.on('overlayadd', function(e) {
console.log('overlayadd called');
hasOverlay = true;
});
mymap.on('overlayremove', function(e) {
console.log('overlayremove called');
lightLines.removeFrom(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.removeFrom(mymap);
});
var overlays = {
'Demo': lightLines
};
L.control.layers(baseMaps, overlays).addTo(mymap);
The HTML code is as follows:
<body style="margin: 0; padding: 0; height: 100%">
<div id="mapid" style="width: 100%; height: 100%"></div>
The leaflet CSS and JS are being included as well.
You just miss a closing body and html tag
<!DOCTYPE html>
<html style="height: 100%">
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin="" />
<script src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
</head>
<body style="margin: 0; padding: 0; height: 100%">
<div id="mapid" style="width: 100%; height: 100%"></div>
<script>
function layerParams(id) {
return {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'CC-BY-SA, ' +
'Imagery © Mapbox',
id: id,
tileSize: 512,
zoomOffset: -1
};
}
var mapboxUrl = 'https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw';
var light = L.tileLayer(mapboxUrl, layerParams('mapbox/light-v10'));
var streets = L.tileLayer(mapboxUrl, layerParams('mapbox/streets-v11'));
var satellite = L.tileLayer(mapboxUrl, layerParams('mapbox/satellite-streets-v11'));
var mymap = L.map('mapid', {
center: [30.267222, -97.743056],
zoom: 13,
layers: [light]
});
var baseMaps = {
"Light": light,
"Streets": streets,
"Satellite": satellite
};
lightLines = L.layerGroup();
streetsLines = L.layerGroup();
satelliteLines = L.layerGroup();
var params = {
color: 'blue',
opacity: 0.75,
smoothFactor: 1
};
var latlngs = [
[30.267222, -97.743056],
[31.267222, -96.743056]
];
tempParams = Object.assign(params, {
weight: 10
});
satelliteLines.addLayer(L.polyline(latlngs, tempParams));
tempParams = Object.assign(params, {
weight: 3
});
lightLines.addLayer(L.polyline(latlngs, tempParams));
tempParams = Object.assign(params, {
weight: 5
});
streetsLines.addLayer(L.polyline(latlngs, tempParams));
var hasOverlay = false;
mymap.on('baselayerchange', function(e) {
switch (e.name) {
case 'Light':
if (hasOverlay) {
lightLines.addTo(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.removeFrom(mymap);
}
break;
case 'Streets':
if (hasOverlay) {
lightLines.removeFrom(mymap);
streetsLines.addTo(mymap);
satelliteLines.removeFrom(mymap);
}
break;
case 'Satellite':
if (hasOverlay) {
lightLines.removeFrom(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.addTo(mymap);
}
}
});
mymap.on('overlayadd', function(e) {
console.log('overlayadd called');
hasOverlay = true;
});
mymap.on('overlayremove', function(e) {
console.log('overlayremove called');
lightLines.removeFrom(mymap);
streetsLines.removeFrom(mymap);
satelliteLines.removeFrom(mymap);
});
var overlays = {
'Demo': lightLines
};
L.control.layers(baseMaps, overlays).addTo(mymap);
</script>
</body>
</html>
Edit:
you need to define explicit height (f.i 100vh) because setting 100% height means the height of the parent div which does not exist in this case
fiddle

How do I list my gists?

Can I get a listing of my gists?
Such a listing would list all gists, not only four and not show the contents of a gist until I click it.
There is a simple way:
https://gist.github.com/anders
just put user name in the end of the url: gist.github.com/[user name]
Use GitHub Gist API: https://developer.github.com/v3/gists/#list-a-users-gists
For example, list all public Gist of user anders: https://api.github.com/users/anders/gists
a part of return result:
"html_url": "https://gist.github.com/5b2bd534992dafe3f05202d43d8e48a2",
Then access: https://gist.github.com/5b2bd534992dafe3f05202d43d8e48a2 you will see detail content of this specific gist.
You can use the github API
for example:
MY Gists
https://api.github.com/users/{your git username}/gists
produces a json file like seen below:
This answer correctly suggests retreiving gist information with the free, unauthenticated, cors-enabled API: https://api.github.com/users/${username}/gists.
However, the answer doesn't mention that the initial request only returns the first page. To get all public gists for a user, iterate the pages until you see an empty array response (I guess you could save a request if any returns less than the maximum page size, which appears to be 30). Here's an example in JS for convenience:
const fetchJson = (...args) =>
fetch(...args).then(response => {
if (!response.ok) {
throw Error(response.status);
}
return response.json();
});
const fetchGists = async (username, maxPages=10) => {
const gists = [];
for (let page = 1; page <= maxPages; page++) {
const url = `https://api.github.com/users/${username}/gists?page=${page}`;
const chunk = await fetchJson(url);
if (chunk.length === 0) {
break;
}
gists.push(...chunk);
}
return gists;
};
fetchGists("gaearon").then(gists => {
// for all fields:
//document.body.textContent = JSON.stringify(gists, null, 2);
// ...or select interesting fields:
gists = gists.map(({
description, files, html_url, created_at, updated_at
}) => ({
description, files, html_url, created_at, updated_at
})).sort((a, b) => b.updated_at.localeCompare(a.updated_at));
document.body.textContent =
`total number of public gists: ${gists.length}
${JSON.stringify(gists, null, 2)}`;
});
body {
white-space: pre;
font-family: monospace;
}
Caution: the rate limit at the time of writing is 60 requests per hour, which is easy to exceed. You can monitor your current rate limits in the response headers:
x-ratelimit-limit: 60
x-ratelimit-remaining: 0
x-ratelimit-reset: 1664391218
x-ratelimit-resource: core
x-ratelimit-used: 60
Here's a more comprehensive example which shows the rate limits and gists and a prettier interface. I host a version on GitHub pages so I can easily find my gists (the built-in GitHub website gist page is awkward to click through 10 items at a time and has poor search functionality):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gist List</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/5.1.0/github-markdown-dark.min.css" crossorigin="anonymous" referrerpolicy="no-referrer" />
<style>
body {
margin: 0;
padding: 2.5em;
box-sizing: border-box;
}
.markdown-body {
min-width: 200px;
max-width: 980px;
margin: 0 auto;
}
.github-limits {
margin-top: 1em;
margin-bottom: 2em;
}
.gists ul {
list-style-type: none;
padding: 0 !important;
margin: 0 !important;
}
.gists th {
cursor: pointer;
position: relative;
}
.gists .sorted-desc:after {
position: absolute;
right: 0.5em;
content: "\25BC";
font-size: 0.8em;
}
.gists .sorted-asc:after {
position: absolute;
right: 0.5em;
content: "\25B2";
font-size: 0.8em;
}
.github-logo {
position: absolute;
right: 1.5em;
top: 1.5em;
}
td, th {
min-width: 75px;
font-size: 0.9em;
word-break: break-word;
}
#media (max-width: 767px) {
.markdown-body {
padding: 15px;
}
}
#media (max-width: 467px) {
.markdown-body {
padding: 10px;
}
td, th {
min-width: 70px;
font-size: 0.8em;
}
}
</style>
</head>
<body class="markdown-body">
<div class="github-logo">
<a href="https://github.com/ggorlen/gist-list">
<img src="https://github.githubassets.com/images/modules/site/icons/footer/github-mark.svg" alt="GitHub mark" width="20" height="20">
</a>
</div>
<h1>Gist List</h1>
<div>
<form class="gist-search">
<input
class="github-username"
placeholder="Enter a GitHub username"
autofocus
>
<input type="submit" value="search">
</form>
</div>
<div class="github-limits"></div>
<div class="gists"></div>
<script>
"use strict";
class GHRequestError extends Error {
constructor(limits = {}, ...params) {
super(...params);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, GHRequestError);
}
this.name = "GHRequestError";
this.limits = limits;
}
}
const fetchJson = (...args) => fetch(...args).then(async response => {
const {headers} = response;
const limits = {
remaining: headers.get("x-ratelimit-remaining"),
limit: headers.get("x-ratelimit-limit"),
reset: new Date(headers.get("x-ratelimit-reset") * 1000),
};
if (!response.ok) {
const message = response.statusText || response.status;
throw new GHRequestError(limits, message);
}
return {limits, payload: await response.json()};
});
const fetchGists = async (username, maxPages=10) => {
const gists = [];
let limits;
for (let page = 1; page <= maxPages; page++) {
const url = `https://api.github.com/users/${username}/gists?page=${page}`;
const {limits: lastLimits, payload: chunk} = await fetchJson(url);
limits = lastLimits;
if (chunk.length === 0) {
break;
}
gists.push(...chunk);
}
return {limits, gists};
};
const firstFile = gist =>
Object.keys(gist.files).length
? Object.values(gist.files)[0].filename : "";
const gistDescription = gist => `
<a href="${gist.html_url}">
${gist.description || (
Object.keys(gist.files).length
? firstFile(gist)
: "<em>no description</em>"
)
}
</a>
`;
const gistFiles = gist => `
<ul>
${Object.values(gist.files)
.map(e => `
<li>${e.filename}</li>
`)
.join("")}
</ul>
`;
const gistTableRow = gist => `
<tr>
<td>
${gistDescription(gist)}
</td>
<td>
${gistFiles(gist)}
</td>
<td>
${gist.created_at.slice(0, 10)}
</td>
<td>
${gist.updated_at.slice(0, 10)}
</td>
</tr>
`;
const gistsTable = gists =>
gists.length === 0 ? "<div>No gists found</div>" : `
<table>
<tbody>
<tr>
${headers.map(({name}) => `<th>${name}</th>`).join("")}
</tr>
${gists.map(gistTableRow).join("")}
</tbody>
</table>
`;
const listenToHeaderClick = header => {
header.addEventListener("click", ({target: {textContent}}) => {
let {key, ascending} = headers.find(e => e.name === textContent);
if (sortedBy === textContent) {
gists.reverse();
ascending = header.classList.contains("sorted-desc");
}
else {
sortedBy = textContent;
gists.sort((a, b) => key(a).localeCompare(key(b)));
if (!ascending) {
gists.reverse();
}
}
gistsToDOM(gists);
showSortedIcon(ascending);
});
};
const gistsToDOM = gists => {
document.querySelector(".gists").innerHTML = gistsTable(gists);
document.querySelectorAll(".gists th").forEach(listenToHeaderClick);
};
const limitsToDOM = limits => {
document.querySelector(".github-limits").innerHTML = `
<small>
<em>
${limits.remaining}/${limits.limit} API requests remaining.
Usage resets at ${limits.reset}.
</em>
</small>
`;
};
const showSortedIcon = ascending => {
document.querySelectorAll(".gists th").forEach(e => {
if (e.textContent === sortedBy) {
e.classList.add(ascending ? "sorted-asc" : "sorted-desc");
}
});
};
const handleGistsResponse = response => {
({limits, gists} = response);
limitsToDOM(limits);
gistsToDOM(gists);
showSortedIcon(headers.find(e => e.name === sortedBy).ascending);
};
const handleError = err => {
const gistsEl = document.querySelector(".gists");
gistsEl.innerHTML = err.message;
limitsToDOM(err.limits);
};
const searchGists = username => {
const submit = document.querySelector(".gist-search [type='submit']");
submit.disabled = true;
fetchGists(username)
.then(handleGistsResponse)
.catch(handleError)
.finally(() => submit.disabled = false);
};
const trySearchFromURLParam = () => {
const username = new URLSearchParams(window.location.search).get("username");
if (username) {
const unEl = document.querySelector(".github-username");
unEl.value = username;
searchGists(username);
}
};
const listenForSubmit = () => {
document.querySelector(".gist-search")
.addEventListener("submit", event => {
event.preventDefault();
const {value} = event.target.querySelector(".github-username");
searchGists(value);
});
};
let limits;
let gists;
let sortedBy = "Created";
const headers = Object.freeze([
{
name: "Description",
key: e => e.description || firstFile(e),
ascending: true,
},
{
name: "Files",
key: firstFile,
ascending: true,
},
{
name: "Created",
key: e => e.created_at,
ascending: false,
},
{
name: "Updated",
key: e => e.updated_at,
ascending: false,
},
]);
trySearchFromURLParam();
listenForSubmit();
</script>
</body>
</html>

nvd3 Display 2 Chart

at my work I try to print some graph with nvd3.
But I can only display 1 graph on my page, and I don't understand why the previous graph don't appear.
Could you give me some hint ?
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<link href="lib/css/nv.d3.css" rel="stylesheet">
</head>
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
position: relative;
width: 960px;
}
/**********
* Legend
*/
.nvd3 .nv-legend .nv-series {
cursor: pointer;
}
.nvd3 .nv-legend .nv-disabled circle {
fill-opacity: 0;
}
text {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
form {
position: absolute;
right: 10px;
top: 10px;
}
#chart, #pid svg {
height: 600px;
width: 600px;
}
</style>
<div id="pid">
<svg></svg>
</div>
<div id="chart">
<svg></svg>
</div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="lib/js/nv.d3.js"></script>
<script>
var divs = ["pid", "chart"];
divs["pid"]= {id:"#pid svg", datam:[
{
values:[
{x:"M",y:1},
{x:"T",y:2},
{x:"W",y:3},
{x:"R",y:3},
{x:"F",y:4},
{x:"S",y:5},
{x:"U",y:6}
],
key:"Apples"
},
{
values:[
{x:"M",y:5},
{x:"T",y:2},
{x:"W",y:6},
{x:"R",y:8},
{x:"F",y:2},
{x:"S",y:4},
{x:"U",y:1}
],
key:"Zebras"
},
{
values:[
{x:"M",y:4},
{x:"T",y:6},
{x:"W",y:5},
{x:"R",y:7},
{x:"F",y:7},
{x:"S",y:2},
{x:"U",y:5}
],
key:"Bananas"
}
], color:['purple', 'black', 'yellow']};
divs["chart"]= {id:"#chart svg", datam:[
{
values:[
{x:"M",y:1},
{x:"T",y:2},
{x:"W",y:3},
{x:"R",y:3},
{x:"F",y:4},
{x:"S",y:5},
{x:"U",y:6}
],
key:"Apples"
},
{
values:[
{x:"M",y:5},
{x:"T",y:2},
{x:"W",y:6},
{x:"R",y:8},
{x:"F",y:2},
{x:"S",y:4},
{x:"U",y:1}
],
key:"Zebras"
}
], color:['red', 'blue', 'green']};
console.log(divs)
var i=0;
var chart = new Array(2);
nv.render = function render(step) {
// number of graphs to generate in each timeout loop
step = step || 1;
nv.render.active = true;
nv.dispatch.render_start();
setTimeout(function() {
var chart, graph;
for (var i = 0; i < step && (graph = nv.render.queue[i]); i++) {
chart = graph.generate();
if (typeof graph.callback == typeof(Function)) graph.callback(chart);
nv.graphs.push(chart);
}
nv.render.queue.splice(0, i);
if (nv.render.queue.length) setTimeout(arguments.callee, 0);
else {
nv.dispatch.render_end();
nv.render.active = false;
}
}, 0);
};
nv.render.active = false;
nv.render.queue = [];
for (var key in divs) {
console.log(i);
nv.addGraph(function(obj) {
if (typeof arguments[0] === typeof(Function)) {
obj = {generate: arguments[0], callback: arguments[1]};
}
nv.render.queue.push(obj);
console.log(nv.render.queue.length);
if (!nv.render.active) {
nv.render();
}
chart[i] = nv.models.multiBarChart().showControls(true).groupSpacing(0.5).color(divs[key]['color']);
chart[i].yAxis
.tickFormat(d3.format(',.1f'));
d3.select(divs[key]['id'])
.datum(divs[key]['datam'])
.transition().duration(500).call(chart[i]);
nv.utils.windowResize(chart[i].update);
return chart[i];
});
i++;
};
// render function is used to queue up chart rendering
// in non-blocking timeout functions
</script>
I hope you colud help me, thanks.