How to keep previous data in Leaflet Realtime - node.js

I am trying to use Leaflet realtime plugin (https://github.com/perliedman/leaflet-realtime), they mentioned in the documentation that we can keep previous updates by adding start:false in the constructor.
var map = L.map('map'),
realtime = L.realtime({
url: 'https://wanderdrone.appspot.com/',
crossOrigin: true,
type: 'json'
}, {
interval: 3 * 1000, start:false
}).addTo(map);
Anyone have better idea on how to do that ?
plnkr has a good demo:
http://plnkr.co/edit/NmtcUa?p=preview

If you set start: false, automatic updates will be disabled. This means you will have to call the layer's update method yourself, providing any GeoJSON data you want to add or update; you can also remove added features with the remove method. These methods can be used if you want to use something other than server polling.

You can use the following code that I copied from plnkr while changed a little bit, because L.realtime inherit L.geoJson. And L.geoJson have 'layeradd'.
realtime.on('layeradd', function(e) {
var coordPart = function(v, dirs) {
return dirs.charAt(v >= 0 ? 0 : 1) +
(Math.round(Math.abs(v) * 100) / 100).toString();
},
popupContent = function(fId) {
var feature = e.features[fId],
c = feature.geometry.coordinates;
return 'Wander drone at ' +
coordPart(c[1], 'NS') + ', ' + coordPart(c[0], 'EW');
},
bindFeaturePopup = function(fId) {
realtime.getLayer(fId).bindPopup(popupContent(fId));
},
updateFeaturePopup = function(fId) {
realtime.getLayer(fId).getPopup().setContent(popupContent(fId));
};
map.fitBounds(realtime.getBounds(), {maxZoom: 3});
Object.keys(e.enter).forEach(bindFeaturePopup);
Object.keys(e.update).forEach(updateFeaturePopup);
});

Related

How to enable and disable perf_hook based on Flag

We have large code with lot of function called in series . For performance improvement we want to measure the time between to specific point.
Step by step we want to make improvement. I was thinking of making user of perf_hook
Our best use case will be using as below , as per the lib
const { PerformanceObserver, performance } = require('perf_hooks');
const obs = new PerformanceObserver((items) => {
console.log(items.getEntries()[0].duration);
performance.clearMarks();
});
obs.observe({ type: 'measure' });
performance.measure('Start to Now');
performance.mark('A');
doSomeLongRunningProcess(() => {
performance.measure('A to Now', 'A');
performance.mark('B');
performance.measure('A to B', 'A', 'B');
});
I looked and searched in lib as well as web , did not find any env variable to enable or disable the perf_hook, so enable and disable the code in PROD stage.
playing around the code .
Just putting the declaration based on condition
let obs = null;
//ACTIVATE or DEACTIVATE
if( true || false) {
obs = new PerformanceObserver((items) => {
console.log(items.getEntries()[0].duration);
performance.clearMarks();
});
obs.observe({ type: 'measure' });
}

adding an assign function as property to an object in NodeJs

for the sake of fun and exploring nodeJS I made an object
var f15c = {
fuel : 10000,
IRST: true,
AESA: true,
speed: 2500,
Ammo:
{
AMRAAM: 6,
Python5: 2,
Delilah: 3,
},
tailnumber : the question begins here.
}
The problem came when I wanted to add tailnumber that is not the same for every plane but should be assigned to the plane.
what is the methode?
var f15c = {
...
tailnumber = function (tn){"whats should i add here?"}
}
or
var f15c = {
...
tailnumber: ?? what should i place here?
SetTailNumber = function(tn)
{
tailnumber=tn;
}
}
or must I have the entire F15c as a function?
var f15c = function(tn) {
...
tailnumber = tn;
but then i cannot set the entire variables complex.
or perhaps I'm doing it wrong and should refer the variable as an individual F15 and use a different function to create it?
but then how do I make that field in a way it is unassigned and waiting to be assigned (and then saves the assigned number)?
would appreciate some heads up
The secret is to use this to refer to a property of the own object
var f15c = {
...
tailnumber: null,
setTailNumber : function(tn)
{
this.tailnumber=tn;
}
}
Then:
f15c.setTailNumber(1234);
console.log(f15c.tailnumber);
Do you mean you want to set a value to a property?
var f15c = {
_tailnumber: 0,
set tailnumber(newtailnumber) {
this._tailnumber = newtailnumber;
},
get tailnumber() {
return this._tailnumber
}
};
f15c.tailnumber = "304";
console.log(f15c.tailnumber);
console.log(f15c);

Is it possible to morph SVG's paths using Velocity.js?

Is it possible to morph SVG's paths using Velocity.js?
FROM
"M292,129c55.2,0,193,125.8,193,181S365.7,506,310.5,506S136,355.2,136,300S236.8,129,292,129z"
TO
"M230,38c55.2,0,348,57.8,348,113S391.2,569,336,569S55,456.2,55,401S174.8,38,230,38z"
var path = document.querySelectorAll('svg path');
Velocity(path[0], {
tween: 1000
}, {
duration: 6000,
easing: 'easeOutBounce',
progress: function (el, c, r, s, t) {
el[0].setAttribute('d', ??????);
}
});
EDIT: Please note I am the author of the code that enabled this in 2016, so it is the official supported way to do it!
Almost, should be something like this:
var path = document.querySelectorAll('svg path'),
from = "M292,129c55.2,0,193,125.8,193,181S365.7,506,310.5,506S136,355.2,136,300S236.8,129,292,129z",
to = "M230,38c55.2,0,348,57.8,348,113S391.2,569,336,569S55,456.2,55,401S174.8,38,230,38z";
Velocity(path[0], {
tween: [to, from]
}, {
duration: 6000,
easing: 'easeOutBounce',
progress: function(elements, complete, remaining, start, tweenValue) {
elements[0].setAttribute('d', tweenValue);
}
});
Edit: Velocity has some string animation support built in, see Rycochets answer below.
If not you could try doing that yourself, by breaking down the path string into an array.
One way could be to use the path data polyfill (as Chrome has deprecated that feature to give easy access to the array points) at polyfill. Then you could loop similar to below through the path points and interpolate.
You could also try using some regex to split and then build back up, a quick example could be something like the following. It's probably not complete (I haven't really tested the regex, and you may get varying number of elements if there are some characters that I haven't thought of).
$velocity=$("#mypath");
var fromPath = "M292,129c55.2,0,193,125.8,193,181S365.7,506,310.5,506S136,355.2,136,300S236.8,129,292,129z";
var toPath = "M230,38c55.2,0,348,57.8,348,113S391.2,569,336,569S55,456.2,55,401S174.8,38,230,38z";
var re = /(([+-]?[0-9\.]+)|[a-z]|\s+)([eE][-+]?[0-9]+)?/gi
var fromMatch = fromPath.match(re)
var toMatch = toPath.match(re)
$velocity.velocity(
{ opacity: 0.5, tween: [0,1] },
{ progress: function( el, complete, remaining, start, tweenValue) {
var interpPath = '';
for( c=0; c<fromMatch.length; c++) {
if( !isNaN( fromMatch[c]) ) {
interpPath += ( toMatch[c] - fromMatch[c] ) * tweenValue + +fromMatch[c]
} else {
interpPath += toMatch[c]
}
}
el[0].setAttribute('d', interpPath)
} }
)
jsfiddle

Set window width in jsDom?

Should be a simple question. How do I set the width in a jsDom object?
jsdom.env({
url:'http://testdatalocation',
scripts: ['http://code.jquery.com/jquery.js'],
done: function(errors, tstWindow) {
console.log(tstWindow.innerWidth);
};
}
});
I can't figure out how to get the "innerWidth" to be anything but 1024
The resizeTo and resizeBy methods are not implemented. You can see that by searching through the code base of jsdom:
$ grep -P 'resize(To|By)' `find . -type f`
./lib/jsdom/browser/index.js: resizeBy: NOT_IMPLEMENTED(null, 'window.resizeBy'),
./lib/jsdom/browser/index.js: resizeTo: NOT_IMPLEMENTED(null, 'window.resizeTo'),
If you just want to set the window size once and for all at initialization time, you could just set the innerWidth value to whatever you want. In a real browser, this is not the right way to do it, but in jsdom it would work.
However, if you have code that depends on resizeTo being present, you can add your own polyfill to the constructor that builds windows:
var jsdom = require("jsdom");
var document = jsdom.env({
html: "<html></html>",
done: function (error, w) {
console.log(w.innerWidth, w.innerHeight);
w.constructor.prototype.resizeTo = function (width, height) {
this.innerWidth = this.outerWidth = width;
this.innerHeight = this.outerHeight = height;
};
w.resizeTo(100, 200);
console.log(w.innerWidth, w.innerHeight);
}
});
This displays:
1024 768
100 200
The code above is for illustration purposes. I've not thought about all the ins and outs of writing a polyfill for resizeTo. resizeBy would be handled similarly but would add deltas to the size of the window.
There isn't currently a formal option or API for doing so.
The values of innerWidth and similar properties are simply set to literal values:
DOMWindow.prototype = createFrom(dom || null, {
// ...
name: 'nodejs',
innerWidth: 1024,
innerHeight: 768,
outerWidth: 1024,
outerHeight: 768,
// ...
});
Beyond test cases and documentation, outerWidth isn't referenced elsewhere else in jsdom, so you could probably assign a new value within the created event, updating outerWidth as well.
The primary use-case for created is to modify the window object (e.g. add new functions on built-in prototypes) before any scripts execute.
created: function (errors, tstWindow) {
tstWindow.outerWidth = tstWindow.innerWidth = 1440;
},
done: function(errors, tstWindow) {
console.log(tstWindow.innerWidth);
}

How to efficiently store/retrieve data to/from chrome.storage.sync?

So, I'm writing an extension to allow people to fine and save colors from images found on the web. It's going well but now I'm trying to conceptualize how I'll actually store them, and list stored items.
As far as I can tell, chrome.storage.sync() only allows for objects. Which means I'd have to do something like this:
{colors: [{colorName: 'white', colorHex: '#ffffff'}, {colorName: 'black', colorHex: '#000000'}]}
Which seems wildly inefficient, since every time I want to add or subtract a color from the favorite list, I will need to get the entire array, change the one item I want, and then store the array back. Not to mention scanning an array for a color to see if it exists or not could be very intensive on a large array.
Ultimately, I'd like to be able to do something along the lines of
colors['#fff'].name = white;
However, that doesn't seem possible.
I'd love to hear some other ideas as to what the best way to accomplish this might be.
The beauty of Javascript is that everything is loosely considered an object. Functions, arrays, and even variables can be accessed as objects.
You could create an array like this,
var colors {}
colors["#FFF"] = "white";
colors["#000"] = "black";
Or perhaps use an array of empty functions,
function color(name, hex /* ... other properties */ ) { }
var colors {
color1: color("white", "#FFF");
color2: color("black", "#000");
}
Then these colors can be accessed by
color1.name
or
color1.hex
Although, because you should use a specific 'key' value for each object in storage, perhaps that is a better way to go.
For instance,
function save_color() {
var white = "#FFF";
//key value callback
chrome.storage.sync.set({"white": white}, function() {
console.log("The value stored was: " + white);
});
}
Or, for multiple colors
function save_colors() {
var white = "#FFF";
var black = "#000";
chrome.storage.sync.set([{"white": white}, {"black": black}], function() {
console.log("The values stored are: " + white + " and " + black);
});
}
I think that may work, i haven't tried storing multiple objects using one api call before, but you should get the point. A good way to implement this may be to have an empty array that gets added to every time the user finds a color they would like to add, then periodically the extension can push the data to sync.
Once you have done a ton of testing and your sync storage is cluttered, keep track of the keys you used during development and remember to run a batch data removal. It would look something like this:
function clear_data() {
var keys = { "white", "black" };
chrome.storage.sync.remove(keys, function() {
for(var i = 0; i < keys.length; i++)
console.log("Removed Data for Key: " + key[i]);
});
}
By the way, to retrieve the value stored in sync,
function load_color() {
var color = "white";
//key callback
chrome.storage.sync.get(color, function(val) {
console.log("The value returned was: " + val);
});
}
I was unsure about this as well, so I made a small example.
manifest.json:
{
"manifest_version": 2,
"name": "Test",
"description": "Test.",
"version": "1.0",
"permissions": [
"storage"
],
"content_scripts": [
{
"matches": ["https://www.google.com/*"],
"js": ["content-script.js"]
}
]
}
content-script.js:
console.log("content script loaded")
function modifyObject() {
chrome.storage.sync.get(null, function(storageData3) {
storageData3.object.property2 = false;
chrome.storage.sync.set(storageData3, function() {
chrome.storage.sync.get(null, function(storageData4) {
console.log("after setting *only* object: " + JSON.stringify(storageData4));
});
});
});
}
// Dumb attempt at setting only property2 of "object"; will add a new top level object "property2".
function attemptToModifyProperty2() {
var toSave = { "property2": false };
chrome.storage.sync.set(toSave, function() {
chrome.storage.sync.get(null, function(storageData2) {
console.log("after attemping to set *only* property2: " + JSON.stringify(storageData2));
modifyObject();
});
});
}
function addArray() {
var toSave = { "array": [1, 2, 3] };
chrome.storage.sync.set(toSave, function() {
chrome.storage.sync.get(null, function(storageData1) {
console.log("after setting *only* array: " + JSON.stringify(storageData1));
attemptToModifyProperty2();
});
});
}
function addObject() {
var toSave = { "object": { "property1": true, "property2": true } };
chrome.storage.sync.set(toSave, function() {
chrome.storage.sync.get(null, function(storageData) {
console.log("after setting *only* object: " + JSON.stringify(storageData));
addArray();
});
});
}
chrome.storage.sync.clear();
addObject();
If you go to google.com (and log in, or change the matches in manifest.json to http), and then open the console, you'll see this output:
content script loaded
content-script.js:42 after setting *only* object: {"object":{"property1":true,"property2":true}}
content-script.js:31 after setting *only* array: {"array":[1,2,3],"object":{"property1":true,"property2":true}}
content-script.js:20 after attemping to set *only* property2: {"array":[1,2,3],"object":{"property1":true,"property2":true},"property2":false}
content-script.js:9 after setting *only* object: {"array":[1,2,3],"object":{"property1":true,"property2":false},"property2":false}
My conclusions from this were that it's only possible to set top-level objects. Even if you want to change only one property that is nested deeply within a top-level object, you will have to pass the entire object to set().

Resources