Zing feed plotting multiple series in 1 chart - javascript

I am trying to plot 2 line series data in ZingChart feed.
Below is my script code.
<script>
var chartData = {
"type":"line",
"refresh": {
"type": "feed",
"transport": "js",
"url": "feed()",
"interval": 1000
},
"series":[
{
"values":[]
},
{
"values":[]
}
]
};
window.onload = function() {
zingchart.render({
id: "chartDiv",
data: chartData,
height: 600,
width: "100%"
});
};
window.feed = function(callback) {
$.ajax({
type: "GET",
dataType: "json",
headers: {
Accept: "application/json",
"Access-Control-Allow-Origin": "*"
},
url: "/PerformanceMonitor/showProcessUsage/${processName}",
success: function (data) {
var mem = data.mem.size/100000;
var tick = {
plot0: parseInt(mem)
};
callback(JSON.stringify(tick));
var tick2 = {
plot1:parseInt(mem/1000)
};
callback(JSON.stringify(tick2));
}
});
};
It gets displayed , but looses the line nature of the graph.Is this the right way ?Is there a better method?. Later I am planning to let user decide how many plots to be allowed in chart at runtime.Is there something in ZingChart that I can make use of ?
Thanks in advance.

The tick object contains the data for each series of a plot. That means you can add multiple plots to that object.
You can replace everything in your success callback with the following code...
var mem = data.mem.size/100000;
var tick = {
plot0: parseInt(mem),
plot1: parseInt(mem/1000)
};
callback(JSON.stringify(tick));
If you wanted to add a third plot to the series, you'd just add a plot2 attribute (since ZingChart's series have a 0-based index).
I'm on the ZingChart team. Let me know if you have other questions.

Related

How to Stop Chart.js Rendering Over Previous Chart

I've put together some code which allows me to query a MySQL database, return the result and populate a chart.js. The problem being that each time the AJAX code runs the chart is rendered over the previous one. I've read through a few similar stackoverflow queries which are recommending the use of myChart.destroy(); or other solutions but I' struggling to work out where this should be inserted into the following code.
Note that I've simplified the code below for simplicity sake.
Any assistance on how to stop this chart 'ghosting' occuring would be greatly appreciated.
<script type="text/javascript">
jQuery(document).ready( function($) {
var valueCheck;
jQuery('#afl_player_year').on( 'change', function () {
afl_player_year = $('#afl_player_year').val();
jQuery.ajax({
type: "POST",
url: "/wp-admin/admin-ajax.php",
dataType: "json",
data: {
action: 'call_player_chart_data',
afl_player_year: afl_player_year,
},
success:function(output){
var y_data1 = output[0];
var y_data2 = output[1];
var x_time = ............
new Chart(document.getElementById("myChart"), {
type: 'bar',
data: {
labels: x_time,
datasets: [{.........
}, {.........
}]
},
options: {
scales: {.........
yAxes: [{.........},{.........},
}]
}
}
});
}
});
}).change();
});
</script>

How to properly code Javascript / Ajax for use with Chart.js

I have a controller action in my MVC project that creates a json record with the components needed. This is working. The issue I am having is bringing it into a chart.js canvas. This will be a pie chart that shows all the related countries with a count of each. Json has this info. Originally this was setup to use google visualization but I want to use chart.js. I just started using it. Creating charts with static data is no issue but I am pulling the info from a SQL table and creating a json to read from.
I have tried using the same structure and calling the data: data[] but it doesn't work I have also tried data: getData, which is a var for the ajax function. I am getting the data per the council on refresh.
Here is my controller Action
public ActionResult CustomersByCountry()
{
CustomerEntities _context = new CustomerEntities();
var customerByCountry = (from c in _context.Addresses
group c by c.Country into g
orderby g.Count() descending
select new
{
Country = g.Key,
CountCustomer = g.Count()
}).ToList();
return Json(new { result = customerByCountry }, JsonRequestBehavior.AllowGet);
}
And here is the JavaScript/ajax - which is nested in a document.ready function with the rest of the charts.
EDIT - changed Ajax - Still not working
OrdersByCountry()
function OrdersByCountry() {
$.ajax({
url: '/admin/CustomersByCountry',
method: "GET",
dataType: "json",
error: function (_, err) {
console.log(_, err)
},
success: function (data) {
console.log (data);
var customer = $("#customerByCountryPieChart").get(0).getContext("2d");
console.log(customer)
var cpieChart = new Chart(customer, {
type: 'pie',
data: data,
options: {
responsive: true,
title: {
display: true,
text: "Customers By Country",
}
}
});
}
});
};
Edit - The now working code is below.
I changed it to get states instead of country, just to clear up possible confusion. It made more sense to me to get States rather than Country at this point. This is working - meaning displaying the graph, I still need to work on the labels etc.
OrdersByStates()
function OrdersByStates() {
$.ajax({
url: '#Url.Action("CustomersByStates", "Admin")',
data: JSON,
contentType: "application/json; charset=utf-8",
method: "get",
dataType: "json",
error: function (_, err) {
console.log(_, err)
},
success: function (response) {
console.log(response);
var jsonresult = response
var labels = jsonresult.result.map(function (e) {
return e.State;
});
var data = jsonresult.result.map(function (e) {
return e.CountCustomer;
});;
var ctx = document.getElementById("CustomerByStatePieChart").getContext("2d");
var cpieChart = new Chart(ctx, {
type: 'pie',
data:
{
datasets: [
{
backgroundColor: ["#46BFBD", "#F7464A"],
hoverBackgroundColor: ["#5AD3D1", "#FF5A5E"],
label: "Orders",
data: data,
}]
},
options: {
responsive: true,
title: {
display: true,
text: "Customers By Country",
}
}
});
}
});
};
});
try:
var cpieChart = new Chart(customer, {
type: 'pie',
data: data.result,
options: {
responsive: true,
title: {
display: true,
text: "Customers By Country",
}
}
});
the response from the server "data" var on your request is {result: LIST}

JQuery DataTables Columns Initializing automatically with data

I have a JQuery DataTable and I have been using it for a while, I guess I am missing something here.
However I came into one of the requirement recently to directly bind with JSON Data.
My JSON for example looks like i.e. coming from API :
[{"componentNumber":"ABC","factory":"India","productNumber":"CR","productRevisionState":"123","placementTimeLocal":"2018-08-21T00:00:00","position":"up"},{"componentNumber":"ABC","factory":"India","productNumber":"CR","productRevisionState":"123","placementTimeLocal":"2018-08-21T00:00:00","position":"up"},
{"componentNumber":"ABC","factory":"India","productNumber":"CR","productRevisionState":"123","placementTimeLocal":"2018-08-21T00:00:00","position":"up"}]
I know that I can use JSON and take columns out in Jquery and pass it to the Datatables columns but what I am looking if there is a simple way where Datatable takes column automatically something like:
$.ajax({
type: "Post",
url: "http://localhost:5555/myapi",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
//datasource = data;
$('#myTable').DataTable({
"Data": JSON.parse(data),
"Columns" : JSON.parse(data)
});
},
error: function (err) {
alert(err);
}
})
What I am looking is that:
Does JQuery have any such features or not? If not can you suggest
any other Datatable library which is fast for large dataset.
I want to get rid of all extra looping around the code
I can't update source system from where data is getting returned
Updated Version of Code, took from below answers, thanks Kiran for making me move a bit:
$.ajax({
type: "Post",
url: "http://localhost:5555/myapi",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
// **how to get rid of this loop? for looping columns**
var adColumns = [];
$.each(data[0], function (i, item) {
var col = {
data: i,
title: i
};
adColumns.push(col);
})
//datasource = data;
console.log(data);
$('#myTable').DataTable({
"data": data,
"info": true,
"paging": true,
"columns": adColumns
});
},
error: function (err) {
alert(err);
}
})
try the following code. It may help you to achieve the desired result. This may not be an optimized code.
Hope this helps.
EDIT
At least one loop will be required to create the array of column names.So you can also use the following code to eliminate multiple loops.
var adColumns = [];
Object.keys(strData[0]).forEach(key => {
var col = {
data: key,
title: key
};
adColumns.push(col);
});
$(function() {
var strData = [{
"componentNumber": "ABC",
"factory": "India",
"productNumber": "CR",
"productRevisionState": "123",
"placementTimeLocal": "2018-08-21T00:00:00",
"position": "up"
}, {
"componentNumber": "ABC",
"factory": "India",
"productNumber": "CR",
"productRevisionState": "123",
"placementTimeLocal": "2018-08-21T00:00:00",
"position": "up"
},
{
"componentNumber": "ABC",
"factory": "India",
"productNumber": "CR",
"productRevisionState": "123",
"placementTimeLocal": "2018-08-21T00:00:00",
"position": "up"
}
];
/*var dta = strData;
var tableColumnNames = [];
var keys = [];
for (var i in strData) {
var key = i;
var val = strData[i];
for (var j in val) {
var sub_key = j;
keys.push(sub_key);
}
}
var sColumns = Array.from(new Set(keys));
var adColumns = [];
for (var col in sColumns) {
var sKey = sColumns[col];
var col = {
data: sKey,
title: sKey
};
adColumns.push(col);
}*/
var adColumns = [];
Object.keys(strData[0]).forEach(key => {
var col = {
data: key,
title: key
};
adColumns.push(col);
});
$('#myTable').DataTable({
"data": strData,
"columns": JSON.parse(JSON.stringify(adColumns))
});
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.19/css/jquery.dataTables.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="myTable">
</table>
DataTables has the ability to read data from virtually any JSON data source that can be obtained by Ajax. This can be done, in its most simple form, by setting the ajax option to the address of the JSON data source. See This Link in DataTable Website.
As for your JSON, here is a fiddle

How to make this code more simple or shorten?

I have this code below for displaying a chart. My problem here is that the labels and datasets are static not dynamic. Can this be possible to make dyanmic?.
var globalNewData = "";
function ChartDataLabel() {
var barChartData = {
labels: [globalNewData[0]["CandidateName"], globalNewData[1]["CandidateName"],
globalNewData[2]["CandidateName"], globalNewData[3]["CandidateName"],
globalNewData[4]["CandidateName"]],
datasets: [{
fillColor: "rgba(0,100,0,1)",
strokeColor: "black",
data: [globalNewData[0]["Votes"], globalNewData[1]["Votes"], globalNewData[2]["Votes"],
globalNewData[3]["Votes"], globalNewData[4]["Votes"]] // Votes = Number of Votes
}]
}
//var index = 11;
var ctx = document.getElementById("canvas").getContext("2d");
var barChartDemo = new Chart(ctx).Bar(barChartData, {
responsive: true,
barValueSpacing: 2
});
}
NewData();
function NewData() {
var url = '../Controller/_NewData'
var res = "";
$.ajax({
type: "POST",
url: url,
dataType: 'json',
// async: false,
success: function (response) {
var Data = response.data;
globalNewData = Data;
ChartDataLabel();
},
error: function (response) {
alert("error");
alert(response);
}
});
}
Controller
public JsonResult _NewData()
{
var Data = new List<object>();
Data = (from a in db.Testings
select new
{
TestID = a.TestID,
CandidateName = a.Candidatename,
Position = a.Position,
Votes = a.NoOfVotes
}).ToList<object>();
return Json(new
{
data = Data
}, JsonRequestBehavior.AllowGet);
}
What I mean in Static is as you can see in the chart code [globalNewData[0]["CandidateName"] It is fix(5) in how many data will be display in the chart. In Dynamic even it add new data it will add the array inside [6]... for example.
Any suggestion will be accepted.
You could map new arrays for labels and dataset data
Something like:
function ChartDataLabel(chartData) {
var barChartData = {
labels: chartData.labels,// reference to labels array created below
datasets: [{
fillColor: "rgba(0,100,0,1)",
strokeColor: "black",
data: chartData.points // reference to points array created below
}]
}
//var index = 11;
var ctx = document.getElementById("canvas").getContext("2d");
var barChartDemo = new Chart(ctx).Bar(barChartData, {
responsive: true,
barValueSpacing: 2
});
}
$.ajax({
...
success: function (response) {
// object with new arrays need to pass to charting function
var chartData ={
labels:[],
points:[]
}
// loop through response data and add to each of labels and points arrays
response.data.forEach(function(item){
chartData.labels.push(item.CandidateName);
chartData.points.push(item.Votes);
})
// pass chartData into function
ChartDataLabel(chartData);
}
})
There are numerous other methods that could be used to map these new arrays also that would reduce code needed even more. I used a longer method for better understanding
Alternative would be to do this mapping on server and send data from server so response.data contains the labels and points arrays needed

Redraw Morris Donut after AJAX call

I'm using Morris Donut for a dashboard I'm working on and retrieving data via AJAX using two date ranges as parameters. The problem I'm facing is when I enter two new date ranges the Donut Chart renders a new one on top of Donut already created upon page load. I've searched about and can see information on using setData(), but I have no idea how to include this within my code.
My Code:
$(document).ready(function () {
var start = $('#SearchStart').val();
var end = $('#SearchEnd').val();
populateDonut(start, end);
});
The search button does the following when clicked:
$('#DateRange').click(function() {
var start = $('#SearchStart').val();
var end = $('#SearchEnd').val();
populateDonut(start, end);
});
Here is the function that is called.
function populateDonut(start, end) {
var param = { start: start, end: end };
$.ajax({
type: "POST",
url: "/WebService.asmx/getDonutData",
contentType: "application/json; charset=utf-8",
dataType: 'json',
async: true,
data: JSON.stringify(param),
success: function (result) {
var data = eval("(" + result.d + ")");
var pieChart = '';
if (data.status == 0) {
var donut = Morris.Donut({
element: 'pieChart',
data: [
{ label: "Inbound", value: data.inbound },
{ label: "Outbound", value: data.outbound },
{ label: "Unanswered", value: data.unanswered }
],
colors: ['#1ca8dd', '#33b86c', '#ebc142'],
resize: true,
formatter: function (x) { return x + "%" }
});
}
}
});
}
Screenshot of what is happening after entering new date ranges:
Try calling $("#pieChart").empty(); before rendering the second chart.
Preferably in here:
$('#DateRange').click(function() {
var start = $('#SearchStart').val();
var end = $('#SearchEnd').val();
// Clear the existing chart before populating new donut
$("#pieChart").empty();
populateDonut(start, end);
});
I tried the below code and it's working with me :
$("#chart-id").empty();
You can use it on each time you call chart data .

Categories