Passing Data from Controller to ChartJS - spring

I am trying to pass data from Controller to feed a chart using ChartJS, but when I use a keySet function as labels, the chart is not rendering.
This is the Method from Controller:
#GetMapping("/reports")
public String showDashboard(Model model) {
Map<String, Integer> data = new LinkedHashMap<String, Integer>();
data.put("JAVA", 50);
data.put("Ruby", 20);
data.put("Python", 30);
model.addAttribute("data", data);
return "reports";
}
This is the HTML Code:
<pre>
<body>
<div class="container">
<div th:replace="fragments/navbar :: top"></div>
<div class="row" style="margin-top: 60px">
<div class="chart-container" style="margin: 0 auto; height:20vh; width:40vw">
<canvas id="myChart"></canvas>
</div>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: [[${data.keySet()}]],
datasets: [{
data: [[${data.values()}]],
backgroundColor: [
'rgb(0,255,255)',
'rgb(46,139,87)',
'rgb(255,165,0)'
],
borderColor: [
'rgb(0,255,255)',
'rgb(46,139,87)',
'rgb(255,165,0)'
],
borderWidth: 1
}]
},
});
</script>
</div>
</div>
</body>
</pre>
The chart is not been rendered and this is the output when I check the source code:
<pre>
<script>
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: [JAVA, Ruby, Python],
datasets: [{
data: [50, 20, 30],
backgroundColor: [
'rgb(0,255,255)',
'rgb(46,139,87)',
'rgb(255,165,0)'
],
borderColor: [
'rgb(0,255,255)',
'rgb(46,139,87)',
'rgb(255,165,0)'
],
borderWidth: 1
}]
},
});
</script>
</pre>
It seems that the function keySet() is not getting values as String.
How can I adjust it to show the values as String and then rendered as Labels?
Regards,

I faced similar problem and found that we should use Object.keys(data) instead of data.keySet(). So below is the way you can use it
var htmldata = [[${data}]];
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: Object.keys(htmldata),
datasets: [{
data: Object.keys(htmldata).map(function(key) {return htmldata[key];}),
backgroundColor: [
'rgb(0,255,255)',
'rgb(46,139,87)',
'rgb(255,165,0)'
],
borderColor: [
'rgb(0,255,255)',
'rgb(46,139,87)',
'rgb(255,165,0)'
],
borderWidth: 1
}]
},
});
Also your javascript is not thymeleaf readable. Please add th:inline=javascript in script tag and provide CDATA as below
<script th:inline="javascript">
/*<![CDATA[*/
// Here goes my previous script
/*]]>*/
</script>

There is a simpler solution. Just generate your LinkedHashMap like this:
graphDataHM.put('"'+yourLabel+'"', yourValue);
Then in the HTML code use:
<pre>
<body>
<div class="container">
<div th:replace="fragments/navbar :: top"></div>
<div class="row" style="margin-top: 60px">
<div class="chart-container" style="margin: 0 auto; height:20vh; width:40vw">
<canvas id="myChart"></canvas>
</div>
<script>
var xValues = ${graphDataHM.keySet()};
var yValues = ${graphDataHM.values()};
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'pie',
data: {
labels: xValues,
datasets: [{
data: yValues,
backgroundColor: [
'rgb(0,255,255)',
'rgb(46,139,87)',
'rgb(255,165,0)'
],
borderColor: [
'rgb(0,255,255)',
'rgb(46,139,87)',
'rgb(255,165,0)'
],
borderWidth: 1
}]
},
});
</script>
</div>
</div>
</body>
</pre>
You can populate your LinkedHashMap with data from any source (database, other objects and so on).

Related

Download HTML as image

How can i download the output from this code automatically when accessing the page, not by clicking any button in the page like I need to automate the download process.
<!DOCTYPE html>
<html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
<body>
<canvas id="myChart" style="width:100%;max-width:600px"></canvas>
<script>
var xValues = [50,60,70,80,90,100,110,120,130,140,150];
var yValues = [7,8,8,9,9,9,10,11,14,14,15];
new Chart("myChart", {
type: "line",
data: {
labels: xValues,
datasets: [{
fill: false,
lineTension: 0,
backgroundColor: "rgba(0,0,255,1.0)",
borderColor: "rgba(0,0,255,0.1)",
data: yValues
}]
},
options: {
legend: {display: false},
scales: {
yAxes: [{ticks: {min: 6, max:16}}],
}
}
});
</script>
</body>
</html>

Is it possible to rotate whole echarts Instance in Apache ECharts?

I'm new to echarts so please forgive me if this is stupid newbie request. I'm trying to rotate whole chart just like in this example of Vega Edge Bundling Example. On the right corner there is a tool and one option is also "rotate".
Example Image of Vega
I would like to do the same thing (rotate whole graph) in echarts but I can't find a way to do it. If it is possible to do it please let me know how I can do it. Thank you for any reply!
It's not perfect but I tried.
I use function to change startAngle,I don't know why the rotation is delayed.
var option = {
title: {
text: 'Referer of a Website',
subtext: 'Fake Data',
left: 'center'
},
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left'
},
series: [
{
name: 'Access From',
type: 'pie',
radius: '50%',
startAngle: 15,
data: [
{ value: 1048, name: 'Search Engine' },
{ value: 735, name: 'Direct' },
{ value: 580, name: 'Email' },
{ value: 484, name: 'Union Ads' },
{ value: 300, name: 'Video Ads' }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
var myChart2 = echarts.init(document.getElementById('main2'));
myChart2.setOption(option);
function rotate() {
var Angle=document.getElementById("range").value;
myChart2.setOption({
series: [{
startAngle:Angle,
}]
});
};
<html lang="Zh-TW">
<head>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.2.2/echarts.min.js"></script>
<meta charset="utf-8">
</head>
<body>
<label class="col-lg-3 control-label">rotate</label>
<div class="col-lg-6"><input type="range" class="form-control" min="0" max="360" value="10" oninput="rotate('range')" id="range"></div>
<div id="main2" style="width:100%;height:600px;"></div
</body>
</html>

How to display string[] for creating column chart in Spring and jsp

I want to create a column chart, I find CanvasJS.Chart to create a chart but it accepts a single element for creating a chart, so my question is how can I use my string[] in CanvasJS.Chart for creating chart
value and Nvalue received from checkbox selection option
#RequestParam(value = "value", required = false) String[] value)
#RequestParam(value = "Nvalue", required = false) String[] Nvalue)
String names[] = value;
String number[] = Nvalue;
model.addAttribute("names", names);
model.addAttribute("umber", number);
<!DOCTYPE HTML>
<html>
<head>
<title>Basic HTML5 Column Chart </title>
<script type="text/javascript">
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer",
{
title:{
text: "Top Oil Reserves"
},
animationEnabled: true,
axisY: {
title: "Reserves(MMbbl)"
},
legend: {
verticalAlign: "bottom",
horizontalAlign: "center"
},
theme: "theme2",
data: [
{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "MMbbl = one million barrels",
dataPoints: [
{y: 297571, label: "Venezuela"}
]
}
]
});
chart.render();
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;">
</div>
</body>
</html>
var names=["one"," two"," tree"];
var values=[10, 20, 30];
var result=names.map(function(name,id){
return {y:values[id]||0, label:name};
});
The result is your dataPoints array.
Example:
<html>
<head>
<title>Basic HTML5 Column Chart </title>
<script type="text/javascript">
window.onload = function() {
var names = ["one", " two", " tree"];
var values = [10, 20, 30];
var result = names.map(function(name, id) {
return {
y: values[id] || 0,
label: name
};
});
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Top Oil Reserves"
},
animationEnabled: true,
axisY: {
title: "Reserves(MMbbl)"
},
legend: {
verticalAlign: "bottom",
horizontalAlign: "center"
},
theme: "theme2",
data: [
{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "MMbbl = one million barrels",
dataPoints: result
}
]
});
chart.render();
}
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/canvasjs/1.7.0/canvasjs.min.js"></script>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;">
</div>
</body>
</html>
Create a class for holding values pairs, I used Gson to transform java objects into json strings.
class DataPoint {
private String y;
private String label;
public DataPoint(String y, String label) {
super();
this.y = y;
this.label = label;
}
}
Create an helper class with a static method which converts the pair of arrays into a jsonString
public class MyHelperClass {
public static String toJson(String[] labels, String[] nums) {
Gson gson = new Gson();
List<DataPoint> data = new ArrayList<DataPoint>();
for (int i = 0; i < nums.length; i++) {
DataPoint dp = new DataPoint(nums[i], labels[i]);
data.add(dp);
}
String jsonData = gson.toJson(data);
return jsonData;
}
}
Insert the jsonString into the jsp
{
type: "column",
showInLegend: true,
legendMarkerColor: "grey",
legendText: "MMbbl = one million barrels",
dataPoints: <%= MyHelperClass.toJson(arrayA,arrayB) %>
}
Eventually you will want to create some RESTful web service instead of putting logic insde the JSP.

Chart Js not display issue: Ajax Call

I am a newbie to Chart JS library. Iam facing issues in displaying my charts automatically. The charts do no display until I click on one of them or trigger the load by using chrome developer tools. Can you help me in displaying the charts automatically without having to click ?
Thanks for your help.
The code of my page is as follows:
<!-- Layout of the different charts -->
<div class="container-fluid">
<div class="row">
<div class="col-sm-6 col-md-4">
<div class="chart-wrapper">
<div class="chart-title">
Distance totale (en mètres) par Tag
</div>
<div class="chart-stage">
<div id="grid-1-1">
<div id="chart-01"></div>
<canvas id="chart01" ></canvas>
</div>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="chart-wrapper">
<div class="chart-title">
Durée totale (en secondes) par Tag
</div>
<div class="chart-stage">
<div id="chart-02"></div>
<canvas id="chart02"></canvas>
</div>
</div>
</div>
<div class="col-sm-6 col-md-4">
<div class="chart-wrapper">
<div class="chart-title">
Nombre de Trajets par Zone
</div>
<div class="chart-stage">
<div id="chart-03"></div>
<canvas id="chart03"></canvas>
</div>
</div>
</div>
</div>
<div class="row" >
<div class="col-sm-6 col-md-4">
<div class="chart-wrapper">
<div class="chart-title">
Durée totale (en secondes) par Zone
</div>
<div class="chart-stage">
<div id="chart-04"></div>
<canvas id="chart04"></canvas>
</div>
</div>
</div>
</div>
<hr/>
</div>
<!-- The scripts to inject data in the graphs -->
<script type="text/javascript" src="js/bootstrap.min.js"></script>
<script>
var userSite = '';
var ctx1 = document.getElementById("chart01");
var ctx2 = document.getElementById("chart02");
var ctx3 = document.getElementById("chart03");
var ctx4 = document.getElementById("chart04");
var tags = [];
var tagsColor = [];
var tagsBorderColor = [];
var distances = [];
var durations = [];
var areas = [];
var nbpaths = [];
var chart01 = {};
var chart02 = {};
var chart03 = {};
var chart04 = {};
<!-- Uitlity to create colors adapted to the graphs -->
function getRandColor(){
var color = [{c:'rgba(255, 99, 132, 0.2)',b:'rgba(255,99,132,1)'},
{c:'rgba(54, 162, 235, 0.2)',b:'rgba(54, 162, 235, 1)'},
{c:'rgba(255, 206, 86, 0.2)', b:'rgba(255, 206, 86, 1)'},
{c:'rgba(75, 192, 192, 0.2)', b:'rgba(75, 192, 192, 1)'},
{c:'rgba(153, 102, 255, 0.2)',b:'rgba(153, 102, 255, 1)'},
{c:'rgba(255, 159, 64, 0.2)]',b:'rgba(255, 159, 64, 1)'}];
return color[Math.floor(Math.random()*(color.length-1))];
}
<!-- Get the specific site to feed data -->
window.onload = function() {
$.ajax({
type: 'GET',
url: 'rest/maps/sites',
dataType: 'json',
async: false,
success: function(data) {
userSite = data[0];
}
});
<!-- Calling webservices to get data -->
$.ajax({
url: 'rest/tags/' + userSite + '/chartinfos',
dataType: 'json',
success: function(response, status){
for ( i=0; i<response.length; i++){
var color = getRandColor();
tags.push(response[i].idTag);
durations.push(response[i].duration);
tagsColor.push(color.c);
tagsBorderColor.push(color.b);
distances.push(response[i].distance);
}
}
});
chart01 = new Chart(ctx1, {
type: 'bar',
data: {
labels: tags,
datasets: [{
label: 'Distance/Tag',
data: distances,
backgroundColor: tagsColor,
borderColor: tagsBorderColor,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
chart02 = new Chart(ctx2, {
type: 'bar',
data: {
labels: tags,
datasets: [{
label: 'Durée/Tag',
data: durations,
backgroundColor: tagsColor,
borderColor: tagsBorderColor,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
$.ajax({
url: 'rest/areas/' + userSite + '/chartinfos2',
dataType: 'json',
success: function(response, status){
for ( i=0; i<response.areas.length; i++){
var color = getRandColor();
areas.push(response.areas[i].idAreas);
nbpaths.push(response.areas[i].nbPaths);
tagsColor.push(color.c);
tagsBorderColor.push(color.b);
}
}
});
chart03 = new Chart(ctx3, {
type: 'bar',
data: {
labels: areas,
datasets: [{
label: 'Trajets/Zone',
data: nbpaths,
backgroundColor: tagsColor,
borderColor: tagsBorderColor,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
chart04 = new Chart(ctx4, {
type: 'bar',
data: {
labels: areas,
datasets: [{
label: 'Durée/Zone',
data: durations,
backgroundColor: tagsColor,
borderColor: tagsBorderColor,
hidden: false,
borderWidth: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
};
</script>
</body>
</html>

Generate Highchart using from date range MYSQL Ajax

I am trying to generate a bar graph using data from MYSQL through ajax by taking two input date fields from the user and returning the results using ajax.The problem is that when i select the date range, it doesn't show me anything.
I am new to Ajax as well, so any help will be appreciated.
Below is the code i have tried so far;
Thanks
<?php
$cakeDescription = "Highcharts Pie Chart";
?>
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title><?php echo $cakeDescription ?></title>
<link href="../webroot/css/cake.generic.css" type="text/css" rel="stylesheet">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
//default
var startdate = document.getElementById('startdate').value;
var enddate = document.getElementById('enddate').value;
var options = {
chart: {
renderTo: 'container',
type: 'column'
},
title: {
text: 'Highcharts Chart PHP with MySQL Example',
x: -20 //center
},
subtitle: {
text: 'Sumber : Jabatan XYZ',
x: -20
},
xAxis: {
categories: []
},
yAxis: {
title: {
text: 'Jumlah Pelawat'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
headerFormat: '<span style="font-size:11px">{series.name}</span><br>',
pointFormat: '<span style="color:{point.color}">{point.name}</span>:<b>{point.y}</b> of total<br/>'
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
format: '{point.y}'
}
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -40,
y: 100,
floating: true,
borderWidth: 1,
shadow: true
},
series: []
};
function getAjaxData(startdate,enddate) {
$.getJSON("data.php", function(json) {
options.xAxis.categories = json[0]['data']; //xAxis: {categories: []}
options.series[0] = json[1];
chart = new Highcharts.Chart(options);
});
}
});
</script>
<script src="http://code.highcharts.com/highcharts.js"></script>
<script src="http://code.highcharts.com/modules/exporting.js"></script>
</head>
<body>
<a class="link_header" href="/highcharts/"><< Back to index</a>
<div class="menu_top" >
<input type="date" id="startdate" name="startddate">
<input type="date" id="enddate" name="enddate">
</div>
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto;"></div>
</body>
</html>
Below is my data.phpfile,
<?php
#Basic Line
require '../../conn/connection.php';
$id = $_GET['id'];
$startdate = $_GET['startdate'];
$enddate = $_GET['enddate'];
$result = mysql_query("SELECT DISTINCT(membername), COUNT(membername)
AS member
FROM responses WHERE timerecorded>=" . $startdate . " AND timerecorded<=" . $enddate . " GROUP BY membername");
$bln = array();
$bln['name'] = 'Bulan';
$rows['name'] = 'Jumlah Pelawat';
while ($r = mysql_fetch_array($result)) {
$bln['data'][] = $r['membername'];
$rows['data'][] = $r['member'];
}
$rslt = array();
array_push($rslt, $bln);
array_push($rslt, $rows);
print json_encode($rslt, JSON_NUMERIC_CHECK);
mysql_close($con);

Resources