Highcharts series data from JSON object - json

I am new to JSON and mvc so here is my issue. I am currently working on graphs using highcharts. I have a controller which returns a JSON object.
public JsonResult _GetChart_TrendPublicationTypeDetailed_Data(int
yearToDisplay)
{
//Types of publications to be considered
string[] publication_types = new string[] { "article", "book", "book_section", "conference_proceedings" };
//Get the list of outputs with usp authors
var uspPubs = _uspAuthoredPublications();
//List of years for which to display the data
List<int> yearRange = _getListOfYears(yearToDisplay, yearRangeFactor_10);
//Get the data
var data = from eprint_summary in localDB.Summary
where
eprint_summary.Year > (yearToDisplay - yearRangeFactor_10)
&& eprint_summary.Year <= yearToDisplay
&& publication_types.Contains(eprint_summary.TypeCode)
&& uspPubs.Contains(eprint_summary.EprintId)
//&& eprint_summary.refereed == "TRUE" //TODO: Confirm whether we need this filter in our counts
group eprint_summary by new { eprint_summary.Year, eprint_summary.TypeDesc } into typeTrend
orderby typeTrend.Key.Year, typeTrend.Key.TypeDesc
select new
{
Year = typeTrend.Key.Year,
Type = typeTrend.Key.TypeDesc,
Count = typeTrend.Count()
};
//Extract the series data
List<object> countData = new List<object>();
foreach (var item in data.ToList().Select(y => y.Type).Distinct().OrderBy(y => y))
{
List<int> yearlyData = new List<int>();
foreach (var year in yearRange)
{
var rec = data
.Where(y => y.Type == item)
.Where(y => y.Year == year)
.Select(y => y.Count).ToArray();
yearlyData.Add(
rec == null || rec.Length == 0 ? 0 : rec[0]
);
}
countData.Add(
new
{
name = item, //Name of the series
data = yearlyData.ToArray() //Array of data
}
);
}
//Form the json object using the series data and labels
return Json(
new
{
labels = yearRange.ToArray(),
series = countData
},
JsonRequestBehavior.AllowGet
);
}
The above is my JSON in controller.
I have my view as below where I am getting the JSON object but I do not know how to append to my graph as series. How would I convert the JSON object to something that the series accepts.
var seriesData = ' ';
var test = ' ';
function ajaxCall() {
$.ajax({
type: "post",
datatype: "Json",
async: true,
url: '#Url.Action("_GetChart_TrendPublicationTypeDetailed_Data", "ResearchCharts")',
data: { yearToDisplay: '#(DateTime.Now.AddYears(-1).Year.ToString())' },
success: function (data) {
seriesData = data;
test = seriesData.series;
//bindChart(test);
//alert(JSON.stringify(seriesData));
alert(JSON.stringify(test));
},
error: function () {
alert("An error occurred.");
}
});
}
//functions call
ajaxCall();
bindChart(test);
function bindChart(test) {
var test2 = [{ "name": "Book", "data": [14, 17, 9, 10, 6, 19, 6, 8, 0, 4] }, { "name": "Book Chapter", "data": [65, 74, 44, 66, 9, 23, 36, 51, 53, 36] }, { "name": "Conference Proceedings", "data": [15, 17, 27, 30, 28, 54, 35, 43, 50, 35] }, { "name": "Journal Article", "data": [178, 162, 133, 139, 133, 191, 160, 194, 149, 169] }];
$('#chartTrendsPublicationTypeDetailed').highcharts({
chart: {
type: 'line'
},
title: {
text: 'My data'
},
xAxis: {
categories: ['2007', '2008', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016']
},
series: test2//[{ "name": "Book", "data": [14, 17, 9, 10, 6, 19, 6, 8, 0, 4] }, { "name": "Book Chapter", "data": [65, 74, 44, 66, 9, 23, 36, 51, 53, 36] }, { "name": "Conference Proceedings", "data": [15, 17, 27, 30, 28, 54, 35, 43, 50, 35] }, { "name": "Journal Article", "data": [178, 162, 133, 139, 133, 191, 160, 194, 149, 169] }]
});
Please help, just need to somehow pass the data to highcharts.
in the picture, I have added the series manually and it works, but I need to pass in a variable which the series property accepts.

Old Highcharts rendering code:
$('#chartTrendsPublicationRankDetailed').highcharts({
chart: {
type: 'line'
},
title: {
text: 'My data'
},
xAxis: {
categories: labels
},
series: seriesData
});
New Highcharts rendering code. This accepts my JSON objects successfully and renders the graphs.
function bindChartItemType(seriesData, labels) {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'chartTrendsPublicationTypeDetailed',
type: 'line',
height: 500,
width: 500
},
credits: {
enabled: false
},
title: {
text: 'Trend of Publications by Item Type'
},
xAxis: {
categories: labels,
title: {
text: '<b>Year</b>'
}
},
yAxis: {
min:0,
title: {
text: '<b># of publications</b>'
}
},
series: seriesData
});
}
Feel free to add anything you like in the comments.
Regards
Shafraz Buksh

Related

Apex charts in Angular 9

I have some problem using apex charts in angular 9, essentially I'm able to see the chart (line chart) when I mock the data as in the first screenshot, but I can't get data from REST API, I mean the chart disappears.
mocked datas
This is the method containing the chart:
drawGraph(){
this.projectService.getLineChartData(this.getID()).then((data) =>{
for(let i = 0; i<data.resourceListSize; i++){
this.chartOptions = {
series: [
{
name: "data",
data: [28, 29, 33, 36, 32, 32, 33]
},
{
name: "Low - 2013",
data: [12, 11, 14, 18, 17, 13, 13]
}
],
chart: {
height: 350,
type: "line",
dropShadow: {
enabled: true,
color: "#000",
top: 18,
left: 7,
blur: 10,
opacity: 0.2
},
toolbar: {
show: false
}
},
colors: ["#77B6EA", "#545454"],
dataLabels: {
enabled: true
},
stroke: {
curve: "smooth"
},
title: {
text: "Average High & Low Temperature",
align: "left"
},
grid: {
borderColor: "#e7e7e7",
row: {
colors: ["#f3f3f3", "transparent"], // takes an array which will be repeated on columns
opacity: 0.5
}
},
markers: {
size: 1
},
xaxis: {
categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"],
title: {
text: "Month"
}
},
yaxis: {
title: {
text: "Temperature"
},
min: 5,
max: 40
},
legend: {
position: "top",
horizontalAlign: "right",
floating: true,
offsetY: -25,
offsetX: -5
}
};
}
})
}
Any help would be appreciated! Thank you
Step 1,
set the configuration with out data like below(minimum configuration)
this.chartOptions = {
series: [],
chart: {
height: 350,
type: "line"
},
xaxis: {}
}
Step 2:
Data from api response and set to "chartoptions" variable,
this.chartOptions.series=[{
name: "data",
data: [28, 29, 33, 36, 32, 32, 33]
}, {
name: "Low - 2013",
data: [12, 11, 14, 18, 17, 13, 13]
}
];
this.chartOptions.xaxis=
{
categories: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"]
}

One series name in higcharts not getting populated even though json send the correct information

The last series in a bar chart is showing "Series 4" as a name, even though its proper name is coming correcty from json file.
The information from the json file comes from a SQL query that prints the information in a string with the following format:
[
{"name": "Operation","data": [{"y":3000, "second": 1500, "third": 5}]},
{"name": "Mechanical","data": [{"y":2515, "second": 515, "third": 8}]},
{"name": "Electrical","data": [{"y":1800, "second": 475, "third": 10}]},
{"name": "Operation Slag","data": [{"y":1000, "second": 1500, "third": 7}]}
]
Since the colors of the series are set manually, I am using the below to add just data and name to each series:
jspData.forEach(function(jspData, i) {
Delays.series[i].setData(jspData.data);
Delays.series[i].setName(jspData.name);
}];
This is working as expected until the last series which show "Series 4" name and not "Operation Slag".
$(function () {
$(document).ready(function(){
$.getJSON('getData.json', function(jspData) {
var Delays = new Highcharts.chart({
chart: {
renderTo: 'Delays',
type: 'bar'
},
xAxis: {
categories: [''],
lineWidth: 0,
minorTickLength: 0,
tickLength: 0,
gridLineWidth: 0,
minorGridLineWidth: 0,
title: {
text: null
}
},
yAxis: {
gridLineWidth: 0,
minorGridLineWidth: 0,
lineWidth: 0,
tickWidth: 0,
tickLength: 0,
min: 0,
title: null,
labels: {
enabled: false,
}
},
tooltip: {
enabled:true,
style:{fontSize:'10px', fontFamily:"sans-serif"},
formatter: function() {
console.log(this);
return 'Total duration: ' + this.y + 'min<br/>Delay Code: ' + this.point.second + '<br/>Count of Events: ' + this.point.third;
},
},
plotOptions: {
bar: {
borderWidth: 0.5,
dataLabels: {
enabled: true,
format: '{series.name}',
style: {
fontSize: "10px",
fontWeight:'normal',
textOutline: false,
fontFamily: 'sans-serif',
},
}
},
series: {
groupPadding: 0,
pointPadding: 0,
},
},
legend:{
enabled:false,
},
series: [{
color:'#4572A7',
data: []
}, {
color:'#89A54E',
data: []
}, {
color:'#AA4643',
data: []
}, {
color:'#A1745B',
data: []
}],
});
jspData.forEach(function(jspData, i) {
Delays.series[i].setData(jspData.data);
Delays.series[i].setName(jspData.name);
});
});
});
});
Last series name should not be "Series 4" but "Operation Slag". Chart is render porperly all other data is populated correctly.
The setName method is internal and it requires to redraw the chart. In your case it's enough to change the order of calls, because setData causes redraw:
jspData.forEach(function(jspData, i) {
Delays.series[i].setName(jspData.name);
Delays.series[i].setData(jspData.data);
});
Live demo: http://jsfiddle.net/BlackLabel/0qkf26zp/
API: https://api.highcharts.com/class-reference/Highcharts.Series#setData

Typescript JSON : Adding child attributes and displaying against parent item attributes

Below is the Json which i need to process
var oldArr =
[{
"careerLevel": "Associate",
"careerLevels": [
{
"201609": 21,
"201610": 22,
"careerID": "10000120"
},
{
"201609": 31,
"201610": 32,
"careerID": "10000130"
}]}];
And convert the above json to :
var newArr= [{
"201609": 52,
"201610": 54,
"careerLevel": "Associate",
"careerLevels": [
{
"201609": 21,
"201610": 22,
"careerID": "10000120"
},
{
"201609": 31,
"201610": 32,
"careerID": "10000130"
}]
}];
Iam trying to achieve the summation using reduce() function:
var arr = [{x:1},{x:2},{x:4}];
arr.reduce(function (a, b) {
return {x: a.x + b.x};
});
console.log(arr); //Outputs that same initial array
var reduceArr = oldArr.reduce((sum, item) =>
const total = sum + item.201609; // this gives me error
);
I have some idea about reduce function but i am still new to this stuff.
I dont know why noone attempted this question. Although people were quick to downvote.
I have created below code to get the desired result :
var oldArr =
{
"careerLevel": "Associate",
"careerLevels": [
{
"201609": 21,
"201610": 22,
"201611": 23,
"careerID": "10000120"
},
{
"201609": 31,
"201610": 32,
"201611": 33,
"careerID": "10000130"
}]
};
var finalSummedJson = JSON.stringify(SummationProcessing(oldArr));
return finalSummedJson;
}
// Summation Logic
function SummationProcessing(oldArr) {
let sumArr = [];
let allKeysInLevels = Object.keys(oldArr.careerLevels[0]);
let uniqueKeys = allKeysInLevels.filter((key, index) => {
return parseInt(key) > 0 && allKeysInLevels.indexOf(key) == index
});
uniqueKeys.forEach(uniqueKey => {
var sumKey = oldArr.careerLevels.reduce((acc, val) => {
return acc + val[uniqueKey];
}, 0);
sumArr.push(sumKey);
});
var reducedData = oldArr.careerLevels.reduce((redArr, inpArr) => {
var keysToFilter = Object.keys(inpArr);
var keyysss = keysToFilter.filter((key, index) => { return parseInt(key) > 0 && keysToFilter.indexOf(key) == index });
keyysss.forEach((element, i) => {
if (!redArr[element]) {
redArr[element] = sumArr[i];
}
// });
});
return redArr;
}, {});
// console.log("reducedData", JSON.stringify(reducedData));
Object.keys(reducedData).forEach(key => { oldArr[key] = reducedData[key] });
return oldArr;
// console.log("finalArr", oldArr);
}
The final result was :
{
"201609": 52,
"201610": 54,
"201611": 56,
"careerLevel": "Associate",
"careerLevels": [{
"201609": 21,
"201610": 22,
"201611": 23,
"careerID": "10000120"
}, {
"201609": 31,
"201610": 32,
"201611": 33,
"careerID": "10000130"
}]
}

streaming multiple series to highcharts

I'm using websockets to stream valid JSON to highcharts.js. My goal is to chart a few lines simultaneously on the same graph. The JSON, which I control, contains data 4-16 series (called parsers) that I'd like overlay with highcharts. Example of JSON:
[
{
"y": 91,
"x": 1403640998,
"name": "parser1"
},
{
"y": 184,
"x": 1403640998,
"name": "parser2"
},
{
"y": 26,
"x": 1403640998,
"name": "parser3"
}
]
I can get a single line to graph, but they get combined into a single series. I'd like to dynamically adjust the series based on the number of parsers I'm monitoring. If my JSON contains information for 3 parsers, like I posted above, I'd like to see 3 lines automatically update every second.
As you can see, I can only get 1 to show.
My HTML
<script type="text/javascript">
$(function () {
$('#container').highcharts({
chart: {
type: 'spline',
events: {
load: function () {
var $message = $('#message');
var connection = new WebSocket('ws://x.x.x.x:8888/ws');
var self = this;
connection.onmessage = function(event) {
var data = JSON.parse(event.data);
var series = self.series[0];
var redrawVal = true;
var shiftVal = false;
if (series.data && series.data.length > 25) {shiftVal = true;}
var newseries = {
name: '',
x: 0,
y: 0
};
$.each(data, function(i,item){
newseries.name = item.name;
newseries.x = item.x;
newseries.y = item.y;
console.log(newseries)
series.addPoint(newseries, redrawVal, shiftVal);
});
};
}
}
},
title: {
text: 'Using WebSockets for realtime updates'
},
xAxis: {
type: 'date'
},
series: [{
name: 'series',
data: []
}]
});
});
Can someone help me get multiple series to dynamically display in highcharts.js?
The general idea should be that for each series you set it's id. Then you cna get that series this way: chart.get(id). So if you have series, then add point to that series, if not, then create new one, just like this: http://jsfiddle.net/9FkJc/8/
var self = this;
data = [{
"y": 91,
"x": 1403640998,
"name": "parser1"
}, {
"y": 184,
"x": 1403640998,
"name": "parser2"
}, {
"y": 26,
"x": 1403640998,
"name": "parser3"
}];
var series = self.series[0];
var redrawVal = true;
$.each(data, function (i, item) {
var series = self.get(item.name);
if (series) { // series already exists
series.addPoint(item, redrawVal, series.data.length > 25);
} else { // new series
self.addSeries({
data: [item],
id: item.name
});
}
});

How do I properly format a JSON object in an external file?

I have used the code available from http://codeblitz.wordpress.com/2009/06/22/jquery-charts/
It uses jqPlot. So I have the following sample code Default.html that works:
<script type="text/javascript">
var jsonObj = { "pageHits": [30, 60, 22, 5, 60, 88, 102], "rssHits": [33, 45, 121, 23, 55, 35, 77], "xAxis": ['Jan 2009', 'Feb 2009', 'Mar 2009', 'Apr 2009', 'May 2009', 'June 2009', 'Jul 2009'] };
$(function () {
$.jqplot('chartDiv', [jsonObj.pageHits, jsonObj.rssHits], CreateBarChartOptions());
});
function CreateBarChartOptions()
{
var optionsObj = {
title: 'Blog Statistics',
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: jsonObj.xAxis
}
},
series: [{label:'Page Hits'}, {label: 'RSS Hits'}],
legend: {
show: true,
location: 'nw'
},
seriesDefaults:{
shadow: true,
renderer:$.jqplot.BarRenderer,
rendererOptions:{
barPadding: 8,
barMargin: 10
}
},
highlighter: {
showTooltip: true,
tooltipFade: true
}
};
return optionsObj;
}
</script>
I have copied the code and put it into Default.aspx. The only thing I want to change is to be able to get the data from an external file, so now my code is:
<script type="text/javascript">
var jsonObj;
$.getJSON('example.json', function (response)
{
jsonObj = response;
alert(jsonObj.property);
});
$(function () {
$.jqplot('chartDiv', [jsonObj.pageHits, jsonObj.rssHits], CreateBarChartOptions());
});
function CreateBarChartOptions()
{
var optionsObj = {
title: 'Blog Statistics',
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: jsonObj.xAxis
}
},
series: [{ label: 'Page Hits' }, { label: 'RSS Hits'}],
legend: {
show: true,
location: 'nw'
},
seriesDefaults: {
shadow: true,
renderer: $.jqplot.BarRenderer,
rendererOptions: {
barPadding: 8,
barMargin: 10
}
},
highlighter: {
showTooltip: true,
tooltipFade: true
}
};
return optionsObj;
}
</script>
But jsonObj is always undefined, I'm presuming my file is not formatted properly. I have tried example.json to contain this:
{"pageHits": [30, 60, 22, 5, 60, 88, 102], "rssHits": [33, 45, 121, 23, 55, 35, 77], "xAxis": ['Jan 2009', 'Feb 2009', 'Mar 2009', 'Apr 2009', 'May 2009', 'June 2009', 'Jul 2009']}
and this:
{"pageHits": [30, 60, 22, 5, 60, 88, 102], "rssHits": [33, 45, 121, 23, 55, 35, 77], "xAxis": ["Jan 2009", "Feb 2009", "Mar 2009", "Apr 2009", "May 2009", "June 2009", "Jul 2009"]}
But to no avail. What am I doing wrong?
Thanks for any assistance,
Julian
You'd probably need to do something like:
$.getJSON('example.json', function (response)
{
var jsonObj = response;
$.jqplot('chartDiv', [jsonObj.pageHits, jsonObj.rssHits], CreateBarChartOptions());
});
The way you have it now your annon function to trigger jqplot will run 'inline', while the ajax loading will still be going on.