I'm trying to make a Slideshow/carousel with pie charts in it. The charts load when the page loads, but only one is displayed at a time.
The problem is that when I move the slideshow to the side to display the second chart, instead of rendering within it's container it takes up the whole space of it's grandparent. Specifically, the first chart that renders is the correct size, any other chart is wrong.
This doesn't use any PHP or anything of the sort, just javascript, html, css and the canvasjs framework. I've tried forcing the graphs to be a fixed size but when I load the next one it just ignores all of the rules I set.
Here is the code:
/*--------- function that creates the charts ----------*/
function criaGrafico(id, valores, tp) {
setInner(id, '');
if (valores == '') return;
var dados = new Array;
var title = {
text: '',
};
var legenda = {
fontSize: "14",
verticalAlign: "bottom",
horizontalAlign: "left",
fontFamily: "sans-serif",
itemWrap: false
};
dados[0] = {
dataPoints: new Array,
indexLabelFontSize: 10,
indexLabelFontFamily: "sans-serif",
indexLabelFontColor: "darkgrey",
indexLabelLineColor: "darkgrey",
indexLabelPlacement: "outside",
indexLabelMaxWidth: 60,
type: tp,
showInLegend: false, // true mmm
legendMarkerType: 'square'
};
var opc = {
title: title,
legend: legenda,
data: dados
};
var chart = new CanvasJS.Chart(id, opc);
var campo = '';
for (var i = 0, lt = valores.length; i < lt; i++) {
campo = valores[i].split("|");
chart.options.data[0].dataPoints.push({
y: Decimal(campo[0]),
legendText: campo[4],
indexLabel: campo[2],
toolTipContent: campo[1],
color: campo[3]
/*,click:function(e){clicouGrafico(e)}*/
,
cursor: "pointer"
});
}
chart.render();
}
/* function that sets the parameters for the chart */
function graficoProj1() {
var val = new Array();
val[0] = '71|Finalizadas: 87 (71%)|Fin|green|Finalizadas';
val[1] = '9|Direcionadas: 12 (9%)|Dir|orange|Direcionadas';
val[2] = '18|Iniciadas: 22 (18%)|Ini|blue|Iniciadas';
criaGrafico('chart_inov3', val, "pie");
}
#chart_inov3 {
margin-left: 15px;
z-index: 0;
position: relative;
}
<div class="slideshow-container">
<div class="projSlides fade">
<div class='col-d-4 col-t-4'>
<div id='chart_container' style="height: 170px; width: 170px;">
<div id="chart_inov3"></div>
</div>
</div>
<!-- some other info that would stay besides the chart,
in the same parent container -->
</div>
</div>
Then, the function graficoProj1 is called when the window loads, along with the other charts that will go into the slideshow, like graficoProj2 and graficoProj3.
The result should be a chart that stays inside it's own container, like so:
However, when I press the "Next" button to the right to display the next slide, the other chart renders like this:
EDIT:
I suspect this might be linked to the way I display the containers of the slideshow, since they are first set as display: none and then they get to be display: block when focused. This might cause the charts to not render properly within their container since they are not shown. Rerendering them might fix this problem, but I'm still at a loss at how to.
Does anyone have any idea of what could be causing this?
I've fixed it already, forgot to update. The problem was in the "showSlide" javascript function (which was not in this post). When hidden, the charts don't render, so I just have to call the render function after display: block is shown.
Related
Since I could not find and answer for this question, I hope it's not a duplicate. I'm using chartist.js, and I make a simple donut, that's pretty easy and straight forward, but now I'd like to disable the labels, which works fine and add a single lable inside of the donut (Thhis is the problem). It's not needed, that the label gets greated, by the chart itself, it would be sufficient if it's just a new div or something else.
My Code so far:
<div class="ct-chart1 ct-chart ct-perfect-fourth"></div>
and
new Chartist.Pie('.ct-chart1', {
labels: [],
series: [75, 25]
}, {
donut: true,
width: '300px',
height: '200px',
donutWidth: 30,
startAngle: 0,
total: 100
});
I already tried to make the chart itself a flexbox and add the label as child and center it that way, but that did not work and I tried to surround the chart with a new div, but that let's the chart disappear.
<div>
<div class="ct-chart1 ct-chart ct-perfect-fourth"></div>
</div>
I'd use the draw event to center labels to the middle of the chart. Check this bin http://jsbin.com/hipafu/edit?html,css,js,output
Also watch out for the styles:
.ct-label {
dominant-baseline: central;
text-anchor: middle;
}
I'm trying to render two dynamic charts using canvasJS, Chart one is rendering properly, in fact second chart is populating properly, please see the inspect element image, but it's not displaying on the page.
This is interface, just one chart is displaying
and here is inspect elem.
#adverts is rendering, but not displayed here.
.chartContainer{
height: 400px;
width: 100%;
}
PS I tried to commented out first chart rendering code, but not working at all, still displaying the first one only.
EDIT
Here is console log about what I'm getting back to render chart
here is snippet
function drawChart(obj, placeholder, From, To){
var legendFrom;
var legendTo;
if(From != 'undefined'){
legendFrom = From;
}
if(To != 'undefined'){
legendTo = To;
}
var dataPoints = [];
var from = [];
var to = [];
var advertFrom = [];
var advertTo = [];
for (var i = 0; i <= obj.length - 1; i++) {
if(obj[i].typeOf != 'undefined' || obj[i].typeOf != ''){
if(obj[i].typeOf == 'from'){
from.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
advertFrom.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:obj[i].adverts});
}else{
to.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
advertTo.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:obj[i].adverts});
}
}
else
from.push({label:obj[i].year+"-"+obj[i].month+"-"+obj[i].day,y:Math.round(obj[i].avgPrice * 1000) / 1000});
}
var chart = new CanvasJS.Chart("chartContainer",
{
animationEnabled: true,
//theme: "theme1",
zoomEnabled: true,
title:{
text: placeholder
},
data: [
{
type: "spline", //change type to bar, line, area, pie, etc
showInLegend: true,
legendText: "From "+legendFrom,
dataPoints: from
},
{
type: "spline",
showInLegend: true,
legendText: "From "+legendTo,
dataPoints: to
}
],
legend: {
cursor: "pointer",
itemclick: function (e) {
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}
});
chart.render();
var adverts = new CanvasJS.Chart("adverts",
{
animationEnabled: true,
zoomEnabled: true,
title:{
text: placeholder
},
data: [
{
type: "column", //change type to bar, line, area, pie, etc
showInLegend: true,
legendText: "From "+legendFrom,
dataPoints: advertFrom
},
{
type: "column",
showInLegend: true,
legendText: "From "+legendTo,
dataPoints: advertTo
}
]
});
adverts.render();
}
I just replicated a canvasJS enviroment in JSFiddle
http://jsfiddle.net/fLbngdv9/1/
Make sure you are are using a new VAR for each chart.
var chart = new CanvasJS.Chart("chartContainer", {..});
chart.render();
var chart2 = new CanvasJS.Chart("chartContainer2", {..});
chart2.render();
Seems to work fine. If you can provide me with some code examples then perhaps I can help you find an answer.
Probably just a copy paste mistake but you have a syntax error at the very bottom.
...
adverts.render();
}
This should be
...
adverts.render();
Just remove the extra bracket. I updated the JS Fiddle to be more like your example... [here]
Edit:
I was able to replicate in my latest JSFiddle and I know this sounds crazy but when I changed the ID of your second div from adverts to chartContainer2 it worked fine.
Still investigating as to why this is but I would try renaming the ID on the div and also the reference for the graphs creation.
SEE HERE
Edit 2:
This appears to be a Chrome specific bug with the ID adverts. To replicate all you need to do is check out this link http://www.briangebel.com/test.html
(As you can see the div Adverts is hidden in Chrome but visible on FF,Opera,IE)
So what is happening..
Chrome's ADBlocker extension sees this ID and automatically adds an in page stylesheet.
This style sheet has the following Style
This only affects Chrome as it is caused by a specific extension. (I am attempting to contact the developer to see if he can resolve this but until then follow the below solution)
Solution
Simple don't use that ID. (You could simply disable AdBlocker but this extension is so widely used I would still recommend changing the ID)
I am using jqplot to create a pie chart from an HTML table.
However, when attempting to set a var the chart doesn't plot.
If i simply set a number for the var, such as:
var DataTest = 22;
then the chart works fine.
However, when I get the value from the table it doesn't, as below:
var DataTest = $(dataID + ' td:nth-child(46)').text();
The pie chart wont display.
The pie chart series is being set through a var also:
var PieChartS1 = [ ['Label', DataTest] ];
Then included in the chart code as follows:
var PieChartPlot = $.jqplot('PieChart', [PieChartS1, PieChartS2 ], {
seriesDefaults: {
renderer:$.jqplot.DonutRenderer,
rendererOptions:{
sliceMargin: 1,
startAngle: -145,
showDataLabels: true,
dataLabels: 'label',
padding: '5',
ringMargin: '5',
dataLabelThreshold: '1',
highlightMouseOver: true,
}
},
grid: {background: 'transparent', borderWidth: '0', cursor: 'pointer',},
});
I'm wondering whether it is a format issue?
Thanks for any help
Richard
Update:
Am wondering whether the graph is being formed by the script before the data has been obtained, so it is just showing blank as it is finding no data. Perhaps I need to delay the graph formation until the 'get data' scripts are fully executed?
Had some help from elsewhere.
It needs to be specified as an integer, so the change needs to be:
var DataTest = parseInt($(dataID + ' td:nth-child(46)').text());
This works fine.
I'm trying to create a pie chart through the use of flot charts. I have successfully managed to create one with the following code:
HTML:
<div class="row">
<div class="col-md-6">
<div id="pie-chart"></div>
</div>
</div>
Javascript:
var data = [];
data[0] = { label: "Vertification successful", data: 9 };
data[1] = { label: "Vertification failed", data: 2 };
var series = Math.floor(Math.random() * 10) + 1;
$.plot($("#pie-chart"), data,
{
series: {
pie: {
show: true,
}
},
grid: { hoverable: true },
});
And it displays just fine.
The thing is, if I change the ID of the div element to "pie-chart1" (rather than "pie-chart")
and update the javascript accordingly:
$.plot($("#pie-chart1"), data,
I get the following error:
Uncaught Invalid dimensions for plot, width = 501, height = 0
What on earth could be causing this? I simply wanna rename the ID which apparently for some reason is impossible.
It's very likely that there is some CSS or possibly JS elsewhere on your site that expects the div to be called pie-chart. You need to ensure that it still applies to the new div. For example, if you had:
#pie-chart {
width: 400px;
height: 300px;
}
When you change the ID of the div, you need to update that reference too, or else the placeholder's height and width become undefined, which Flot cannot handle.
If your goal in adding that number is to create several charts, then you should use a class to apply the styles rather than an ID.
I am using jqPlot to display many graphs on some webpages. I am wanting to be able to save these graphs to an image file.
What is the best way to do this? Is it possible to have a right click menu option on the graph that enables the graph to be saved to an image file?
Here is some code for one of my graphs:
var plotCogsLineGraph = $.jqplot('FinancialsLineGraph', [[30,31,34,40,45], [34,38,31,42,38]],
{
axes:
{
xaxis:
{
ticks: ['5','4','3','2','1']
},
yaxis:
{
label:'%',
pad: 1.05,
ticks: ['0','15','30','45','60']
}
},
width: 480, height: 270,
legend:{show:true, location: 's', placement: 'insideGrid', renderer: $.jqplot.EnhancedLegendRenderer},
seriesDefaults:
{
rendererOptions: {smooth: true}
},
series:[
{
lineWidth:1,
label:'COGS',
markerOptions: { size:1, style:'dimaond' }
},
{
lineWidth:1,
label:'Wages',
markerOptions: { size: 1, style:"dimaond" }
}
]
}
);
What needs to be added to this above code to enable saving the graph to an image file?
Try this:
$('#FinancialsLineGraph').jqplotSaveImage()
Let's say your plot is drawing in a div with 'plot' id.
You have to apply native jqplotToImageStr({}) function in order to convert the plot to an image.
Then you can fill an other div (with id = 'graphicImage' for example) in order to display this freshly generated image :
var graphicImage = $('#graphicImage');
if(graphicImage.html() == ""){ //If the image was even generated, don't generate it again
var divGraph = $('#plot').jqplotToImageStr({});
var divElem = $('<img/>').attr('src', divGraph);
graphicImage.html(divElem);
}
In order to download the image, you can do something like :
open(divGraph.toDataURL("image/png"));
In my case it doesn't work great as the image downloaded on my computer is corrupted.
If you find a way to save it I'll be great to hear about it.
Anyway, once you have done the first part on this answer (fill the '#graphicImage' div with the image corresponding to jqplot), you can save it thanks to a right click on it...
$('#GraphName').jqplotSaveImage() but aware that if you have applied some custom styles on ticks this won't be saved to image