Highcharts Highmaps prevent initial zoom effect - animation

I built a map with Highmaps that initially zooms in to a lat lon position: see fiddle
Here is my code:
parsed: function() {
var chart = this.chart,
center = chart.fromLatLonToPoint({
lat: 50,
lon: 10
});
setTimeout(function() {
chart.mapZoom(.2, center.x, center.y);
When the map is loaded and when the time slider is started the map zooms in. How can I prevent this animation?

You can disable animation on the chart level and restore it after initial zoom:
chart: {
animation: false,
...
}
chart.update({
chart: {
animation: true
}
});
Live demo: https://jsfiddle.net/BlackLabel/xarg940y/
API Reference: https://api.highcharts.com/highmaps/chart.animation

Related

Drawing target line (plotLine) on Kendo Angular Pie Chart

Is it possible to draw a target line on pie chart?
For example, goal is 90% but installed is 70% and not-installed is 30%. I need to show the goal as dotted line as shown in the image below.
You can use the render event of the grid to draw the dotted line on the chart. I would use the visual property of the series to get the center point and radius of the pie, then in the render, draw a path from the pie center at the correct angle.
WORKING DEMO
var center;
var radius;
$("#chart").kendoChart({
theme: "Bootstrap",
legend: {visible: true,position: "bottom"},
seriesDefaults: { labels: {visible: false, }},
series: [{
type: "pie",
data: [{
category: "Installed",value: 45,color: "#52B84D"
}, {
category: "Not Installed",value: 25,color: "#E64F49"
}],
visual: function(e) {
//use this function to get the center and radius
//for use in the render function
center = e.center;
radius = e.radius;
// return the default visual element
return e.createVisual();
},
}],
render: function(e){
var draw = kendo.drawing;
var geom = kendo.geometry;
var chart = e.sender;
//angle is 90% of 270 because 0 is horizontal
var cornerRad = (0.9 * 270) * Math.PI / 180;
var nx = Math.cos(cornerRad)*radius + center.x;
var ny = Math.sin(cornerRad)*radius + center.y;
// The center and radius are populated by now.
var path = new draw.Path({
stroke: {
color: "#000",
width: 2,
dashType: "dash"
}
});
path.moveTo(center).lineTo(nx, ny, 0).close();
// Draw it on the Chart drawing surface
chart.surface.draw(path);
}
});

Set events on canvas pushpin of Bing Map

I am facing one issue while setting event on Pushpin which was created by canvas. To set the environment please goto Bing Map - Pushpin Event Example. And copy below code in Javascript tab and run the example.
var map = new Microsoft.Maps.Map(document.getElementById('myMap'), {});
var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), {
icon: createRedArrow(110),
anchor: new Microsoft.Maps.Point(12, 12)
});
map.entities.push(pushpin);
function createRedArrow(heading) {
var c = document.createElement('canvas');
c.width = 24;
c.height = 24;
var ctx = c.getContext('2d');
// Offset the canvas such that we will rotate around the center of our arrow
ctx.translate(c.width * 0.5, c.height * 0.5);
// Rotate the canvas by the desired heading
ctx.rotate(heading * Math.PI / 180);
//Return the canvas offset back to it's original position
ctx.translate(-c.width * 0.5, -c.height * 0.5);
ctx.fillStyle = '#f00';
// Draw a path in the shape of an arrow.
ctx.beginPath();
ctx.moveTo(12, 0);
ctx.lineTo(5, 20);
ctx.lineTo(12, 15);
ctx.lineTo(19, 20);
ctx.lineTo(12, 0);
ctx.closePath();
ctx.fill();
ctx.stroke();
// Generate the base64 image URL from the canvas.
return c.toDataURL();
}
// Binding the events
Microsoft.Maps.Events.addHandler(pushpin, 'click', function () { highlight('pushpinClick'); });
Microsoft.Maps.Events.addHandler(pushpin, 'dblclick', function () { highlight('pushpinDblclick'); });
Microsoft.Maps.Events.addHandler(pushpin, 'mousedown', function () { highlight('pushpinMousedown'); });
Microsoft.Maps.Events.addHandler(pushpin, 'mouseout', function () { highlight('pushpinMouseout'); });
Microsoft.Maps.Events.addHandler(pushpin, 'mouseover', function () { highlight('pushpinMouseover'); });
Microsoft.Maps.Events.addHandler(pushpin, 'mouseup', function () { highlight('pushpinMouseup'); });
// Setting up the printout panel
document.getElementById('printoutPanel').innerHTML =
'<div id="pushpinClick">click</div><div id="pushpinDblclick">dblclick</div><div id="pushpinMousedown">mousedown</div><div id="pushpinMouseout">mouseout</div><div id="pushpinMouseover">mouseover</div><div id="pushpinMouseup">mouseup</div>';
function highlight(id) {
document.getElementById(id).style.background = 'LightGreen';
setTimeout(function () { document.getElementById(id).style.background = 'white'; }, 1000);
}
You can notice that all pushpin events are working on canvas's width/height (24/24) area as shown in below image
And as per my requirement events should only work on drawn part of canvas and also canvas w/h will be like 100. So, how do I achieve that?
Also, if two or more pushpins are nearer (see below image) and if both canvas are overlap to each other then how we can identify both pushpins are different for pushpin event?
Here, I have provided my requirement with Bing Map's exisiting example. But here is actual pushpin secnario.
Unfortunately this is a limitation in how pushpins are rendered in Bing Maps. There is an option to modify the click area to be round rather than square which will help a bit here. See the roundClickableArea pushpin option: https://learn.microsoft.com/en-us/bingmaps/v8-web-control/map-control-api/pushpinoptions-object

Add 3d(2d) object on map mapbox Gl using three.js or p5.js

As I understand I have to use one canvas for both mapbox Gl and p5.
But how to do this? And what if I have p5 animation will it overwrite the canvas with map?
Any example or hint? Thanks.
My code, but nothing serious
mapboxgl.accessToken = 'pk.***';
var mapGL = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
center: [-120.36603539685188, 50.68667605749022],
zoom: 11.6
});
var mainCanvas;
function setup() {
mainCanvas = createCanvas(720, 400, WEBGL);
}
function draw() {
background(102);
rotate(frameCount / 100.0);
rect(30, 20, 25, 25);
}
Different drawing libraries don't usually play nice with each other on the same canvas. You could try something like overlaying the P5.js canvas on top of the mapbox canvas.
Better yet, use a map library that's already compatible with P5.js, like Mappa or p5.tiledmap. That allows you to draw a map inside P5.js, which makes drawing on top of it much easier.
This is a very old question, but for whoever revisits this question looking for an option... nowadays this could be easily done with the latest version of threebox and a few lines of code. The result looks like this:
<script>
mapboxgl.accessToken = 'pk.eyJ1IjoianNjYXN0cm8iLCJhIjoiY2s2YzB6Z25kMDVhejNrbXNpcmtjNGtpbiJ9.28ynPf1Y5Q8EyB_moOHylw';
var origin = [2.294514, 48.857475];
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/satellite-v9',
center: origin,
zoom: 18,
pitch: 60,
bearing: 0
});
map.on('style.load', function () {
map
.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function (map, mbxContext) {
window.tb = new Threebox(
map,
mbxContext,
{
defaultLights: true,
}
);
// import tower from an external glb file, downscaling it to real size
// IMPORTANT: .glb is not a standard MIME TYPE, you'll have to add it to your web server config,
// otherwise you'll receive a 404 error
var options = {
obj: '/3D/eiffel/eiffel.glb',
type: 'gltf',
scale: 0.01029,
units: 'meters',
rotation: { x: 0, y: 0, z: 0 }, //default rotation
adjustment: { x: -0.5, y: -0.5, z: 0 } // place the center in one corner for perfect positioning and rotation
}
tb.loadObj(options, function (model) {
model.setCoords(origin); //position
model.setRotation({ x: 0, y: 0, z: 45.7 }); //rotate it
tb.add(model);
})
},
render: function (gl, matrix) {
tb.update();
}
});
})
</script>

How to rotate left or right in Cesium Map based on view bounds

Want to mimic the left-right arrow keys in CesiumJS app similar to Google Earth navigation. Press right or left arrow keys should rotate the globe ~5% of the view bounds to the right or left, respectively. If zoomed out then it rotates a large extent and zoomed in rotates a smaller extent.
Already looked at the documentation for Viewer, Camera, Scene, etc. but it's not obvious how to do something that should be simple.
Able to rotate a fixed amount right or left but want to rotate amount based on the width in the view extent. How do you get the max extent top, left, right, bottom for the view in cesium?
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationHelpButton: false, animation: false, timeline: false
});
var camera = viewer.camera;
document.addEventListener('keydown', function(e) {
setKey(e);
}, false);
function setKey(event) {
if (event.keyCode == 39) { // right arrow
camera.rotateRight(Cesium.Math.toRadians(10.0));
} else if (event.keyCode == 37) { // left arrow
camera.rotateLeft(Cesium.Math.toRadians(10.0));
}
}
To test, visit SandCastle app and paste in the javascript snippet above. To activate the keyboard bindings, click full screen mode and the arrow keys will work.
Alternatively, the camera can be used to access positionCartographic, but this is only the cartographic position of the camera, not the view bounds.
var positionCartographic = camera.positionCartographic;
var height = positionCartographic.height;
var lat = positionCartographic.latitude;
var lon = positionCartographic.longitude + Cesium.Math.toRadians(10.0);
camera.flyTo({
destination: Cesium.Cartesian3.fromRadians(lon, lat, height),
duration: 1.0
});
Here a fixed angle is added to the center view point, but the angle needs to be a percentage of the difference between max and min longitude values in the view extent; e.g. angle = (maxLon - minLon) / 20
You're in luck. The much-requested feature for Camera.computeViewRectangle was just added in Cesium 1.19, released about a week ago as of this writing. Here it is in action.
Note that browsers are generally not comfortable with embedded documents receiving keypress events, so this doesn't work too well as a Stack Snippet. You have to click the magnifying-glass geocoder search box (to get a text entry field), that can receive arrow key events, and then this demo will work. Outside of Stack Overflow, you may find it easier to receive keypresses.
var viewer = new Cesium.Viewer('cesiumContainer', {
navigationHelpButton: false, animation: false, timeline: false
});
var camera = viewer.camera;
document.addEventListener('keydown', function(e) {
setKey(e);
}, false);
function setKey(event) {
var horizontalDegrees = 10.0;
var verticalDegrees = 10.0;
var viewRect = camera.computeViewRectangle();
if (Cesium.defined(viewRect)) {
horizontalDegrees *= Cesium.Math.toDegrees(viewRect.east - viewRect.west) / 360.0;
verticalDegrees *= Cesium.Math.toDegrees(viewRect.north - viewRect.south) / 180.0;
}
if (event.keyCode === 39) { // right arrow
camera.rotateRight(Cesium.Math.toRadians(horizontalDegrees));
} else if (event.keyCode === 37) { // left arrow
camera.rotateLeft(Cesium.Math.toRadians(horizontalDegrees));
} else if (event.keyCode === 38) { // up arrow
camera.rotateUp(Cesium.Math.toRadians(verticalDegrees));
} else if (event.keyCode === 40) { // down arrow
camera.rotateDown(Cesium.Math.toRadians(verticalDegrees));
}
}
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
font-family: sans-serif;
}
<link href="http://cesiumjs.org/releases/1.19/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"/>
<script src="http://cesiumjs.org/releases/1.19/Build/Cesium/Cesium.js">
</script>
<div id="cesiumContainer"></div>

How to animate a HighChart chart that is created dynamically?

I would like to draw each point immediately when it's added. But it waits and draws all the points at the end. Before trying to use the built in API I used a queue to add those tasks, but isn't the API support that? See the fiddle:
http://jsfiddle.net/7dx7u34v/
$(function () {
$('#container').highcharts({
chart: {
animation: {
duration: 10000
}
},
});
$('#update').click(function () {
var chart = $('#container').highcharts();
chart.addSeries({});
for(var i = 0; i < 500 ; i ++){
var chart = $('#container').highcharts();
chart.series[0].addPoint([i,50 * (i % 3)])
}
});
});
Animation is by default true if you not explicitly define its options .In your case your animation duration is higher than the plot time while adding point. If you reduce animation time ,it will be shown
animation: {
duration: 1000
}
Updated fiddle here

Resources