HighCharts & MVC: How to load whole graph definition and data with JSON? - json

I'd like to know how it is possible to load options & data graph or whole graph structure returning a JSON object?
In particular, I'd like to dynamically create options, categories, axis, data, etc. with JSON; I think it is possible, but I only found informations describing how to load data& series, not options.
For example, I'd like to define title, xAxis, etc, returning a JSon Object:
[...]
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: []
},
[...]
In particular, I need to dynamically create a more complex graph, similar to this one: http://www.highcharts.com/demo/column-stacked-and-grouped
Thanks in advance!

With DotNet.Highcharts is possible to create the chart on the server side as you like without using JavaScript or JSON. Here is the example which you would like do with the library:
Highcharts chart = new Highcharts("chart")
.InitChart(new Chart { DefaultSeriesType = ChartTypes.Column })
.SetTitle(new Title { Text = "Total fruit consumtion, grouped by gender" })
.SetXAxis(new XAxis { Categories = new[] { "Apples", "Oranges", "Pears", "Grapes", "Bananas" } })
.SetYAxis(new YAxis
{
AllowDecimals = false,
Min = 0,
Title = new YAxisTitle { Text = "Number of fruits" }
})
.SetTooltip(new Tooltip { Formatter = "TooltipFormatter" })
.SetPlotOptions(new PlotOptions { Column = new PlotOptionsColumn { Stacking = Stackings.Normal } })
.SetSeries(new[]
{
new Series
{
Name = "John",
Data = new Data(new object[] { 5, 3, 4, 7, 2 }),
Stack = "male"
},
new Series
{
Name = "Joe",
Data = new Data(new object[] { 3, 4, 4, 2, 5 }),
Stack = "male"
},
new Series
{
Name = "Jane",
Data = new Data(new object[] { 2, 5, 6, 2, 1 }),
Stack = "female"
},
new Series
{
Name = "Janet",
Data = new Data(new object[] { 3, 0, 4, 4, 3 }),
Stack = "female"
}
});
You can find a lot of ASP.NET MVC examples here: http://dotnethighcharts.codeplex.com/releases/view/80650

Related

Convert results from query to json object

I am attempting to convert an api from PHP to react.js. my data looks like this:
s
c
d
A
1
4/1
B
4
4/1
A
2
4/2
B
5
4/2
A
3
4/3
B
6
4/3
I pass json back to the app and it's built like this in PHP.
$graph_arr['bar']['series'][$s] += (int) $c;
$graph_arr['line']['series'][$s][] = (int) $c;
the resulting json looks like this
{line:
{labels: ['4/1','4/2','4/3'], //already have this figured out
series: [{ name: 'A', data: [1,2,3]},
{ name: 'B', data: [4,5,6]}
]}
}
How would I do this in react, new to react.js so I am not too familiar everything works or is constructed yet.
const graph_data = [['a',1,'4/1'],['a',2,'4/1'],['a',3,'4/1'],
['a',4,'4/4'],['b',5,'4/1'],['b',6,'4/1'],['b',7,'4/1'],['b',8,'4/4']]
const series = Object.entries(graph_data).map((row,i) => { })
edit:
found this How to group an array of objects by key. which is close
You can treat it just like you do an array in PHP.
jsonData["line"]["series"][0].name
You can also extract (deconstruct) the data out
const jsonData = {
line: {
labels: ["4/1", "4/2", "4/3"], //already have this figured out
series: [
{ name: "A", data: [1, 2, 3] },
{ name: "B", data: [4, 5, 6] }
]
}
};
const { line } = jsonData;
const { labels, series } = line;
{labels}
{labels[0]}
{series.map((data) => data.name)}
I put them in an example with a couple of different ways for you:
https://codesandbox.io/s/determined-keller-3ott6?file=/src/App.js

Sequelize: Write multidimensional array to database

I have a JSON file with nested arrays of varying length. That is, each object has an ARR with a different number of objects.
{ "count": 200,
"objects": [
{
"id": "FIRST",
"b": "two",
"c": "three",
"ARR": [{
"aa": "onion ",
"bb": 2,
"cc": "peanuts"},
},
{
"aa": "Jam ",
"bb": 4,
"cc": "Bread"},
}],
"d":"four"
]
}, . . . on and on
I have imported the JSON data to my JavaScript file:
const data = JSON.parse(require('fs').readFileSync('./jsonfiles/objects.JSON', 'utf8'))
trim data down to the objects of interest
const objs=data.objects;
I'm using Sequelize to write this to a mysql database. I have two models: Model 1: hasMany Arr sets: Model 2: belongsTo Model1.
Writing the to table1 from Model1 works well like this:
for (var key in Objs) {
var item = Objs[key]
db.Model1.create({
modelID: item.id,
modelB: item.b,
modelC:item.c
})
}
Now, I'm trying to write ARR to the associated model and am stumped on how to do this.
I do not know how many objects will be in each ARR
Storing ARR as a JSON obj in table1 won't serve well later.
This is the function I created for our companies API. Took me a week to put together but hopefully, this helps.
exports.functionName = async (req, res) => {
const params = req.params.something;
if (!params) {
res.status(httpStatusCodes.BAD_REQUEST).send({message:'Please provide params'});
return;
}
const function = inputs.map(prop => ({
propOne: uniqueID,
propTwo: prop.value,
}));
const value = await productInput.bulkCreate(function);
if (!value || value.length < 1) {
res.status(httpStatusCodes.INTERNAL_SERVER_ERROR).send({ message:'No inputs were updated for this product.' });
return;
}
res.send(value);
return;
};

How to remove extra column value from jqgrid json data

Free Jqgrid has actions column. colmodel:
{"hidden":false,"label":"","name":"_actions","width":72
,"align":"left","template":"actions","fixed":false,"resizable":true,
"formatoptions":{"editbutton":true,"delbutton":true,"delOptions":{"url":"Delete" }}},
{"label":"Nimetus","name":"Nimi","index":"Nimi","editoptions":{"maxlength":80,"size":80 }
It is populated from remote json data like
{"total":1,
"page":1,
"rows":[{"id":"2ARVELDUSARV", "cell":[null,"2ARVELDUSARV"]},
{"id":"ACME","cell":[null,"ACME"]},
{"id":"KAKSKOERA","cell":[null,"KAKSKOERA"]}
]
}
In cell array first column is not used.
If this column is removed, jqgrid does not render data correctly since this column presence is required as placeholder for actions column.
How to fix this so that jqgrid will accept data without first column:
{"total":1,
"page":1,
"rows":[{"id":"2ARVELDUSARV", "cell":[null,"2ARVELDUSARV"]},
{"id":"ACME","cell":["ACME"]},
{"id":"KAKSKOERA","cell":["KAKSKOERA"]}
]
}
Update
I looked for data format change as recommended in answer.
jqgrid data is created from sql select statement in ASP.NET MVC4 using code below. Web API serializes this to format for json for jqgrid automatically.
How to create result which can serialized to propertyname: value format recommended in answer ?
object GetDataForJqGrid() {
IDbConnection conn;
using (var dataReader = DataAccessBase.ExecuteReader(sql.ToString(), out conn,
CommandBehavior.CloseConnection | CommandBehavior.SingleResult,
sql.GetParameters.ToArray()))
{
var rowList = new List<GridRow>();
var pkeys = DatabasePrimaryKey();
while (dataReader.Read())
{
var pkv = new List<object>();
int offset = 1; // required for actions column
var row = new GridRow
{
id = IdHelper.EncodeId(pkv),
cell = new object[dataReader.FieldCount + offset + imageCount]
};
for (int j = 0; j < dataReader.FieldCount; j++)
row.cell[offset + j] = dataReader.GetValue(j);
rowList.Add(row);
}
return new
{
total = rowList.Count() < rows ? page : page + 1, page,
rows = rowList
};
}
public class GridRow
{
public string id;
public object[] cell;
}
The most easy way would be to chanege the format of data returned from the server to use repeatitems: false style of the data. I mean the usage of
{
"total": 1,
"page": 1,
"rows": [
{ "id": "2ARVELDUSARV", "Nimi": "2ARVELDUSARV" },
{ "id": "ACME", "Nimi": "ACME" },
{ "id": "KAKSKOERA", "Nimi": "KAKSKOERA"}
]
}
or, after adding key: true to the definition of the column Nimi
{
"total": 1,
"page": 1,
"rows": [
{ "Nimi": "2ARVELDUSARV" },
{ "Nimi": "ACME" },
{ "Nimi": "KAKSKOERA"}
]
}
instead of
{
"total": 1,
"page": 1,
"rows": [{
"id": "2ARVELDUSARV",
"cell": ["2ARVELDUSARV"]
}, {
"id": "ACME",
"cell": ["ACME"]
}, {
"id": "KAKSKOERA",
"cell": ["KAKSKOERA"]
}]
}
Alternatively one can use jsonReader: { repeatitems: false } event with your current format of data and add jsonmap: "cell.0" property to, which means getting the first element (index 0) from the array cell:
$("#list").jqGrid({
datatype: "json",
url: "andrus.json",
colModel: [
{ label: "", name: "_actions", template: "actions" },
{ label: "Nimetus", name: "Nimi", jsonmap: "cell.0" }
],
iconSet: "fontAwesome",
jsonReader: { repeatitems: false }
});
see the demo.
I personally would recommend you don't use your original format (cell with array of values) and use just the named property with additional id property (if id value is not included in the item already). If you would do use the solution with jsonmap you should be carefully with changing the order of the columns (using remapColumns) and later reloading of data. You could required to update jsonmap values after the changing the column order. Thus I repeat that I recommend you to change format of data returned from the server.
UPDATED: The Updated part of your question formulate absolutely new question which have no relation with jqGrid. It's pure C# problem. Nevertheless I try to answer, because I use C# too.
What you can do with minimal changes of your code is the following: You should add using System.Dynamic; and using System.Linq; first of all. Then you should replace the code inside of using (...) {...} to about the following
var rowList = new List<dynamic>();
while (dataReader.Read()) {
var row = new ExpandoObject() as IDictionary<string, object>;
for (int j = 0; j < dataReader.FieldCount; j++) {
if (!dataReader.IsDBNull(j)) {
row.Add(dataReader.GetName(j), dataReader.GetValue(j));
}
}
rowList.Add(row);
}
Serializing of rowList will produce the names properties. If you know the primary key of the data, then you can add id property with the corresponding value in the same way (using row.Add("id", IdHelper.EncodeId(pkv))). I don't included the part because the code which you posted is not full and pkv is currently always new List<object>(), which is wrong. If the data have composed key (multiple value set is unique) then you can make string concatenation of the keys using '_' (underscore) as the separator.

best way to parse nested object in AngularJS?

I'm trying to use angularjs for parsing a nested data structure returned from a remote server. I'm really stumped by this pattern because i'm trying to access the "events" data with the following function
$scope.generate_event = function(){
from_date = $scope.dts.from
to_date = $scope.dts.to
from = from_date.getFullYear()+'/'+(from_date.getMonth()+1)+'/'+from_date.getDate()
to = to_date.getFullYear()+'/'+(to_date.getMonth()+1)+'/'+to_date.getDate()
$http.get(server+'rawdata?vids='+$scope.selected_vehicle.id+'&evfields=lat,lon,f_event_time,speed&from='+from+'&to='+to)
.success(function(data){
$scope.report_data = data
$localStorage.report_data = data
$scope.generate()
})
}
Any advice or even a hint on the best approach would be great, i need this running for work and its been a month now. Thanks!
{
"rawData": {
"keys": {
"lat": ["number", "lat"],
"lon": ["number", "lon"],
"speed": ["number", "Speed [mph]"],
"code": ["number", "EVC"],
"vid": ["number", "Vehicle ID"]
},
"keys_order": ["lat", "lon", "speed", "code", "vid"],
"events": [{
"f_lon": -8.3315599999999996,
"code": 4,
"vid": 5,
"lon": -833156,
"f_lat": 51.90831,
"lat": 5190831,
"speed": 78.0
}, {
"f_lon": -8.3741599999999998,
"code": 4,
"vid": 5,
"lon": -837416,
"f_lat": 51.903979999999997,
"lat": 5190398,
"speed": 78.0
}]
}
}
UPDATE: I didnt explain the problem correctly. Here's the generate function
$scope.generate = function(){
$scope.event_config = {
title: 'Events', // chart title, legend etc
/*etc
*etc
*/
data = {}
data.series = [' Events']
data.data = []
this fucker ----->$scope.report_data.events.forEach(function(value, index, array){
o = {}
o.x = value.f_event_time
o.y = [value.lat+'/'+value.lon]
o.tooltip = value.speed
data.data.push(o)
})
$scope.event_data = data
I'm getting error 'forEach undefined'. This is supposed to generate a d3 chart but 'report_data' is intially used to store distance data from a different function for local storage. So do i need a second variable for localStorage? ie $scope.report_event = $localStorage.report_event? Can someone look at the source code if i send it?
$http.get(server+'rawdata?vids='+$scope.selected_vehicle.id+'&evfields=lat,lon,f_event_time,speed&from='+from+'&to='+to)
.success(function(data){
if (data) {
var events = data.rawData.events; // get the events json array
$scope.generate(events);
}
})
and in your controller have the declarative function like
$scope.generate = function(events) {
// your code
}
Solved it with the following
$scope.generate_report = function(){
from_date = $scope.dts.from
to_date = $scope.dts.to
from = from_date.getFullYear()+'/'+(from_date.getMonth()+1)+'/'+from_date.getDate()
to = to_date.getFullYear()+'/'+(to_date.getMonth()+1)+'/'+to_date.getDate()
$http.get(server+'vehicle/'+$scope.selected_vehicle.id+'/counters/deltas/day?from='+from+'&to='+to)
.success(function(data){
$scope.report_data = data
$localStorage.report_data = data
$scope.process()
})
$http.get(server+'rawdata?vids='+$scope.selected_vehicle.id+'&genevcodes=39,40&evfields=lat,lon,f_event_time,mph,speed,code&from='+from+'&to='+to)
.success(function(data){
if(data){
var events = data.rawData.events
}
$scope.report_event = events
$localStorage.report_event = events
$scope.generate()
})
}
just had to declare another localstorage variable for storing events from the JSON object Thanks Yannik

Filtering JSON request

I have a simple set of JSON data that I am pulling from a local file and loading into a datatable
Using YUI, how can I filter the response of this request to match only the data that is relevant to the request data?
EDIT: improper formatting on first post
YUI().use('aui-datatable', 'datatable-sort', 'aui-io-request', 'aui-tabview', 'datasource-io',
function(Y) {
var columns = [{
key : 'id',
sortable : true
}, {
key : 'name',
sortable : true
},{
key : 'price',
sortable : true
}];
var dataTable = new Y.DataTable({
columns : columns
}).render("#searchResultsTab");
var node = Y.one('#searchButton');
var criteria = document.getElementById("searchCriteria");
node.on(
'click', //on Search..
function(){
dataSource = new Y.DataSource.IO({source:'mydata.json'});
request = document.getElementById("searchBox").value;
dataSource.sendRequest({
on: {
success: function(e){
var response = e.data.responseText;
jdata = Y.JSON.parse(response);
dataTable.set('data', jdata.info); //setting table data to json response
},
failure: function(e){
alert(e.error.message);
}
}
});
}
);
new Y.TabView(
{
srcNode: '#searchResultsContainer'
}
).render();
});
mydata.json
{"info" : [
{"id": 1,"name": "A green door","price": 12.50 },
{"id": 2,"name": "A blue door","price": 10.50 },
{"id": 3,"name": "A red door","price": 8.50 }
}
In your on success method filter your response data before setting the datatable data source. Here is an example of model list filtering: http://yuilibrary.com/yui/docs/model-list/#filtering-models