Related
I am trying to plot pandas dataframe from a python function and display it on a web server using Highcharts pie chart. I can get the data from the function to the web server as json data through flask. but when I want to display it the chart is empty. Through the web console I also made sure that the data format going into the Highcharts is correct but still nothing.
Here I am retrieving the panda dataframe and sending it to the web server through flask:
actype_json = actype.to_json(orient = 'records')
#app.route('/data/airport', methods = ['GET'])
def broadcast_data():
return eval(json.dumps(actype_json))
#app.route('/')
def plotgraph():
return render_template('airport.html')
On my HTML file, I tried to use AJAX to call for the data and plot it in a Highcharts Pie Chart:
<!DOCTYPE html>
<html>
<head>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://code.highcharts.com/modules/export-data.js"></script>
<script
src="https://code.jquery.com/jquery-3.3.1.js"
integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60="
crossorigin="anonymous">
</script>
</head>
<body>
<div id="container" style="min-width: 310px; height: 400px; max-width: 600px; margin: 0 auto"></div>
<script>
function GetUpdatedData(){
$.ajax({
url: "/data/airport",
})
.done(function( data ) {
console.log( data );
DrawGraph(data);
});
}
function DrawGraph(dataset) {
// Radialize the colors
Highcharts.setOptions({
colors: Highcharts.map(Highcharts.getOptions().colors, function (color) {
return {
radialGradient: {
cx: 0.5,
cy: 0.3,
r: 0.7
},
stops: [
[0, color],
[1, Highcharts.Color(color).brighten(-0.3).get('rgb')] // darken
]
};
})
});
// Build the chart
Highcharts.chart('container', {
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: 'Browser market shares in January, 2018'
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
},
connectorColor: 'silver'
}
}
},
series: [{
name: 'Aircraft',
data: [dataset]
}]
});
setTimeout(GetUpdatedData, 1500);
}
</script>
</body>
</html>
This is the screenshot of the Highcharts Pie Chart that I am seeing:
The response tab is showing the format of the data trying to be plotted on Highchart. Any advice will be very helpful. Thanks!
You've made a simple mistake when adding data to series.data array. Note that your data is actually a correct Highcharts data array with point objects inside:
data:
[{
"AC TYPE": "B773",
"y": 35
}, {
"AC TYPE": "B77W",
"y": 16
}]
However, you've added this array inside another one like that:
series: [{
name: 'Aircraft',
data: [dataset]
}]
This gives you an invalid data format with two nested arrays:
series: [{
name: 'Aircraft',
data: [[{
"AC TYPE": "B773",
"y": 35
}, {
"AC TYPE": "B77W",
"y": 16
}]]
}]
Remove the wrapping array and the chart should be rendered correctly.
Demo:
https://jsfiddle.net/BlackLabel/49rhpmyg/
I just ask a question which was basically I was having a problem of z-index which got resolved now. But there is now another problem which I am facing as when I am clicking back button it is working in IE rather it is opening location of the folder where the particular file exists. Is there a special way to go back to an initial position in IE.
My fiddle is at this location -
fiddle link
Anyway I posting my code -
<!DOCTYPE HTML>
<html>
<head>
<script src="http://canvasjs.com/assets/script/canvasjs.min.js"></script>
<!-- <link type='text/css' rel="stylesheet" href='style.css' /> -->
<style>
#chartContainerpie{
position: absolute;
top: 130px;
left: 0px;
}
#chartContainer{
position: absolute;
top: 0px;
left: 0px;
}
#link {
visibility : hidden;
top : 0px;
left : 0px;
position:relative;
z-index:100;
}
</style>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "My First Chart in CanvasJS"
},
backgroundColor: "transparent",
data: [{
click: function(e){
anotherchart();
},
// Change type to "doughnut", "line", "splineArea", etc.
type: "doughnut",
dataPoints: [{
label: "apple",
y: 10
}, {
label: "orange",
y: 15
}, {
label: "banana",
y: 25
}, {
label: "mango",
y: 30
}, {
label: "grape",
y: 28
}]
}]
});
chart.render();
var chart = new CanvasJS.Chart("chartContainerpie", {
backgroundColor: "transparent",
data: [{
// Change type to "doughnut", "line", "splineArea", etc.
indexLabelPlacement: "inside",
indexLabelFontColor: "white",
indexLabelFontSize: "14px",
type: "pie",
dataPoints: [{
label: "apple",
y: 10
}, {
label: "orange",
y: 15
}, {
label: "banana",
y: 25
}, {
label: "mango",
y: 30
}, {
label: "grape",
y: 28
}]
}]
});
chart.render();
}
function anotherchart () {
document.getElementById("chartContainerpie").innerHTML = "";
document.getElementById("chartContainer").innerHTML = "";
document.getElementById("link").style.visibility = "visible";
// alert( e.dataSeries.type+ ", dataPoint { x:" + e.dataPoint.x + ", y: "+ e.dataPoint.y + " }" );
var chart = new CanvasJS.Chart("chartContainernew", {
backgroundColor: "transparent",
data: [{
// Change type to "doughnut", "line", "splineArea", etc.
indexLabelPlacement: "inside",
indexLabelFontColor: "white",
indexLabelFontSize: "14px",
type: "doughnut",
dataPoints: [{
label: "apple",
y: 10
}, {
label: "orange",
y: 15
}, {
label: "banana",
y: 25
}, {
label: "mango",
y: 30
}, {
label: "grape",
y: 28
}]
}]
});
chart.render();
}
</script>
</head>
<body>
<div>
<div id="chartContainerpie" style="height: 188px; width: 100%;"></div>
<div id="chartContainer" style="height: 400px; width: 100%; "></div>
</div>
<div>
<a id="link" href="">Back</a>
<div id="chartContainernew" style="height: 400px; width: 100%; "></div>
</div>
<div>
</div>
</body>
</html>
In IE, empty HTML HREF leads to directory listing. For further information, you can refer this link.
Meanwhile you can use
<a id="link" href='#' onclick='location.reload(true); return false;'>Back</a>
This will refresh the page and you will get your old chart back.
But there are better ways to do this. Since you are placing one div on another, you can always place one more hidden div which you can show on click while hiding original 2 div.
In my fiddle, I'm trying to replicate plotting a DevExpress's DevExtreme doughnut chart:
var dataSource = [{
region: "Asia",
val: 4119626293
}, {
region: "Africa",
val: 1012956064
}, {
region: "Northern America",
val: 344124520
}, {
region: "Latin America and the Caribbean",
val: 590946440
}, {
region: "Europe",
val: 727082222
}, {
region: "Oceania",
val: 35104756
}];
$("#container").dxPieChart({
dataSource: dataSource,
title: "The Population of Continents and Regions",
tooltip: {
enabled: true,
format: "millions",
percentPrecision: 2,
customizeTooltip: function(arg) {
return {
text: arg.valueText + " - " + arg.percentText
};
}
},
legend: {
horizontalAlignment: "right",
verticalAlignment: "top",
margin: 0
},
series: [{
type: "doughnut",
argumentField: "region",
label: {
visible: true,
format: "millions",
connector: {
visible: true
}
}
}]
});
#container {
height: 440px;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container"></div>
This official code is working in ChartJS's fiddle.
Since I'm not doing it in an ASP.NET MVC project, chartjs after the DevExpress MVC scripts shall not be an issue
What am I missing here?
Check the console - it isn't finding the .dxPieChart function because it can't load the 'insecure' chart.js script:
'Mixed Content: The page at 'https://jsfiddle.net/xameeramir/51h3bmgf/' was loaded over HTTPS, but requested an insecure script 'http://cdn3.devexpress.com/jslib/15.2.10/js/dx.chartjs.js'. This request has been blocked; the content must be served over HTTPS.'
Maybe you find a https CDN link for the library?
Change http cdn to https. Https cdn for the devextreme chartjs 13.1.5 library: https://dxjscdn2.blob.core.windows.net/jslib/13.1.5/js/dx.chartjs.js
I am working with KendoUI bar chart. Please check this fiddle. In this fiddle I am setting series config at the design time. I want to add series to the chart at run time on click of a button. How can I add series to kendo chart on click of a button.
Currently series is assigned at the design time, i want to do the same at the run time on click of a button.
Code:
<!DOCTYPE html>
<html>
<head>
<base href="http://demos.telerik.com/kendo-ui/bar-charts/grouped-stacked-bar">
<style>html { font-size: 14px; font-family: Arial, Helvetica, sans-serif; }</style>
<title></title>
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.1.112/styles/kendo.common-material.min.css" />
<link rel="stylesheet" href="//kendo.cdn.telerik.com/2016.1.112/styles/kendo.material.min.css" />
<script src="//kendo.cdn.telerik.com/2016.1.112/js/jquery.min.js"></script>
<script src="//kendo.cdn.telerik.com/2016.1.112/js/kendo.all.min.js"></script>
</head>
<body>
<div id="example">
<div class="demo-section k-content wide">
<div id="chart"></div>
</div>
<script>
function createChart() {
$("#chart").kendoChart({
title: {
text: "World population by age group and sex"
},
legend: {
visible: false
},
seriesDefaults: {
type: "column"
},
series: [{
name: "0-19",
stack: "Female",
data: [854622, 925844, 984930, 1044982, 1100941, 1139797, 1172929, 1184435, 1184654]
}, {
name: "20-39",
stack: "Female",
data: [490550, 555695, 627763, 718568, 810169, 883051, 942151, 1001395, 1058439]
}, {
name: "40-64",
stack: "Female",
data: [379788, 411217, 447201, 484739, 395533, 435485, 499861, 569114, 655066]
}, {
name: "65-79",
stack: "Female",
data: [97894, 113287, 128808, 137459, 152171, 170262, 191015, 210767, 226956]
}, {
name: "80+",
stack: "Female",
data: [16358, 18576, 24586, 30352, 36724, 42939, 46413, 54984, 66029]
}, {
name: "0-19",
stack: "Male",
data: [900268, 972205, 1031421, 1094547, 1155600, 1202766, 1244870, 1263637, 1268165]
}, {
name: "20-39",
stack: "Male",
data: [509133, 579487, 655494, 749511, 844496, 916479, 973694, 1036548, 1099507]
}, {
name: "40-64",
stack: "Male",
data: [364179, 401396, 440844, 479798, 390590, 430666, 495030, 564169, 646563]
}, {
name: "65-79",
stack: "Male",
data: [74208, 86516, 98956, 107352, 120614, 138868, 158387, 177078, 192156]
}, {
name: "80+",
stack: "Male",
data: [9187, 10752, 13007, 15983, 19442, 23020, 25868, 31462, 39223]
}],
seriesColors: ["#cd1533", "#d43851", "#dc5c71", "#e47f8f", "#eba1ad",
"#009bd7", "#26aadd", "#4db9e3", "#73c8e9", "#99d7ef"],
valueAxis: {
labels: {
template: "#= kendo.format('{0:N0}', value / 1000) # M"
},
line: {
visible: false
}
},
categoryAxis: {
categories: [1970, 1975, 1980, 1985, 1990, 1995, 2000, 2005, 2010],
majorGridLines: {
visible: false
}
},
tooltip: {
visible: true,
template: "#= series.stack #s, age #= series.name #"
}
});
}
$(document).ready(createChart);
$(document).bind("kendo:skinChange", createChart);
</script>
</div>
</body>
</html>
Ageonix gave a good answer! If you do not want to use a global variable for the chart options, you can get the chart instance from the DOM data-attribute, add the series to the chart instance and then tell the chart to redraw:
var newseries = {
name: "100+",
stack: "Female",
data: [654622, 625844, 784930, 844982, 900941, 39797, 72929, 118435, 118454]
};
//Get the chart
var chart = $("#chart").data("kendoChart");
//add the series
chart.options.series.push(newseries);
//refresh the chart
chart.redraw();
Updated DOJO
If you set the chart options as a global variable, you can then modify options.series and set it to your updated series data source in the button click event and call createChart() again, which will update (recreate) the chart with the updated series.
Create a global chartOptions variable:
var chartOptions =
{
title: {
text: "World population by age group and sex"
},
legend: {
etc. etc.
Then create the chart with the options stored in the variable:
$("#chart").kendoChart(chartOptions);
Finally, update the options.series with the updated data and recreate the chart:
click: function()
{
chartOptions.series = updatedSeries;
$("#chart").kendoChart(chartOptions);
}
I updated your Dojo and added a button that populates a new series on click.
http://dojo.telerik.com/oTeTi/3
I've got some charts of http://canvasjs.com/javascript-charts/ and they are just wonderful! I used one of them and it worked perfectly :
<script type="text/javascript">
google.charts.load("current", {packages: ["corechart"]});
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['ip', 'quantity'],
#foreach($ipsWithBytesDates as $item)
['{{$item['ip']}}', {{$item['counts']}}],
#endforeach
]);
var options = {
title: 'My Daily Activities',
is3D: true,
};
var chart = new google.visualization.PieChart(document.getElementById('piechart_3d'));
chart.draw(data, options);
}
</script>
<div id="piechart_3d" style="width: 700px; height: 350px;"></div>
Now i need a second chart - I've already got it from the website and copy & paste it in my code.. but this haven't worked like I want.. the second chart works but overwrites the whole first chart.
The first chart is a column chart and is at the top of my page.. the second chart should be at the bottom.. but it isn't, it every time just overwrites my first chart -- could anybody tell me why? I think it's because of the "window.onload" at the beginning of both chart.. but I haven't really worked with javascript.
second chart:
<script type="text/javascript">
window.onload = function () {
var secchart = new CanvasJS.Chart("chartContainer2",
{
title:{
text: "U.S Smartphone OS Market Share, Q3 2012",
fontFamily: "Impact",
fontWeight: "normal"
},
legend:{
verticalAlign: "bottom",
horizontalAlign: "center"
},
data: [
{
//startAngle: 45,
indexLabelFontSize: 20,
indexLabelFontFamily: "Garamond",
indexLabelFontColor: "darkgrey",
indexLabelLineColor: "darkgrey",
indexLabelPlacement: "outside",
type: "doughnut",
showInLegend: true,
dataPoints: [
{ y: 53.37, legendText:"Android 53%", indexLabel: "Android 53%" },
{ y: 35.0, legendText:"iOS 35%", indexLabel: "Apple iOS 35%" },
{ y: 7, legendText:"Blackberry 7%", indexLabel: "Blackberry 7%" },
{ y: 2, legendText:"Windows 2%", indexLabel: "Windows Phone 2%" },
{ y: 5, legendText:"Others 5%", indexLabel: "Others 5%" }
]
}
]
});
secchart.render();
}
</script>
<script type="text/javascript"></script>
<div id="chartContainer2" style="height: 300px; width: 100%;"></div>
source code from the chartlibary:
You need to have separate containers for each chart. Each snippet you've pasted is using var chart = new CanvasJS.Chart("chartContainer",
Try setting the 2nd chart to use a different element on your page.
<div id="chartContainer1" style="height: 300px; width: 100%;"></div>
<div id="chartContainer2" style="height: 300px; width: 100%;"></div>
var chart = new CanvasJS.Chart("chartContainer1", ...
var chart = new CanvasJS.Chart("chartContainer2", ...
Looks like both of these charts are being rendered in an element called "chartContainer". In both code snippets there is a div at the bottom with this name. You should change the name of this div for at least one of the charts.