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/
Related
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?
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've searched far and wide and I wasn't able to figure out what's wrong with my code. Apologies if I am missing something obvious.
I have a JSON object as follows:
var data={
"by_date":[
{"date":"2014-01-01", "count":10},
{"date":"2014-02-01", "count":20},
{"date":"2014-03-01", "count":30},
{"date":"2014-04-01", "count":15},
{"date":"2014-05-01", "count":20}
],
"by_location": {
"name":"World","children":[
{
"name":"United States", "children":[{"name":"New York", "children":[{"name":"Albany","count":5}, {"name":"NYC","count":5}]}]
},
{
"name":"Canda", "children":[
{
"name":"Alberta", "children":[{"name":"Edmonton","count":5},{"name":"Calgary","count":5}]
},
{
"name":"British Columbia", "children":[{"name":"Victoria","count":2},{"name":"Vancouver","count":8}]
}
]
},
{
"name":"China", "children":[{"name":"Beijing","count":30}]
},
{
"name":"India", "children":[{"name":"Bangalore","count":15}]
},
{
"name":"Germany", "children":[{"name":"Frankfurt","count":20}]
}
]
}
};
I want to display a line chart using data from data.by_date and a zoomable circlepack from data.by_location on the same HTML page. I have two Javascript functions by_date, which creates a line chart, and by_location, which creates a circlepack, and they both have the exact same code as Mike Bostock's line chart and zoomable circlepack examples and I call them as follows:
by_date(data.by_date);
by_location(data.by_location); // Creates circlepack, but zoom doesn't work.
The problem is that while both the line chart and the circlepack are created and displayed on the page, the zoom functionality doesn't work on the circlepack. I get the following error:
Uncaught TypeError: Cannot read property 'parent' of undefined
However, if I don't call by_date and only call by_location, it works perfectly fine.
//by_date(data.by_date);
by_location(data.by_location); // Zoom works great now!
Since by_date uses only data.by_date, and doesn't even touch data.by_location, why would commenting it out somehow make by_location work okay?
Here are fiddles demonstrating the issue:
Both line and circlepack (circlepack doesn't zoom): http://jsfiddle.net/xk5aqf8t/6/
Line chart function by_date commented (zoom works fine): http://jsfiddle.net/38sayeqa/
Note that the only difference between the two fiddles is the commented call to by_date.
Any help is greatly appreciated. Thanks in advance!
The problem in your case is that in your zoom transition you're selecting all text elements in the document, including the line chart where elements' bound data doesn't have any parent property (hence the error message).
The fix is easy. Just constrain your transition selection to the current chart. In your case you already have a selection of text elements, you can simply reuse it as demonstrated below:
// Let's keep our initial selection in the text variable:
var text = svg.selectAll('text').data(nodes);
text.enter()... // the entering selection is a subselection, so we keep it separate
// Create a new transition on the existing selection of text nodes
var transition = text.transition().duration(...); // the transition will reuse `text` selection
transition.filter(...); // don't subselect anything here
Here's a demo.
I am trying to use RGraph library to manipulate a vertical progress bar, but I'm stuck because after creating the progress bar I can't manipulate its properties, here's the code I have been using:
window.onload = function ()
{
// Create the object. The arguments are: The canvas ID, the indicated value and the maximum value.
var myProgress = new RGraph.VProgress('myProgress', 60, 100)
// Configure the chart to look as you want.
.Set('chart.colors', ['blue'])
.Set('chart.tickmarks',['true'])
.Set('chart.tickmarks.color',['white'])
.Set('chart.title',"Nivel")
// Now call the .Draw() method to draw the chart.
.Draw();
}
and after that I try to read the value property using a click on a button,but it says undefined:
function myFunction()
{
var valor= myProgress.value;
alert(valor);
}
How can I access the properties of an object created in another function? My idea is to change the level of the progress bar according to a control put in the webpage.
Thanks in advance for any help supplied.
myProgress is scoped within your onload handler, thus it can't be seen by other functions out of that scope.
var myProgress;
window.onload = function() {
myProgress = new RGraph.VProgress('myProgress', 60, 100)
// ...
};
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);
}