Leaflet circle loop remove past and retain recent iterations - javascript

Good day!
I am trying to play around with animating a pulsating radius based on leaflet L.cicle and have managed to limit the radius size.
However, I am having a problem with several iterations of the radius are not removed from the map, resulting in a large number of circles.
I would appreciate some advice on how to remove the previous iterations of the circle and keep the most recent circle generated.
<!DOCTYPE html>
<html>
<head>
<title>Map</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
<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>
<style>
html, body {
height: 100%;
margin: 0;
}
#map {
width: 600px;
height: 400px;
}
</style>
<style>body { padding: 0; margin: 0; } #map { height: 100%; width: 100vw; }</style>
</head>
<body>
<div></div>
<div id='map'></div>
<script>
var map = L.map('map').setView([1.3400776203517657, 103.88408580637439],6);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token=ACCESS_TOKEN', {
maxZoom: 18,
attribution: 'Map data © OpenStreetMap contributors, ' +
'Imagery © Mapbox',
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1
}).addTo(map);
function radiuspulse() {
const secs = 0.1 * 60;
let radiuschange = 0;
setInterval(function() {
if (radiuschange < 50000) {
radiuschange += 500;
const circle = L.circle([1.3400776203517657, 103.88408580637439], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.1,
weight:0,
id: 'abc123',
radius: radiuschange
}).addTo(map);
function clearcontent() {
document.getElementsByTagName("g").innerHTML = "";
};
}
else {
// clearInterval();
let radiuschange = 0;
radiuspulse();
}
}, secs);
}
radiuspulse()
</script>
</body>
</html>

Don't create always a new Circle, change only the radius with setRadius():
Also you can remove the circle with circle.removeFrom(map)
var circle = L.circle([1.3400776203517657, 103.88408580637439], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.1,
weight:0,
id: 'abc123',
radius: 500
}).addTo(map);
var interval = null;
function radiuspulse() {
const secs = 0.1 * 60;
let radiuschange = circle.getRadius();
interval = setInterval(function() {
if (radiuschange < 50000) {
radiuschange += 500;
circle.setRadius(radiuschange);
}
else {
clearInterval(interval);
circle.setRadius(0);
radiuspulse();
}
}, secs);
}
function clearcontent() {
circle.removeFrom(map);
}

Related

Extending leaflet SVG renderer fails to show vector layers

I am working on modifying the Leaflet SVG renderer for some cosmetic changes, but I have not been able to get even the most basic extension to work (even without any custom code aside from changing things like create() to L.DomUtil.create()).
here is my most simple example setup:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin=""/>
<script src="https://unpkg.com/leaflet#1.6.0/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>
<style>
body{
padding: 0;
margin: 0;
}
#mapid{
width: 100vw;
height: 100vh;
}
</style>
</head>
<body>
<div id="mapid" style=""></div>
<script>
L.SVG.test = L.SVG.extend({
_initPath: function(layer){
const path = layer._path = L.DomUtil.create('path');
// #namespace Path
// #option className: String = null
// Custom class name set on an element. Only for SVG renderer.
if(layer.options.className){
path.classList.add(...L.Util.splitWords(layer.options.className));
}
if(layer.options.interactive){
path.classList.add('leaflet-interactive');
}
this._updateStyle(layer);
this._layers[L.Util.stamp(layer)] = layer;
},
_updateStyle: function(layer){
const path = layer._path,
options = layer.options;
if(!path){
return;
}
if(options.stroke){
path.setAttribute('stroke', options.color);
path.setAttribute('stroke-opacity', options.opacity);
path.setAttribute('stroke-width', options.weight);
path.setAttribute('stroke-linecap', options.lineCap);
path.setAttribute('stroke-linejoin', options.lineJoin);
if(options.dashArray){
path.setAttribute('stroke-dasharray', options.dashArray);
} else {
path.removeAttribute('stroke-dasharray');
}
if(options.dashOffset){
path.setAttribute('stroke-dashoffset', options.dashOffset);
} else {
path.removeAttribute('stroke-dashoffset');
}
} else {
path.setAttribute('stroke', 'none');
}
if(options.fill){
path.setAttribute('fill', options.fillColor || options.color);
path.setAttribute('fill-opacity', options.fillOpacity);
path.setAttribute('fill-rule', options.fillRule || 'evenodd');
} else {
path.setAttribute('fill', 'none');
}
}
});
var testRenderer = new L.SVG.test();
var map = L.map('mapid', {preferCanvas: false, renderer: testRenderer}).setView([51.505, -0.09], 13);
var tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© OpenStreetMap'
}).addTo(map);
L.marker([51.5, -0.09]).addTo(map)
.bindPopup("<b>Hello world!</b><br />I am a popup.");
L.polygon([
[51.509, -0.08],
[51.503, -0.06],
[51.51, -0.047]
], {fillOpacity: 0.5}).addTo(map).bindPopup("I am a polygon.");
L.circle([51.508, -0.11], 500, {fillOpacity: 0.5}).addTo(map).bindPopup("I am a circle.");
</script>
</body>
</html>
It does not throw any errors in the console and I really don't know where to go from here.
Inspecting the dom shows that the layers exist in the svg tag and that they have coordinates, but the g element does not seem to have any height.
what am I doing wrong?

leaflet path not very accurate when on a skateboard

I'm trying to draw a path while on my skateboard. The path is not very accurate and sometimes speed will show 2500mph which obviously isn't correct.
<!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.0" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/icons/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/icons/favicon-16x16.png"
/>
<link rel="manifest" href="/manifest.json" />
<link rel="mask-icon" href="/icons/safari-pinned-tab.svg" color="#5bbad5" />
<meta name="msapplication-TileColor" content="#da532c" />
<meta name="theme-color" content="#ffffff" />
<title>Tracking Map - Skatespot.com</title>
<script src="https://cdn.jsdelivr.net/npm/#turf/turf#6/turf.min.js"></script>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet#1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""
/>
<link
rel="stylesheet"
href="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.css"
/>
<style>
* {
box-sizing: border-box;
}
html {
font-size: 62.5%;
}
body {
margin: 0;
padding: 1rem;
font-size: 1.6rem;
font-family: sans-serif;
width: calc(100vw - 2rem);
height: calc(100vh - 13.7rem);
margin: 0 auto;
}
header {
padding: 1rem 0;
}
#map {
width: 100%;
height: 100%;
}
.marker img {
width: 3rem;
}
.marker span {
display: block;
background: #fff;
width: 10rem;
padding: 1rem;
border-radius: 0.4rem;
border: 1px solid black;
}
#status {
display: block;
}
header nav {
display: flex;
justify-content: flex-start;
align-items: center;
}
header nav * {
margin: 0 0.5rem;
}
#logo {
width: 3rem;
border: none;
display: inline-block;
}
#media (min-width: 481px) {
/* portrait e-readers (Nook/Kindle), smaller tablets # 600 or # 640 wide. */
#status {
display: inline-block;
}
body {
height: calc(100vh - 9.8rem);
}
}
</style>
</head>
<body>
<header>
<nav>
<img id="logo" src="/logo.svg" alt="Skatespot.com" />
<button id="start">start</button>
<button id="stop">stop</button>
<button id="marker">add marker</button>
<button id="export">export</button>
</nav>
<span id="status"></span>
<span id="distance"></span>
</header>
<div id="map"></div>
<script
src="https://unpkg.com/leaflet#1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""
></script>
<script src="https://unpkg.com/leaflet-control-geocoder/dist/Control.Geocoder.js"></script>
<script>
const exportButton = document.getElementById("export");
let intv;
let watchId;
const status = document.getElementById("status");
const distance = document.getElementById("distance");
let startTime;
let markers = [];
let stats = { topSpeed: 0 };
const map = L.map("map", {
center: [9.082, 8.6753],
zoom: 8,
});
const osm = L.tileLayer(
"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
{
attribution:
'© SkateSpot, Inc.',
}
).addTo(map);
const mqi = L.tileLayer(
"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
{
id: "mapbox.streets",
attribution:
'© SkateSpot, Inc.',
}
);
const baseMaps = {
Street: osm,
Satellite: mqi,
};
const overlays = {
//add any overlays here
};
L.control
.layers(baseMaps, overlays, { position: "bottomleft" })
.addTo(map);
L.Control.geocoder().addTo(map);
if (!navigator.geolocation) {
console.log("Your browser doesn't support geolocation feature!");
} else {
navigator.geolocation.getCurrentPosition(setMapStart);
}
const trackingPath = [];
const polyline = L.polyline([], {
color: "red",
weight: 3,
className: "path",
}).addTo(map);
function start() {
startTime = new Date().getTime();
watchId = navigator.geolocation.watchPosition(
getPosition,
console.error,
{ enableHighAccuracy: true }
);
}
function setMapStart(position) {
const { latitude, longitude, accuracy } = position.coords;
const pos = [latitude, longitude];
console.log("set: ", pos);
map.setView(new L.LatLng(latitude, longitude), 15, {
animation: true,
});
}
function getPosition(position) {
// console.log(position)
const { latitude, longitude, accuracy } = position.coords;
const pos = [latitude, longitude];
//const pos = turf.randomPosition([49, 23, 43, 20])
trackingPath.push({
pos,
time: new Date().getTime(),
});
console.log("Time", new Date().getTime());
console.log("Time", new Date());
polyline.addLatLng(pos);
map.fitBounds(polyline.getBounds());
//distance
if (trackingPath.length) {
const line = turf.lineString(trackingPath.map((i) => i.pos));
console.log("");
const length = turf.length(line, { units: "miles" });
//speed
curTime = new Date().getTime();
const diffTime = (curTime - startTime) / 1000 / 60 / 60;
const speed = length / diffTime;
const segStop = trackingPath[trackingPath.length - 1];
const segStart = trackingPath[trackingPath.length - 2];
const segment = turf.lineString([segStart.pos, segStop.pos]);
const segmentLength = turf.length(segment, { units: "miles" });
const tDiff = (segStop.time - segStart.time) / 1000 / 60 / 60;
const segmentSpeed = segmentLength / tDiff;
const sSpeed10 = getSegmentSpeed(10, trackingPath);
console.log("speed", speed, length / speed);
stats.distance = parseFloat(length.toFixed(4));
stats.avgSpeed = parseFloat(speed.toFixed(2));
stats.currSpeed = parseFloat(segmentSpeed.toFixed(2));
stats.avgLast10Speed = parseFloat(sSpeed10.toFixed(2));
if (stats.topSpeed <= stats.currSpeed) {
stats.topSpeed = stats.currSpeed;
}
distance.innerHTML = `${stats.distance} miles, avg ${stats.avgSpeed} mph,
segment speed ${stats.currSpeed} and for the last 10 points: ${stats.avgLast10Speed} top speed: ${stats.topSpeed}`;
}
console.log(
"Your coordinate is: Lat: " +
latitude +
" Long: " +
longitude +
" Accuracy: " +
accuracy
);
}
exportButton.addEventListener("click", function () {
console.log("trackingPath", trackingPath);
save(
"data.json",
JSON.stringify({ paths: trackingPath, markers, stats }, null, 2)
);
});
function getSegmentSpeed(segmentPoints, trackingPath) {
if (trackingPath.length < segmentPoints) return 0;
const segStop = trackingPath[trackingPath.length - 1];
const segStart = trackingPath[trackingPath.length - segmentPoints];
const segment = turf.lineString([segStart.pos, segStop.pos]);
const segmentLength = turf.length(segment, { units: "miles" });
const tDiff = (segStop.time - segStart.time) / 1000 / 60 / 60;
const segmentSpeed = segmentLength / tDiff;
return segmentSpeed;
}
function save(filename, data) {
const blob = new Blob([data], { type: "text/csv" });
if (window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, filename);
} else {
const elem = window.document.createElement("a");
elem.href = window.URL.createObjectURL(blob);
elem.download = filename;
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
}
}
function addMarker(e) {
e.preventDefault();
status.innerText = "adding marker...";
navigator.geolocation.getCurrentPosition((position) => {
const { latitude, longitude, accuracy } = position.coords;
const pos = [latitude, longitude];
markers.push({ pos, time: new Date().getTime() });
const marker = L.marker(pos, {
icon: new L.DivIcon({
className: "marker",
html: `<img src="/icons/marker.svg" alt="" />
<textarea>click to edit</textarea>`,
}),
}).addTo(map);
const Overlaymaps = {
Marker: marker,
};
L.control.layers(Overlaymaps).addTo(map);
status.innerText = `Marker added at ${pos.join(", ")}`;
});
}
function startTracking(e) {
status.innerText = "Started tracking...";
e.preventDefault();
start();
}
function stopTracking(e) {
status.innerText = "Stopped tracking.";
e.preventDefault();
//clearInterval(intv);
navigator.geolocation.clearWatch(watchId);
}
document.getElementById("start").addEventListener("click", startTracking);
document.getElementById("stop").addEventListener("click", stopTracking);
document.getElementById("marker").addEventListener("click", addMarker);
</script>
</body>
</html>
As far as reproducing you'd have to get on a bike or skateboard to test it. But I get long straight lines that appear to show up near beginning and end of a run.
You can test it online here: https://skatespot.profullstack.com/
Click "start" then skate somewhere
Appears to work flawlessly in a car but slower moving transportion seems buggy at best for paths.

Keep Getting this.callInitHooks error (Leaflet)

I'm trying to add markers and a search bar to my leaflet choropleth map. However, I keep running into an error that tells me: Uncaught TypeError: this.callInitHooks is not a function. It comes from my leaflet.js file, and am unsure how to fix it. Most of my error seems to come from the leaflet links I've copied into my body before my script, or because of me trying to add a search bar or markets onto my map. I pasted my code below:
<html>
<head>
<title>How to make a choropleth map with Leaflet.js</title>
<meta charset="utf-8">
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.3.0/dist/leaflet.css" />
<link rel="stylesheet" href="leaflet-search.css" />
<script src="censustracts.js"></script>
<style type="text/css">
html, body, #map{
height: 100%;
padding: 0;
margin: 0;
}
.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255,255,255,0.8);
box-shadow: 0 0 15px rgba(0,0,0,0.2);
border-radius: 5px;
}
.info h4 {
margin: 0 0 5px;
color: #777;
}
.legend {
line-height: 18px;
color: #555;
}
.legend i {
width: 18px;
height: 18px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
</style>
</head>
<body>
<div id="map"></map>
<script src="https://unpkg.com/leaflet#1.3.0/dist/leaflet.js"></script>
<script src="leaflet-search.js"></script>
<script type="text/javascript">
var map = L.map('map').setView([37.8, -96], 4);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {attribution: 'OSM'})
.addTo(map);
L.geoJson(statesData).addTo(map);
L.geoJson(statesData).addTo(map);
function getColor(d) {
return d > 1000 ? '#800026' :
d > 500 ? '#BD0026' :
d > 200 ? '#E31A1C' :
d > 100 ? '#FC4E2A' :
d > 50 ? '#FD8D3C' :
d > 20 ? '#FEB24C' :
d > 10 ? '#FED976' :
'#FFEDA0';
}
function style(feature) {
return {
fillColor: getColor(feature.properties.density),
weight: 2,
opacity: 1,
color: 'white',
dashArray: '3',
fillOpacity: 0.7
};
}
L.geoJson(statesData, {style: style}).addTo(map);
///Functionality
function highlightFeature(e) {
var layer = e.target;
layer.setStyle({
weight: 5,
color: '#666',
dashArray: '',
fillOpacity: 0.7
});
info.update(layer.feature.properties);
if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
layer.bringToFront();
}
}
function resetHighlight(e) {
geojson.resetStyle(e.target);
info.update();
}
function zoomToFeature(e) {
map.fitBounds(e.target.getBounds());
}
function onEachFeature(feature, layer) {
layer.on({
mouseover: highlightFeature,
mouseout: resetHighlight,
click: zoomToFeature
});
}
geojson = L.geoJson(statesData, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
//Add info
var info = L.control();
info.onAdd = function (map) {
this._div = L.DomUtil.create('div', 'info'); // create a div with a class "info"
this.update();
return this._div;
};
// method that we will use to update the control based on feature properties passed
info.update = function (props) {
this._div.innerHTML = '<h4>US Population Density</h4>' + (props ?
'<b>' + props.name + '</b><br />' + props.density + ' people / mi<sup>2</sup>'
: 'Hover over a state');
};
info.addTo(map);
//Add Legend
var legend = L.control({position: 'bottomright'});
legend.onAdd = function (map) {
var div = L.DomUtil.create('div', 'info legend'),
grades = [0, 10, 20, 50, 100, 200, 500, 1000],
labels = [];
// loop through our density intervals and generate a label with a colored square for each interval
for (var i = 0; i < grades.length; i++) {
div.innerHTML +=
'<i style="background:' + getColor(grades[i] + 1) + '"></i> ' +
grades[i] + (grades[i + 1] ? '–' + grades[i + 1] + '<br>' : '+');
}
return div;
};
legend.addTo(map);
///Bind Popups
var data = [
{"loc":[32,-86], "title":"aquamarine"},
{"loc":[41.575730,13.002411], "title":"black"},
{"loc":[41.807149,13.162994], "title":"blue"},
{"loc":[41.507149,13.172994], "title":"chocolate"},
{"loc":[41.847149,14.132994], "title":"coral"},
{"loc":[41.219190,13.062145], "title":"cyan"},
{"loc":[41.344190,13.242145], "title":"darkblue"},
{"loc":[41.679190,13.122145], "title":"Darkred"},
{"loc":[41.329190,13.192145], "title":"Darkgray"},
{"loc":[41.379290,13.122545], "title":"dodgerblue"},
{"loc":[41.409190,13.362145], "title":"gray"},
{"loc":[41.794008,12.583884], "title":"green"},
{"loc":[41.805008,12.982884], "title":"greenyellow"},
{"loc":[41.536175,13.273590], "title":"red"},
{"loc":[41.516175,13.373590], "title":"rosybrown"},
{"loc":[41.506175,13.273590], "title":"royalblue"},
{"loc":[41.836175,13.673590], "title":"salmon"},
{"loc":[41.796175,13.570590], "title":"seagreen"},
{"loc":[41.436175,13.573590], "title":"seashell"},
{"loc":[41.336175,13.973590], "title":"silver"},
{"loc":[41.236175,13.273590], "title":"skyblue"},
{"loc":[41.546175,13.473590], "title":"yellow"},
{"loc":[41.239190,13.032145], "title":"white"}
];
var markersLayer = new L.LayerGroup(); //layer contain searched elements
map.addLayer(markersLayer);
var controlSearch = L.Control.Search({
position:'topright',
layer: markersLayer,
initial: false,
zoom: 12,
marker: false
});
map.addControl( controlSearch );
for(i in data) {
var title = data[i].title, //value searched
loc = data[i].loc, //position found
marker = new L.Marker(new L.latLng(loc), {title: title} );//se property searched
marker.bindPopup('title: '+ title );
markersLayer.addLayer(marker);
}
</script>
</body>
</html>
Don't use new with lowercase function:
marker = new L.Marker(new L.latLng(loc), {title: title} );
Use new L.LatLng(loc) or L.latLng(loc) without new

How to select existing chart and update it in NVD3.js

Please take a look at the below sample from NDV3.js chart library:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.min.js"></script>
<link href="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.css" rel="stylesheet" type="text/css">
<style>
text {
font: 12px sans-serif;
}
svg {
display: block;
}
html, body, #chart1, svg {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
.dashed {
stroke-dasharray: 5,5;
}
</style>
</head>
<body class='with-3d-shadow with-transitions'>
<div style="position:absolute; top: 0; left: 0;">
<button onclick="updateChart();">Update Chart</button>
<script>
var updateChart = function() {
// GET CHART HERE
chart.update();
}
</script>
</div>
<div id="chart1"></div>
<script>
// Wrapping in nv.addGraph allows for '0 timeout render', stores rendered charts in nv.graphs, and may do more in the future... it's NOT required
var chart;
var data;
var legendPosition = "top";
nv.addGraph(function() {
chart = nv.models.lineChart()
.options({
duration: 300,
useInteractiveGuideline: true
})
;
// chart sub-models (ie. xAxis, yAxis, etc) when accessed directly, return themselves, not the parent chart, so need to chain separately
chart.xAxis
.axisLabel("Time (s)")
.tickFormat(d3.format(',.1f'))
.staggerLabels(true)
;
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(function(d) {
if (d == null) {
return 'N/A';
}
return d3.format(',.2f')(d);
})
;
data = sinAndCos();
d3.select('#chart1').append('svg')
.datum(data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function sinAndCos() {
var sin = [];
for (var i = 0; i < 100; i++) {
sin.push({x: i, y: i % 10 == 5 ? null : Math.sin(i/10) }); //the nulls are to show how defined works
}
return [
{
area: true,
values: sin,
key: "Sine Wave",
color: "#ff7f0e",
strokeWidth: 4,
classed: 'dashed'
}
];
}
</script>
</body>
</html>
This sample is working fine. Please look at the "updateChart" function. The problem is that I have to keep a reference to my chart and update it there. Is there an alternative for that like select it by "d3.select(...)" and update it?
This may be a late reply. Nevertheless...
Tried the below solution where the chart is still maintained as an instance and the update button's onclick triggers an update to the data.
(Added a toggle to return different data to demonstrate update functionality)
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.min.js"></script>
<link href="https://cdn.rawgit.com/novus/nvd3/v1.8.1/build/nv.d3.css" rel="stylesheet" type="text/css">
</head>
<body class='with-3d-shadow with-transitions'>
<div style="position:absolute; top: 0; left: 0;">
<button onclick="update();">Update Chart</button>
</div>
<div id="chart1">
<svg></svg>
</div>
<script>
var chart;
var toggle = true;
var chartData;
nv.addGraph(function () {
chart = nv.models.lineChart()
.options({
duration: 300,
useInteractiveGuideline: true
});
chart.xAxis
.axisLabel("Time (s)")
.tickFormat(d3.format(',.1f'))
.staggerLabels(true);
chart.yAxis
.axisLabel('Voltage (v)')
.tickFormat(function (d) {
if (d == null) {
return 'N/A';
}
return d3.format(',.2f')(d);
});
var data = sinAndCos();
chartData = d3.select('#chart1 svg').datum(data);
chartData.transition().duration(500).call(chart);
d3.select('#chart1').append('svg')
.datum(data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
function update() {
var data = sinAndCos();
chartData.datum(data).transition().duration(500).call(chart);
nv.utils.windowResize(chart.update);
};
function sinAndCos() {
var sin = [],
sin2 = [];
for (var i = 0; i < 100; i++) {
sin2.push({
x: i,
y: i % 10 == 5 ? null : Math.sin(i / 10) * 0.25 + 0.5
});
sin.push({
x: i,
y: i % 10 == 5 ? null : Math.sin(i / 10)
});
}
if (toggle) {
toggle = !toggle;
return [{
area: false,
values: sin2,
key: "Sine 2 Wave",
color: "#2ca02c",
strokeWidth: 4,
classed: 'dashed'
}];
} else {
toggle = !toggle;
return [{
area: true,
values: sin,
key: "Sine Wave",
color: "#ff7f0e",
strokeWidth: 4,
classed: 'dashed'
}];
}
}
</script>
<style>
text {
font: 12px sans-serif;
}
svg {
display: block;
}
html,
body,
#chart1,
svg {
margin: 0px;
padding: 0px;
height: 100%;
width: 100%;
}
.dashed {
stroke-dasharray: 5, 5;
}
</style>
</body>
</html>

Admob Phonegap build Stuck

Ok I have an application on the market for testing purposes and Im trying to implement admob ads I have my account for banner ads and everything the only thing is that I dont know how to set it up I need help please this is the sample application. Thank you
Mostly what i need i need to show banner ads on my title screen game screen and game over screen Ive tried several tutorials none seem to get me anywhere so thats why i decided maybe here one of you can help Me with this.
This is the html file----------------------------------------------------
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8-8">
<meta name="viewport" content="user-scalable=0, initial-scale=1,minimum-scale=1, maximum-scale=1, width=device-width, minimal-ui=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<script type="text/javascript" src="js/phaser.js"></script>
<script src="js/stateTitle.js"></script>
<script src="js/characters.js"></script>
<style>
body {
padding: 0px;
margin: 0px;
background: black;
c
}
</style>
</head>
<body>
<script src="js/stateOver.js"></script>
<script src="js/main.js"></script>
</body>
</body>
</html>
----------------------------------------------------------------------------_
Main.js
var score =0;
var highscore =0;
var highScoreText;
var scoreText;
var MainState = {
//load the game assets before the game starts
preload: function () { /////////////////////////////preload
this.load.image('background', 'assets/city.png');
this.load.image('bird', 'assets/bird.png');
game.load.image('pipe', 'assets/pipe.png');
},
//executed after everything is loaded
create: function () {
this.background = this.game.add.sprite(0, 0, 'background');
highScoreText = this.game.add.text(600, 40, 'HS: ' + highscore, {
font: '25px Arial',
fill: 'black'
});
/////Bird///////////////////////////////////////////////////
this.bird = this.game.add.sprite(100, 200, 'bird');
game.physics.startSystem(Phaser.Physics.ARCADE);
game.physics.arcade.enable(this.bird);
this.bird.body.gravity.y = 1000;
var spaceKey = game.input.keyboard.addKey(
Phaser.Keyboard.SPACEBAR);
game.input.onDown.add(this.jump, this); //////touch screen jump
spaceKey.onDown.add(this.jump, this);
this.bird.body.collideWorldBounds=true;
this.bird.body.immovable= true;
///////////////////////////////////////////////////////Pipes
this.pipes = game.add.group();
//timer
this.timer = game.time.events.loop(1400, this.addRowOfPipes, this); /////////////timer for pipes
///////////////////////////////////////////////////////Score
this.score = -1;
this.labelScore = game.add.text(20, 20, "0",
{ font: "30px Arial", fill: "black" });
},
// this is execated multiple times per second
update: function () { //////////////////////////////////////////////////update
if (this.bird.y < 0 || this.bird.y > 480)
game.state.start("StateOver");
///Collision
game.physics.arcade.overlap(
this.bird, this.pipes, this.restartGame, null, this);
////////////////////////////////////////////////////////////////////////// Highscore counter
highScoreText.text = 'HS: ' + this.currentHighScore;
{
if (this.score > this.currentHighScore)
{
this.currentHighScore = this.score;
}
}
},
jump: function () {
//this is for so the bird wount fly once dead
if (this.bird.alive == false)
return;
///sound
///this.jumpSound.play();
// Add a vertical velocity to the bird
this.bird.body.velocity.y = -350;
// Jump Animation
var animation = game.add.tween(this.bird);
// Change the angle of the bird to -20° in 100 milliseconds
animation.to({angle: -20}, 100);
// And start the animation
animation.start();
game.add.tween(this.bird).to({angle: -20}, 100).start();
},
restartGame: function () {
// Start the 'main' state, which restarts the game
game.state.start(game.state.current);
///Hit pipe Null
game.physics.arcade.overlap(
this.bird, this.pipes, this.hitPipe, null, this);
},
addRowOfPipes: function() {
var hole = Math.floor(Math.random() * 5) + 1; ///Math.floor(Math.random() * 5) + 1;
for (var i = 0; i < 10 ; i++) ///// (var i = 0; i < 8; i++)
if (i != hole && i != hole + 1) ///// if (i != hole && i != hole + 1)
this.addOnePipe(440, i * 50 ); ///// 640 starting point of pipe 240 point of down ////this.addOnePipe(480, i * 60 + 10);
///Score for pipes
this.score += 1;
this.labelScore.text = this.score;
},
addOnePipe: function(x, y) {
var pipe = game.add.sprite(x, y, 'pipe');
this.pipes.add(pipe);
game.physics.arcade.enable(pipe);
pipe.body.velocity.x = -200;
pipe.checkWorldBounds = true;
pipe.outOfBoundsKill = true;
},
hitPipe: function() {
// If the bird has already hit a pipe, do nothing
// It means the bird is already falling off the screen
if (this.bird.alive == false)
return;
else {
game.state.start("StateOver");
}
// Set the alive property of the bird to false
this.bird.alive = false;
// Prevent new pipes from appearing
game.time.events.remove(this.timer);
// Go through all the pipes, and stop their movement
this.pipes.forEach(function(p){
p.body.velocity.x = 0;
}, this);
},
};
// Initilate the Phaser Framework
var game = new Phaser.Game(480, 640, Phaser.AUTO);
game.state.add("main", MainState);
game.state.add("stateTitle", stateTitle);
game.state.add("StateOver", StateOver);
game.state.add("characters", characters);
game.state.start("stateTitle");
-----------------------------------------------------------------------------
Game over screen stateover.js
var StateOver={
preload:function()
{
game.load.spritesheet('button', 'assets/button.png', 215, 53, 8);
game.load.image("title", "assets/title.png");
game.load.image("game", "assets/extra/gameover.png");
},
create:function()
{
this.title = game.add.tileSprite(0, game.height-640,game.width, 640, 'title');
this.title.autoScroll(-100,0);
this.btnPlayAgain=game.add.button(110,400,'button',this.playAgain,this,2,3,2);
this.btnMainMenu=game.add.button(110,300,'button',this.mainMenu,this,4,5,4);
this.btnStore=game.add.button(110,200,'button',this.Store,this,6,7,6);
this.game.add.sprite (118, 100, "game");
highScoreText = this.game.add.text(130, 150, 'HS: ' + highscore, {
font: '25px Arial',
fill: 'black'
});
},
playAgain:function()
{
game.state.start("main");
},
mainMenu:function()
{
game.state.start("stateTitle");
},
Store:function()
{
game.state.start("characters");
},
update:function()
{
highScoreText.text = 'HIGHSCORE: ' + localStorage.getItem("highscore");
{
if (this.score > localStorage.getItem("highscore"))
{
localStorage.setItem("highscore", this.score);
}
}
},
};
This is the main title screen
var stateTitle={
preload:function()
{
game.load.image("logo", "assets/extra/Logo.png");
game.load.image("title", "assets/title.png");
game.load.spritesheet('button', 'assets/button.png', 215, 53, 8);
},
create:function()
{
this.title = game.add.tileSprite(0, game.height-640,game.width, 640, 'title');
this.title.autoScroll(-100,0);
this.btnStart=game.add.button(110,400,'button',this.startGame,this,0,1,1);
this.btnStore=game.add.button(110,480,'button',this.Store,this,6,7,6);
this.logo = game.add.sprite(60, 150, 'logo');
},
startGame:function()
{
game.state.start("main");
},
Store:function()
{
game.state.start("characters");
},
update:function()
{
},
};
Html with sample
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="UTF-8-8">
<meta name="viewport" content="user-scalable=0, initial-scale=1,minimum-scale=1, maximum-scale=1, width=device-width, minimal-ui=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<script type="text/javascript" src="js/phaser.js"></script>
<script src="js/stateTitle.js"></script>
<script src="js/characters.js"></script>
<style>
body {
padding: 0px;
margin: 0px;
background: black;
c
}
</style>
</head>
<body>
<script src="js/stateOver.js"></script>
<script src="js/main.js"></script>
<script type="text/javascript">
function onDeviceready() {
admob.createBannerView({publisherId: "ca-app-pub-XXXXXXXXXXXXXXXX/BBBBBBBBBB"});
}
document.addEventListener('deviceready', onDeviceready, false);
</script>
</body>
</html>
Firstly add admob plugin then just add below lines to your html file:
<script>
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
if (AdMob)
AdMob.prepareInterstitial({
adId : 'ca-app-pub-xxx/yyy',
autoShow : false
});
if (AdMob)
AdMob.createBanner({
adId : 'ca-app-pub-xxx/yyy',
position : AdMob.AD_POSITION.BOTTOM_CENTER,
autoShow : true,
overlap : true
});
}
</script>
You can change the place of the banner; use TOP_CENTER (I am not sure about this) instead of BOTTOM_CENTER.
Ok SOOOOO many tries alone I was able to fix this by simply inserting the extra needed plugins. Internet connection etc. BOOOOOOOOOOOOOOM Fixed any questions ask.

Categories