Google Chart Tools - overlapping labels - javascript

I'm using Google Chart Tools to display a simple line graph for unknown reason the labels overlap no matter how I set the "legend" parameters. In the screenshot below you can see the result for legend: {position: 'in', alignment:'center'}. How to work around this?

"..when people generally complain about labels overlapping, that's due to attempting to draw in an invisible container. We currently do not support this, so you need to make sure that your container is not display:none when you draw the chart." - Sergey
Link: https://groups.google.com/forum/#!topic/google-visualization-api/c-KpZk--8p0

I had a chart loading near the bottom of a pretty complex page and this issue started. I decided to execute the creation of the chart after the page had loaded to give the parent div time to render.
$(document).ready(function(){
makeChart(data);
})
And the css for the parent div had a fixed height & width.
Hope this helps!

I was rendering graphs on a popup, labels were overlapping. I tried executing the rendering in $(document).ready() as well as $(window).load() - nothing worked out.
On a click event, the popup will appear.
$(document).ready(function()
{
$('.view_graphs').click(function(){
setTimeout(function(){
renderGraph();
},500)
})
})
function renderGraph() {
google.charts.setOnLoadCallback(column_chart);
function column_chart() {
var data = new google.visualization.arrayToDataTable(<?php echo $visitlang_json_data ?>);
var chart = new google.visualization.ColumnChart(document.getElementById('visit_lang_chart'));
var options = {'title':'Report based on language',
'width':600,
'height':500
};
chart.draw(data,options);
}
}
Rendering it on a setTimeout function on click event worked for me

Related

Canvas not rendering after animation without resizing viewport

I have two divs containing one canvas each. In the initial state only one is being displayed, the other has display set to none.
Upon clicking on the first canvas this code is executed:
$("#graph1").click(function(){
if(!$("#graphTwo").hasClass("toggled")) {
$("#graphTwo").animate({"height": "350px"}).removeClass("toggled");
$("#graphTwo").animate({"width": "700px"});
} else {
$("#graphTwo").animate({"height": "0px"}).addClass("toggled");
$("#graphTwo").animate({"width": "0px"});
}
});
The animation works just as intended, but the canvas is not displayed. It only appear after resizing the viewport. Why is this and how can I fix it?
I'm using chart.js.
You could try to call for a chart .update() see docs on updates when the #graphTwo becomes visible. (Because, that's what happens when you resize the viewport -> update chart)
...
if(!$("#graphTwo").hasClass("toggled")) {
$("#graphTwo").animate({"height": "350px"}).removeClass("toggled");
$("#graphTwo").animate({"width": "700px"});
/** add chart update here **/
the_chart_2.update(); // --> put the Chart instance
}
...
But you should be careful at this notice from the Responsive page docs:
Important Note Detecting when the canvas size changes can not be done
directly from the canvas element. Chart.js uses its parent container
to update the canvas render and display sizes.
I think that if the parent is not visible then the Chart is initiated, or updated, then you can have problems with rendering the chart later. So, maybe the safest way to do it is to update the chart, after the animation has finished.
...
if(!$("#graphTwo").hasClass("toggled")) {
$("#graphTwo").animate({
"height": "350px",
"width": "700px"
},
500, /* speed */
function(){
// Animation ended
/** add chart update here **/
the_chart_2.update(); // --> put the Chart instance
}).removeClass("toggled"); // ?
}
...
Did this make a difference?

OpenLayers: How can I redraw a map after a sidebar is collapsed?

I am using OpenLayers to display a map, and AdminLte for the interface.
My problem : When collapsing the main left sidebar on a given page, all the boxes and what it contains changes size (I don't really know how) so the maps gets bigger as well. The problem is that when it happens, all the features displayed on the maps apparently change position and are not where they are supposed to be anymore.
What I would like: To redraw the map after the sidebar collapses.
Any suggestion?
I tried:
$('.navbar-collapse').on('shown.bs.collapse', function() {
map.updateSize();
});
and:
$('.sidebar').on('shown.bs.collapse', function() {
map.updateSize();
});
but to no avail...
EDIT : My question is similar to this one: OpenLayers: How to re-align mouse coordinates and vector layers after fluid css rendering of map div but his solution doesn't work for me :)
EDIT 2 : Just to clarify: I think the solution to my problem would be to call the map.updateSize() method when the sidebar has finished collapsing. The problem is that I don't know how to catch the moment when the sidebar has finished collapsing/expanding!
A temporary solution I found was to start a timeout when the button triggering the sidebar collapse and then call the map.updateSize() method:
$('.sidebar-toggle').click(function(){
setTimeout(function(){ map.updateSize(); }, 500);
});
It works...but it's kind of meh :/
If you're trying to redraw the map after the sidebar collapses, change your event handler to the following:
$('.sidebar').on('hidden.bs.collapse', function() {
map.updateSize();
});
According to the list of event handlers here, the hidden.bs.collapse event is fired when a collapse element has been hidden from the user.
I have the same problem, using React and a class component my (awful) solution is this:
shouldComponentUpdate = async () =>
await new Promise(res =>
setTimeout(() => {
this.map.updateSize()
res(false)
}, 500)
)
It's awful because the resize causes the map to jump. If there is a way of achieving the map resize without a jump that would be pretty cool.
(500 is the animation time for my drawer to close)

highcharts not responsive after reflow

I am setting up a specialised Print button. The page is complicated and needs some pre-processing before being sent to window.print().
I have the Highcharts code working at this point. It correctly resizes the charts on the page, and then, post print, it sizes them back to their original size.
The problem is that from then on, the charts will not respond to Media Query changes. The site is Responsive, built on Bootstrap, so this is not a functional result.
How do I change the chart size, but leave it able to respond to Media Queries?
The code I am using is:
Setup Code
var saveChartContainerWidth = $('.highcharts-container').css('width');
var saveChartContainerWidthSVG = saveChartContainerWidth.slice(0, -2);
$('.highcharts-container').css('width', '690px');
$(Highcharts.charts).each(function(i,chart){
var height = chart.renderTo.clientHeight;
var width = 690; // chart.renderTo.clientWidth;
chart.setSize(width, height);
chart.reflow();
});
Post Print Teardown Code
$('.highcharts-container').css('width', saveChartContainerWidth);
$(Highcharts.charts).each(function(i,chart){
var height = chart.renderTo.clientHeight;
var width = saveChartContainerWidthSVG;
chart.setSize(width, height);
chart.reflow();
});
With the help of #Ryan's link, and comments from a co-worker, I tried a number of solutions which, while not working, got me closer.
Having then a better idea of what to look for, I finally found this answer Highcharts + Bootstrap .table-responsive issue which provided a key ingredient.
The two keys are:
Do not set the size on either the SVG itself, or the direct Highchart's container. (I set it on a containing Div one level higher.)
Trigger a $(window).trigger("resize"); event.
This worked in all browsers tested (Firefox, Chrome, IE 9 - 11).
----------------- The Final Code -----------------------
// Setup
$('.chart-container').css('width', '690px');
$(window).trigger("resize");
// Teardown
$('.chart-container').css('width', '');
$(window).trigger("resize");
Do this after setting the size will do the trick.
window.onresize = () => {
chart.setSize($('parentElement').offsetWidth, height)
chart.reflow()
}
Yet if you change the onresize function to something else, it might not work. So this is more like a quick solution, yet it works perfectly

JQuery Mobile + ChartJS : Responsive Bar Chart displayed only after resizing

I've been trying to add a responsive bar chart with Chart.js to one of my JQM projects.
This is what I've done: http://jsfiddle.net/mauriciorcruz/1pajh3zb/3/
Chart must be displayed on Page Two and it must be responsive. In my example, if you change responsive : true to false, it will work like a charm.
If responsive is set to true, after clicking the button you'll see nothing, but if you resize the screen the Chart will magically appear.
Any guesses why this is happening? I've tried different JQM events for #pagetwo without success.
Thank you very much!
In jQM 1.4, you would use the new pagecontainer widget's show event to make sure the page is drawn and all dimensions are available for the responsive chart to calculate its width:
$( "body" ).on( "pagecontainershow", function( event, ui ) {
if (ui.toPage.prop("id") == "pagetwo"){
//show chart code here
}
});
You use the ui parameter to see which page is being shown (ui.toPage).
DEMO
For jQM 1.3, there was no pagecontainer, so you just use the pageshow event delegated to yoyr chart page:
$(document).on( "pageshow", "#pagetwo", function() {
//show chart code here
});
DEMO
Using the show event, you are now drawing the chart each time the page is shown. If the chart does not change between visits to the page, you could keep a global javascript variable for the chart once drawn and check if it needs to be drawn on each visit:
var barChart;
$(document).on( "pageshow", "#pagetwo", function() {
if (barChart == null){
//draw if barchart is null
window.barChart = new Chart(ctx).Bar(data...
}
});

amCharts doesn't display chart for initially-hidden divs

I am using amCharts (which uses Raphaƫl behind the scenes) to render some charts as SVG; and have noticed that if the SVG is rendered in an initially-invisible div, the browser does not immediately render the image when the div becomes visible. If I modify the display however, e.g. by resizing the browser or Ctrl-mousewheel zooming, the SVG image is then rendered as expected when the page is redrawn.
The exact method of div visibility switching is via Bootstrap's tabbed navbar.
I admit to not being very experienced with SVG - is this an issue with the browsers' rendering, or amCharts' SVG markup, or am I required to explicitly call some sort of repaint method when I can tell the visibility of an SVG has changed?
Here's a jsFiddle which illustrates the problem; if you switch to Section 2 (in Chrome, Firefox) the chart isn't visible initially. Resizing the display causes it to appear.
I've found the reason for both the initial behaviour and the workaround - and it's all amCharts specific (nothing to do with SVG per se) so I'm rephrasing the title accordingly.
What happens is that when amCharts creates the SVG, it needs to (or at least, decides to) define the width and height in absolute terms. These are based on the size of the target div, obtained via the offsetWidth and offsetHeight properties.
The inactive tab has the display: none property set, and as a result this part of the DOM is not even rendered, so returns zero for both size properties. This ultimately leads to amCharts creating a 0x0 SVG chart when chart.write is called for the hidden div.
Resizing fixes things because each chart registers a listener to the onresize window event, which calls the chart's handleResize method. This forces a recalculation of the width and height based on the div's new (current) dimensions.
So in conclusion I think there are two alternative ways to handle this:
Call chart.write for a chart when and only when its tab becomes visible.
Call each chart's handleResize method when the tabs change.
(The first option avoids the initial hit of rendering an invisible chart, but then does a full redraw every time the tabs are changed. The latter takes a hit up-front but is likely quicker thereafter. For bonus marks, the best solution would be to render each chart exactly once between each resize, the first time it becomes visible, but that's a lot more complex as it would involve interfering with the default event listeners, amongst other things.)
Update: There's further complications with rendering an invisible chart; in particular, I found issues with the height calculations not taking into account the space required by the domain axis and so stretching the chart out of its div. This wasn't fixed by calling handleResize - calling measureMargins beforehand looked like it should work but didn't. (There's probably another method one could call after this to make it work such as resetMargins but at this point it started to feel very flaky...)
As such I don't think it's practical to render a chart for the first time on a non-visible div, so I went with some combination of the bullets above. I listen for when a chart's tab becomes visible for the first time and then call chart.write for the appropriate chart object - and whenever the tabs change, all previously-rendered charts are told to handle the resize.
* Edited *
Here is a updated fiddle. The Canvas will only be rendered once the tab is shown.
I store the chartdiv ids in an array and check whether there are in it or not.
* Edited *
The only solution I found was to show the Graph after the specific tab is shown.
As you see in this jsFiddle.
var tabs = $('.tabbable').tab()
tabs.on('shown', function(e){
id = $(e.target).attr('href');
chartdiv_id = $(id).find('.chartdiv').attr('id');
doChart(chartdiv_id, true);
});
I guess it isn't exactly what you are looking for, but i hope it helps for the moment.
I had the same problem, but my solution it's alternative to display:none, you can use this class in the css
.hidden {
position: absolute !important;
top: -9999px !important;
left: -9999px !important;
}
this dissapear of the screen but visible for the amchart, so the resolution of the chart never lose the size!!!!
I completely agree with Andrzej Doyle.
Issuing handleresize on the chart when clicking on the selected div (tab) works for me on cs-cart with custom tabs (not jquery ones).
The following works while cart beeing globally defined.
function refreshchart(){
chart.handleResize();
};
I also ran into the issue and fixed it by making the initializer a function. Working fiddle.
$("#button").click(function(){
$("#chartdiv").toggle();
makeChart();
});
function makeChart() {
var chart = AmCharts.makeChart("chartdiv", {
//all the stuff
});
}
This Might help you to resolve issue . I have my amchart showing in different tab pan . SVG Component does not allow them to show that div due to resizing issue .
$(window).resize(function() {
setTimeout(function() {
chart.write("chartdiv1");
}, 300);
});
resize again your window while you create your charts ..
Show me charts
<div class="charts_div" style="display:hidden;">
some charts here
</div>
<script>
$(document).on('click', '.show_charts', function(){
$('.charts_div').toggle();
//just redraw all charts available on the page
for(var i = 0; i < AmCharts.charts.length; i++) {
AmCharts.charts[i].validateData();
}
});
</script>
var chart = null;
AmCharts.ready(function () {
chart = AmCharts.makeChart('chart', .....);
});
$(document).ready(function(){
$("#view_chart").click(function(){
chart.validateSize();
});
});
<button type="button" id="view_chart">View Chart</button>
<div style="display:none;" id="chart"></div>
Another work around would be
drawTransactionTypeChart();
setTimeout(function(){hidePieCharts();},1);
Initially set display:inline to div which is chart container, it gets rendered .
Then set display:none using setTimeout() after 1ms.
Hope this helps...
I have two amcharts on different tabs.
A stock chart to be place on #chartdiv and a pie chart to be placed on #chartdivpie.
This is how I solved my problem.
My custom css - to overwrite bootstrap -
#chartdivpie { width: 1138px; height: 500px; }
.tab-content .tab-pane {
position: absolute;
top: -9999px;
left: -9999px;
display: inline;
}
.tab-content .tab-pane.active {
position: inherit !important;
}
JQuery call
$('#myTab a').click(function (e) {
e.preventDefault()
$(this).tab('show');
chart.invalidateSize();
chart.write('chartdiv');
})

Categories