Unable to populate Highchart at runtime using json data - javascript

I am trying to populate highchart by sending data through servlet . My servlet is like:
package com.sandeep.visual.servlet;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.gson.Gson;
import com.sandeep.visual.data.Student;
#WebServlet("/StudentJsonDataServlet")
public class StudentJsonDataServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
public StudentJsonDataServlet() {
super();
}
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
List<Student> listOfStudent = getStudentData();
Gson gson = new Gson();
String jsonString = gson.toJson(listOfStudent);
response.setContentType("application/json");
response.getWriter().write(jsonString);
}
private List<Student> getStudentData() {
List<Student> listOfStudent = new ArrayList<Student>();
Student s1 = new Student();
s1.setName("Sandeep");
s1.setComputerMark(75);
s1.setMathematicsMark(26);
listOfStudent.add(s1);
Student s2 = new Student();
s2.setName("Bapi");
s2.setComputerMark(60);
s2.setMathematicsMark(63);
listOfStudent.add(s2);
Student s3 = new Student();
s3.setName("Raja");
s3.setComputerMark(40);
s3.setMathematicsMark(45);
listOfStudent.add(s3);
Student s4 = new Student();
s4.setName("Sonu");
s4.setMathematicsMark(29);
s4.setComputerMark(78);
listOfStudent.add(s4);
return listOfStudent;
}
}
And I am able to get the desired json in my html page as:
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Dynamic HighChart</title>
<script type="text/javascript" src="./js/jquery.min_1.8.2.js"></script>
</head>
<body>
<script src="http://code.highcharts.com/highcharts.js"></script>
<div id="container" style="height: 400px"></div>
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
type: "GET",
url: 'StudentJsonDataServlet',
dataType: "json",
contentType: "application/json",
crossDomain: true,
success: function (data) {
console.log(data);
// Populate series
var nameArr = new Array();
var processed_json = new Array();
for (i = 0; i < data.length; i++) {
nameArr.push([data[i].name]);
processed_json.push([parseInt(data[i].mathematicsMark),parseInt(data[i].computerMark)]);
}
console.log("name array : " + nameArr);
console.log("FinalArray : " + processed_json);
// draw chart
$('#container').highcharts({
chart: {
type: "line"
},
title: {
text: "Marks obtained"
},
xAxis: {
categories: [nameArr]
},
yAxis: {
title: {
text: "Marks obtained"
}
},
series: [{
name: nameArr,
data: processed_json
}]
});
}
});
});
</script>
</body>
</html>
Now the best thing is that I am able to populate the HighChart but it doesn't appear as I want it to.
I have tried the same above example using google chart and I am getting something like this:
Which is my intended result what I want to get.
But with highchart I am getting something like this:
How can I achieve the same result shown in picture 1 through highChart.
Looking forward to your solutions. Thanks in advance.

To achieve that result, you need to create two series in the beginning:
var series = [{
name: "Mathematics mark",
data: []
}, {
name: "Computer mark",
data: []
}];
Now, add points (marks) to these series:
$.each(data, function(i, point) {
series[0].data.push([
point.name,
parseInt(point.mathematicsMark)
]);
series[1].data.push([
point.name,
parseInt(point.computerMark)
]);
});
Now, set xAxis.type as category, so points' names will be used as xAxis labels:
$('#container').highcharts({
xAxis: {
type: 'category'
},
series: series
});
Working demo: https://jsfiddle.net/sg9rghyg/

Here is working fiddle
Update as per JSON shared , below is complete code:
var seriesData=[];
var data =[{"name":"Sandeep","mathematicsMark":26,"computerMark":75}, {"name":"Bapi","mathematicsMark":63,"computerMark":60},{"name":"Raja","mathematicsMark":45,"computerMark":40},{"name":"Sonu","mathematicsMark":29,"computerMark":78}] ;
$.each (data, function(i){
seriesData.push({name:data[i].name,data: [parseInt(data[i].mathematicsMark),parseInt(data[i].computerMark)]});
}) ;
Use this seriesData in chart
Instead of separate arrays of names and data
[{
name: nameArr,
data: processed_json
}]
Do As below:
[{
name: data[i].name,
data: [parseInt(data[i].mathematicsMark),parseInt(data[i].computerMark)] // or your processed_json
}]

Related

handle click event on item in listbox

I have some line chart which gets data from controller.Also I have Methods ListBox with with some SelectListItem items. When I click on any of these items in Listbox I get graphId and then it pass to controller to "Coordinates" method and this method creates dataCoord list with (x,y) coordinates. So question is how do I modify my script to pass this dataCoord list to my line chart by clicking on any item in Method ListBox
here is Coordinates method:
public JsonResult Coordinates(int graphId)
{
List<DataPoint> dataCoords = new List<DataPoint> { };
string exp = "GRAPHIC_ID = " + graphId;
DataRow[] foundrows;
foundrows = oraVars.Ds.Tables["COORDS"].Select(exp);
for (int i = 0; i < foundrows.Length; i++)
{
double x = Convert.ToDouble(foundrows[i].ItemArray[1]);
double y = Convert.ToDouble(foundrows[i].ItemArray[2]);
dataCoords.Add(new DataPoint(x, y));
}
return Json(dataCoords, JsonRequestBehavior.AllowGet);
}
here is script in view:
$(document).ready(function () {
$("#MethodsListBoxValues").change(function () {
$.ajax({
type: 'POST',
url: '#Url.Action("coordinates")',
dataType: 'json',
data: { graphId: $("#GraphicListBoxValues").val() },
"how to modify script?"
error: function (ex) {
alert('Failed.' + ex);
}
});
return false;
})
});
here is line chart script:
window.onload = function () {
var chart = new CanvasJS.Chart("chartContainer", {
theme: "light2",
animationEnabled: true,
title: {
text: "Simple Column Chart in ASP.NET MVC"
},
subtitles: [
{ text: "Try Resizing the Browser" }
],
data: [
{
type: "line", //change type to bar, line, area, pie, etc
dataPoints:#Html.Raw(ViewBag.DataPoints),
}
]
});
chart.render();
};

No data is displayed with ExtJS and C#

I have a problem with ExtJS and c# does not show me any data only header, I just want to show the records of my sql table, but I could not, my backend works fine and if it returns the records of my BD, the problem is that it does not they are binding, reason why I believe that my JS file is bad and did not find the error so that the registers are shown.
data that return GetCustomer method
app.js:
Ext.require([
'Ext.grid.*',
'Ext.data.*',
'Ext.panel.*',
'Ext.util.*'
]);
Ext.application({
name: 'Fiddle',
launch: function () {
var myStore = new Ext.data.JsonStore({
// Load data at once
autoLoad: true,
// Override default http proxy settings
proxy: new Ext.data.HttpProxy({
pageParam: false, //to remove param "page"
startParam: false, //to remove param "start"
limitParam: false, //to remove param "limit"
noCache: false, //to remove param "_dc"
// Call web service method using GET syntax
url: 'GetCustomers',
// Ask for Json response
headers: {
'Content-type': 'application/json'
}
}),
// Root variable
root: 'data',
// Record identifier
id: 'EmpleadoId',
//reader:Jreader,
// Fields declaration
fields: ['EmpleadoId', 'NombreEmpleado', 'DirectorId'],
});
var grid = new Ext.grid.GridPanel({
// Set store
store: myStore,
// Columns definition
columns: [{
dataIndex: 'EmpleadoId',
header: 'Empleado Id'
}, {
dataIndex: 'NombreEmpleado',
header: 'Nombre Empleado'
}, {
dataIndex: 'DirectorId',
header: 'Director Id'
}],
// Render grid to dom element with id set to panel
renderTo: 'whitespace',
width: 422,
height: 300
});
}
});
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="~/Content/charts-all.css" rel="stylesheet" />
<script src="~/Scripts/ext-all.js"></script>
<script src="~/Scripts/app.js"></script>
</head>
<body>
<div id="whitespace"></div>
<div>
</div>
</body>
</html>
Controller:
public JsonResult GetCustomers()
{
List<Empleados> lstPersona = new List<Empleados>();
SqlConnection con = new SqlConnection("Server=PC;Database=TestPersona;Trusted_Connection=yes;");
SqlCommand cmd = new SqlCommand("SELECT EmpleadoId,NombreEmpleado,DirectorId FROM Empleados", con);
cmd.CommandType = CommandType.Text;
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
Empleados emp = new Empleados();
emp.EmpleadoId = Convert.ToInt16(dr["EmpleadoId"]);
emp.NombreEmpleado = dr["NombreEmpleado"].ToString();
emp.DirectorId = Convert.ToInt16(dr["DirectorId"]);
lstPersona.Add(emp);
}
con.Close();
JsonResult res = Json(new { data = lstPersona }, JsonRequestBehavior.AllowGet);
return res;
}

Using data from API with Chart JS

I am getting data from an api and then reformatting part of it into an array using .map(), I am successfully able to do this, but when it comes time to pass it into Chart JS as data it does work. I am able to pass in a normal, hard coded, array but not my own data...
I tried using an Angular directive (NG2-Charts) to help out thinking maybe that was the problem, but that doesn't work either...
Component.ts:
... Other variable and stuff up here...
getStockData() {
this.stocksService.getStockData()
.subscribe(
(response) => {
for(var i = 0; i < response.length; i++) {
this.stockOpen.push(response[i]['open']);
}
console.log('after loop: ', this.stockOpen);
},
(error) => console.error(error)
);
console.log('real: ', this.stockOpen);
console.log('test: ', this.testData);
}
// Chart JS version
buildStockChart() {
var ctx = document.querySelector("#chart");
this.chart = new Chart(ctx, {
type: 'bar',
data: {
labels: [1,2,3,4,5],
datasets: [
{
data: this.stockOpen,
borderColor: "#3cba9f",
fill: false
}
]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
}
}
});
}
// NG2-Charts version
public lineChartData:Array<any> = [
{data: this.testData},
];
public lineChartLabels:Array<any> = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
public lineChartOptions:any = {
responsive: true
};
Result from console.log():
i also have same problem with chart JS on angular so i force to use another chart.
im now using angular 2 chart js.
i think the problem here is the delay of data fetch by API, the CHART component is already render on html view but the data is still not fetch by the API service.
try to add this code on your code block. This will handle the data if API service data is available.
()=>{this.buildStockChart();}
this.stocksService.getStockData()
.subscribe(
(response) => {
for(var i = 0; i < response.length; i++) {
this.stockOpen.push(response[i]['open']);
}
console.log('after loop: ', this.stockOpen);
},
()=>{
this.buildStockChart();
}
);
console.log('real: ', this.stockOpen);
console.log('test: ', this.testData);
}
This chart is easy to manage for dynamic instances.
Hope this chart will work on you.
https://www.npmjs.com/package/angular2-chartjs
When are you calling the buildStockChart() method?
You should call it right after the for loop into the callback you pass to the subscribe method, since that's the moment when this.stockOpen is populated (before that moment it will be empty as you are seeing in the console).
As #Joseph Agbing, I was unable to get it work with angular 7. I'm now using chart.js only
npm install chart.js --save
with into my someChart.component.html
<div style="display: block"><!--Mandatory div including chart-->
<canvas id="canvas">{{chart}}</canvas>
</div>
into my someChart.component.ts
called from my httpClient.post(...).subscribe(lData => (setChartDataFromEntities(lDataProcessed), ...)
import { Chart } from 'chart.js';
export class someClass {
/**
*
* #param aDate
* #param aChargeUnitArray
*/
setChartDataFromEntities( aDate: Date, aChargeUnitArray: ChargeUnit[] ){
console.debug('setChartDataFromEntities->', aChargeUnitArray)
let lChartDataArray = []
let lChartDataLineDataArray: Array<Number> = []
let lChartLabelsArray: string[] = []
let l_s: string
aChargeUnitArray.forEach(element => {
lChartDataLineDataArray.push(element.charge)
lChartLabelsArray.push(MiscHelper.dateTimeHMSForChart(element.timestamp))
});
lChartDataArray.push(
{
data: lChartDataLineDataArray,
label: MiscHelper.dateForGui(aDate),
}
)
this.chart = new Chart('canvas', {
type: 'line',
data: {
labels: lChartLabelsArray,
datasets: lChartDataArray
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
}
}
});
this.statusMessage = 'Chart loaded'
}
hope it helps somebody more than the day I wasted trying to get it work...

Google chart: “Uncaught (in promise) Error: Unknown header type: 4.7278” error

I'm trying to display a line chart of currency rates via google charts.
Basically i have 2 type of values:
Date (format iso8601)
Rate (decimal number)
when i'm trying to render the chart i get an error: "Uncaught (in promise) Error: Unknown header type: 4.7278”
Here is my code:
PHP array making:
$xml=simplexml_load_file('https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/usd.xml') or die("Error: Cannot create object");
$arrayForChart[] = ["Date","Rate"];
foreach ($xml->DataSet->Series->Obs as $key => $value) {
$dateIso8601Format=(string)$value['TIME_PERIOD'];
$rateForDate=(string)$value['OBS_VALUE'][0];
$rateForDate=(float)$rateForDate;
$arrayForChart[] = [$dateIso8601Format,$rateForDate];
}
$arrayForChart = json_encode($arrayForChart);
Javascript
var arrayForChart;
$.ajax({
type: "POST",
url: ajaxUrl,
//data: {configuration: Config },
success: function (data) {
arrayForChart = data;
arrayForChart = $.map(arrayForChart, function (el) {
return el;
});//converting js object to js array
},
cache: false
});
google.charts.load("current", {packages: ["corechart", "line"]});
google.charts.setOnLoadCallback(drawLineColors);
function drawLineColors() {
var data = google.visualization.arrayToDataTable([arrayForChart]);
var options = {
hAxis: {
title: "Rate",
id: "Rate",
label: "Rate",
type: "number"
},
vAxis: {
title: "Date",
id: "Date",
label: "Date",
type: "string"
},
colors: ["#a52714", "#097138"]
};
var chart = new google.visualization.LineChart(document.getElementById("chart_div"));
chart.draw(data, options);
}
Sample of data:
["Date","Rate","2011-01-03",4.7278,"2011-01-04",4.7301,"2011-01-05",4.6814,"2011-01-06",4.6635]
Anybody might know what is the problem?
Many thanks!
Google charts expects an array of arrays. You appear to be providing it with one flat away. Eg
Array('date', 'value', 1,2,3,4);
Should be
Array(
Array(date, value),
Array(1, 2),
Array(3, 4)
);
Faced Same issue in ASP.Net resolved by changing this
chartData.Add(new object[] { "Post", "Total" });
Mistake you are doing is you are giving rows but not header/column name
**List<object> chartData = new List<object>();
chartData.Add(new object[]
{
"Post", "Total"
});
foreach (DataRow dtrow in dt.Rows)
{
chartData.Add(new object[]
{
dtrow[0].ToString(), Convert.ToInt32(dtrow[1])
});
}**
don't forget to add a comma right after you define the column names. That was the problem in my case.
function drawChart1() {
var data = new google.visualization.arrayToDataTable([
['Month', 'Total claims'],
<?php
if(mysqli_num_rows($sqlclaims) > 0){
while ($row = mysqli_fetch_assoc($sqlclaims)){
echo "['".$row['FINANCIAL_']."', ".$row['tot_claims']."],";
}
}
?>
]);
I had the same issue with angular-google-charts.
The component was initialized with empty array, then it was passed when the data is ready.
I solved it using *ngIf on the chart component with a flag set to false, and set it to true when the data is ready.

sending json data to a grid

I want to send the firstname mike using json to an extjs grid, that reads json.However my knowledge in Json is limited,i don't know how to create the string firstname in json and i'm failing to achieve it.Any help please on how to do so?
//java code
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServlet;
import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import net.sf.json.JSON;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
public class JsonForm extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
}
//grid
Ext.onReady(function(){
Ext.define('Employee',{
extend: 'Ext.data.Model',
proxy: {
type: 'ajax',
reader: 'json'
},
fields: [{
name: 'FirstName',
type: 'string'
}]
});
var gridStore = Ext.create('Ext.data.XmlStore', {
model: 'Employee',
autoLoad: true,
proxy: {
type: 'ajax',
url: '',
reader: {
type: 'json',
root: ''
}
}
});
grid = Ext.create('Ext.grid.Panel', {
store: gridStore,
columnLines: true,
frame: true,
columns: [
{text: "First Name", flex:1, dataIndex: 'FirstName', tdCls: 'no-dirty'},
],
renderTo:Ext.getBody(),
width: '100%',
height: 650
});
});
I believe dataIndex value you have is not correct, you should use field's property name as the value for dataIndex.
dataIndex:'name' instead of what you have..
Take a look at this page from their docs, it might help more
http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.grid.Panel

Categories

Resources