I'm trying to create custom zoom in/out buttons and I've got it working except for the most important part, the zooming..
I've created a map chart like this:
$scope.chart = new Highcharts.Map(config);
Then I have two functions which run whenever you click on zoom in or out:
highcharts.zoomIn = function() {
$scope.chart.mapZoom(0.5);
};
highcharts.zoomOut = function() {
$scope.chart.mapZoom(2);
};
Setting the mapZoom of the chart doesn't give me an error nor does it do anything. I tried calling $scope.chart.redraw() afterwards but it didn't help either. Also saw that it already calls the redraw function in the source code of the mapZoom function.
I can't find any information on how to do this so what exactly am I doing wrong here?
Related
So I have this chart built out and it works except it keeps throwing the error Cannot read property 'chart' of undefined. I am reloading the chart on window resize so that the html labels reload in correct positions.
It's a double donut chart and shows/hides content based on the selected slice.
Any help would be greatly appreciated.
First of all, you define var chart variable in createChart function, so it always will be undefined - use only one definition (the one on top), later just assign chart to that variable. Anyway, I see two solutions:
use setTimeout() in resize event, to render chart with a delay. Not a reliable solution, because user can play around with width of the browser and something may be broken again
wrap initReflow method to check if chart exists, like this:
(function(H, HA) {
H.wrap(H.Chart.prototype.initReflow = function () {
var chart = this,
reflow = function (e) {
if(chart && chart.options) {
chart.reflow(e);
}
};
HA.addEvent(window, 'resize', reflow);
HA.addEvent(chart, 'destroy', function () {
HA.removeEvent(window, 'resize', reflow);
});
});
})(Highcharts, HighchartsAdapter)
Working demo: https://jsfiddle.net/dpsn9gx8/7/
Edit:
Since Highcharts 4.1.10 Highcharts adapter is built-in, so remove it and use Highcharts: https://jsfiddle.net/dpsn9gx8/11/
I am building the functionality that allows mapbox markers to be edited from within a CMS. The functionality should open up and populate a form when a map marker is clicked, and then allow the map marker to be dragged. When the form is saved, the content is submitted via ajax and then the map is reloaded with the featureLayer.loadURL("my_geojson_endpoint").
I have added comments throughout my code below to outline how I am getting to the error.
N.B. I define a property db_id in the geojson to identify each point because when you apply a filter, _leaflet_id changes. I also have jquery included in the code.
Code:
// loop through each marker, adding a click handler
$.each(points._layers, function (item) {
var point = points._layers[item];
attachClickHandler(point);
});
function attachClickHandler(point) {
// open the edit state for the marker on click
$(point._icon).on("click", function () {
openEditState(point);
})
}
function openEditState (point) {
disableEditOthers(point);
displayContent(point);
point.dragging.enable(); // this line causes the error
$(point._icon).off("click");
}
function disableEditOthers (point) {
// hide the other markers from the map (using db_id as mentioned above)
points.setFilter(function (f) {
return f.db_id === point.feature.db_id;
})
// this functions as a callback to display the popup
// since applying the filter on click, does not show the popup
setTimeout(function () {
for (key in points._layers) {
points._layers[key].openPopup();
}
}, 0)
}
In the map creation step I have been able to call this dragging.enable() method on each of the markers and provide "draggability" to all of them, however this is undesirable from a usability point of view. I want the user to clear swap in and out of an edit state.
I discovered this issue on github, solved by the solution to this. However after swapping my mapbox.js version out to the standalone and including the latest version of leaflet (0.7.3) the same error still occured.
Am I calling the function on the wrong property of the object? dumping out the "point" variable just before the line which errors does not show that the draggable property has the enable() function defined.
Any help is much appreciated.
Ok so as a slight workaround, but still not solving the original error.
$.each(points._layers, function (item) {
points._layers[item].dragging.enable()
})
Because I have filtered out the other points, enabling dragging on all points is working around the issue.
If you can provide a fix to my original fix (avoiding the loop) I am happy to accept it.
I think this means I'm missing something basic about the working of nested functions in javascript, but I'm failing to add or remove a layer from a leaflet map using a click function. Specifically, I have a leaflet map with numerous vector layers defined. One of these layers is added to the map on page load, and then subsequent layers are supposed to load on a click event in a layer selector.
Here's the function that handles the click, then updates the sidebar legend, updates classes in the layer selector, and is supposed to update the visible layer:
// ADD THE LAYER CONTROL FUNCTION
$('.layer').click(function() {
var oldLayer = $('.active').attr('id');
var newLayer = $(this).attr('id');
console.log(oldLayer + ' --> ' + newLayer);
$('#infobits').html('<h2>' + this.text + '</h2><hr>' + legendFormatter(
this.id));
map.removeLayer(oldLayer);
$('.layer').removeClass('active');
$(this).addClass('active');
map.addLayer(newLayer);
});
Every time I click on a new layer I get Uncaught TypeError: undefined is not a function, no matter where I put the function (I even had it inside the .getJSON() call for a bit). What's perplexing is that is I go to the JS console in my browser and type verbatim what the function is producing on line 49 of the above script (map.removeLayer(Percent_TC_bg)), the map removes the layer in question.
What can I do to get my map adding and removing layers without error?
I suppose TypeError is thrown inside addLayer or removeLayer. Map#addLayer and #removeLayer accepts ILayer object as parameter, but oldLayer and newLayer is obviously String, which came directly from HTML element's ID property.
So changing oldLayer and newLayer to appreciate ILayer object will fix the problem, I guess.
Edit: Igor beat me to it.
Mics is right - the HTML element's ID is a string, and doesn't reference the layer. You could do something like this after you define your layers to work around this issue:
var myLayers = {
"Percent_TC_bg": Percent_TC_bg,
"Percent_TC": Percent_TC
};
And then add the handler like so
$('.layer').click(function() {
var oldLayer = myLayers[$('.active').attr('id')];
var newLayer = myLayers[$(this).attr('id')];
// ...
});
I seem to be having some trouble with reinitializing a Leaflet map object. I am running an init() function that starts by initializing a map, adding a tilelayer and layer with polygons, and then adding sublayers which color the polygons according to a ST_Intersects query. The issue is that this function is tied to an AJAX call that is caused by a click event but does not update the data according to the new parameters sent to the map. I don't think I am explaining this very well, so here is a bit of my code:
success: function(data) {
init(data);
}
function init(data){
// initiate leaflet map
alert("start");
var map = L.map('cartodb-map').setView([40.750028, -73.926768], 11);
alert("map made");
//create sublayers, etc
}
What happens is that the first time init is run, both 'start' and 'map made' alerts work, and the map is made according to the data. Any further calls to init simply alerts with "start" and "map made" is never alerted so I believe the problem is with reinitializing the leaflet map. What should I do to fix this?
Not sure the problem without seeing more of your code, but you could try calling map.remove(); the second time around. So:
if (map) {
map.remove();
// add in new map initialization here
} else {
var map = ...
}
In my code I'm initializing the chart like this...
<script type="text/javascript">
var chart = null,
defaultOptions = {
chart: etc etc
};
function drawDefaultChart() {
chart = new Highcharts.Chart(defaultOptions);
}
$(function() {
$(document).ready(function() {
drawDefaultChart();
});
});
</script>
then in the body I have
Reset
but when you click the link, all it does is redraw the graph with the settings from the previous state... I'm not quite sure what is going on. If I add chart.destroy(); the chart doesn't work at all...
function drawDefaultChart() {
chart.destroy(); //this makes the chart not work at all
chart = new Highcharts.Chart(defaultOptions);
}
You can clearly see that I 'm pasing default options to the chart that is suppose to get redrawn.... I don't understand why it uses the old filter settings, i'm about to jump off a bridge, can somebody PLEASE HELP?
my live example is here http://goo.gl/sGu0M
//////// UPDATE
I was able to do it with a lot of blood, sweat, and tears. I ended up putting the data into a php variable on another page (to save real estate), and then calling it using php variables, and then I just call it everytime someone clicks a link. I figured out that in order to redraw the graph, you have to reload ALL the data in each time. The PHP makes this easier in terms of amount of data on the screen.
this was the link that eventually helped me figure it out. http://jsfiddle.net/dane/YUa3R/34/
Always it's recommend to refer API documentation.
use following snippet to destroy the chart $('#container').highcharts().destroy();
Click here for a working solution.
First off, I know NOTHING about highcharts, but it would seem you need: (from your actual page)
function drawDefaultChart() {
$("#container").empty();
chart = new Highcharts.Chart(defaultOptions);
}
to be
function drawDefaultChart() {
$("#container").empty().highcharts(defaultOptions);
}
OR perhaps:
function drawDefaultChart() {
$("#container").highcharts(defaultOptions);
}