dhtmlxgantt Populate Nested JSON data - javascript

I have a dhtmlx gantt chart in my page, normally it would have work perfectly but now when I have a JSON file with nested array all my output would be unrecognized instead. I'm trying to populate the official name.
Can Anyone help me with this? Thank you very much.
JSON
{
"data": [
{
"assign_to": {
"id": 3,
"employee_id": "28141",
"official_name": "Hal Jordan",
},
"task": {
"id": 1,
"name": "Modeling",
"description": "3d modeling work"
},
"start_date": "2017-06-15",
"end_date": "2017-06-19"
},
{
"assign_to": {
"id": 3,
"employee_id": "28144",
"official_name": "Kyle Rayner",
},
"task": {
"id": 8,
"name": "Composting",
"description": null
},
"start_date": "2017-06-01",
"end_date": "2017-06-08"
}
]
}
Javascript
gantt.config.columns = [
{name: "assign_to.official_name", label: "Assign To", align: "left", width: 70},
];
function initializeGantt() {
gantt.init("my_scheduler");
gantt.load("/dashboard/ganttchart_list/5/?format=json");
}
initializeGantt();
HTML
<div id="my_scheduler" style='width:1405px; height:245px;'></div>

dhtmlx gantt doesn't support nested structure, so you'll need to preprocess your items before loading them to gantt.
Since you know which format you have and which format is expected by gantt (https://docs.dhtmlx.com/gantt/desktop__supported_data_formats.html#json ) it shouldn't be a problem.
The most important thing
Make sure data items have 'id' property
when you define column name like this:
{name: "assign_to.official_name", label: "Assign To", align: "left", width: 70},
column name can't be mapped to a property of a nested object, so you'll either have to flatten structure during loading, very roughly, it can be done in following way:
http://snippet.dhtmlx.com/129d2e043
Or define a column template which would take value from nested object:
http://snippet.dhtmlx.com/9e8e65e85
please check the console output for a result dataset

Related

how to show multiple data labels on react highchart line chart?

i want to show below data (sample data from my api) on react highchart line chart. but i am confuse how to prepare this data. the chart should be look alike, at Aaxis all assignments name and at y axis if 4 assignment name then look at data each object have values array. so 4 assignment names means 4 charts with multiple data labels. look at below screen shot. first image is what my chart should look alike. the second screenshot is how my chart giving error data is not loading.i am also attaching codesandbox link. the data is too much i have total 30+ assignments names with array of datalabels but right now i am attaching only 4.
codesandbox link : https://codesandbox.io/s/customizable-react-dashboard-with-chart-fork-forked-15rfpq?file=/src/LineHighchart.js
my sample Data:
const data ={"data":[{"assignment_name":"assignment for oliver","0":26,"1":1,"2":70,"3":80,"4":100,"5":10,"6":0,"7":0},{"assignment_name":"assignment","0":25,"1":0,"2":19,"3":35,"4":310,"5":0,"6":0,"7":0},{"assignment_name":"assignment2","0":27,"1":20,"2":10,"3":30,"4":50,"5":90,"6":0,"7":0},
{"assignment_name":"assignment2","0":29,"1":0,"2":10,"3":0,"4":30,"5":0,"6":60,"7":10},
]}
I am not familiar with the react wrapper for Highcharts, but here is a plain vanilla Highcharts object to show a line graph with two series and five data points, which might help you dig further:
{
"chart": {
"height": 436
},
"xAxis": {
"categories": [
"2019-12-30",
"2020-01-06",
"2020-01-13",
"2020-01-20",
"2020-01-27",
],
"title": {
"text": "Week",
}
},
"series": [{
"name": "Count",
"type": "line",
"data": [ 6, 9, 7, 6, 5 ]
}, {
"name": "Slope",
"type": "spline",
"data": [ 5.9, 6.23, 6.57, 6.9, 7.23 ]
}
]
}
UPDATE:
Here is the answer for your comment question: "can u make array of object from my given data and then give that variable to series":
const data ={
"data": [
{"assignment_name":"assignment for oliver",
"0":26,"1":1,"2":70,"3":80,"4":100,"5":10,"6":0,"7":0},
{"assignment_name":"assignment",
"0":25,"1":0,"2":19,"3":35,"4":310,"5":0,"6":0,"7":0},
{"assignment_name":"assignment2",
"0":27,"1":20,"2":10,"3":30,"4":50,"5":90,"6":0,"7":0},
{"assignment_name":"assignment2",
"0":29,"1":0,"2":10,"3":0,"4":30,"5":0,"6":60,"7":10},
]
};
let categories = Object.keys(data.data[0]).filter(key => key.match(/^\d+$/));
let series = data.data.map(obj => {
return {
name: obj.assignment_name,
tyle: 'line',
data: categories.map(key => obj[key])
}
});
let chartObj = {
"chart": {
"height": 436
},
"xAxis": {
"categories": categories,
"title": {
"text": "Assignments",
}
},
"series": series
};
console.log(chartObj);

How to bind a conditional panelCount to a question type of 'paneldynamic' in SurveyJs

In my survey in SurveyJs, I'm attempting to implement a question with the type 'paneldynamic', which has the following structure:
{
type: "paneldynamic",
name: "9.2",
visible: false,
visibleIf: "{9.a.n} > 0",
title: "When did you give birth?",
enableIf: "{9.a.n} > 0",
requiredIf: "{9.a.n} > 0",
templateTitle: "Date of birth:",
templateElements: [
{
type: "text",
name: "9.2.1",
inputType: "date",
maxValueExpression: "today()",
titleLocation: 'hidden'
},
],
panelCount: "{9.a.n}"
}
where Question 9a is a number entry. I want the number of panels on this question to vary depending on the answer given to Q9a, but with this question structure the survey does not appear to bind the value of 9a to the actual panel count.
I've been unable to find anything in the documentation, and have tried variants such as "bindings: { "panelCount": "9.a.n" } which also don't seem to work.
How can I correctly set the variable panelCount property?
You may wish to create a custom function and calculate the number of panels based on another question answer. For example: https://plnkr.co/edit/iYNMt7JRPOh2dTOy.
Survey.Serializer.addProperty("paneldynamic", {
name: "panelCountExpression:expression",
onExecuteExpression: (obj, res) => {
if(res !== undefined) {
obj.panelCount = res;
}
}
});
var json = {
"pages": [
{
"name": "page1",
"elements": [
{
"type": "text",
"name": "question1",
"inputType":"number",
"min": 0,
"max": 5,
"defaultValue":"2"
},
{
"type": "paneldynamic",
"name": "question2",
"panelCountExpression":"{question1}",
"templateElements": [
{
"type": "text",
"name": "question3"
}]
}
]
}
],
};
I also recommend that you review the following:
Blogpost (the example was taken from it): SurveyJS Library — Calculate Properties and Hide Elements With Expressions and Functions.
Documentation: Conditional Logic and Dynamic Texts.
Thanks

check if item exists in json file then get it if exists. And if not complete executing the code

I get a json file from outer link by ajax call. i want to check element is exists in this json file or not and get it if exists. because it changes every time and items increases or decreases. If I get item and this item not existing, I get error and the code not complete. i want to check this item json.children[1].children and json.children[2].children ,..... if exists.
{
"num": 1,
"name": "aa",
"properites": [
{
"name": "prop1",
"value": "value1"
}
],
"children": [
{
"num2": 1,
"name2": "name2",
"properites": [
{
"name": "name",
"value": "value"
}
],
"children": []
},
{
"name": 1,
"num": "1",
"attributes": [
{
"name": "name",
"value": "value"
}
],
"children": []
.......................... big json file
I have tried to get these Items and set in local storage to use in table by this:
localStorage.setItem("row1-item1", json.children[1].children);
localStorage.setItem("row1-item2", json.children[2].children);
localStorage.setItem("row1-item3", json.children[3].children);
localStorage.setItem("row1-item4", json.children[4].children);
localStorage.setItem("row2-item1", json.name[1].children);
localStorage.setItem("row2-item2", json.name[2].children);
localStorage.setItem("row2-item3", json.name[3].children);
localStorage.setItem("row2-item4", json.name[4].children);
the problem here is if json.children[4].children not existing the code not complete the next line and jump out of ajax call even if json.name[1].children is exists. I tried try/catch but not solved it
Try to use map
json.children.map((children,index)=>{
localStorage.setItem('row${index}-item${index}`, children);
}
Or you can use forEach or for loop instead of map.

How to model the rows in getData() since i have nested JSON data?

I want to display these fields :name, age, addresses_id, addresses_city, addresses_primary for each person into data studio.
My JSON data
{
"data": [
{
"name": "Lio",
"age": 30,
"addresses": [
{
"id": 7834,
"city": "ML",
"primary": 1
},
{
"id": 5034,
"city": "MM",
"primary": 1
}
]
},
{
"name": "Kali",
"age": 41,
"addresses": [
{
"id": 3334,
"city": "WK",
"primary": 1
},
{
"id": 1730,
"city": "DC",
"primary": 1
}
]
},
...
]
}
there is no problem if i don't render the addresses field
return {
schema: requestedFields.build(),
rows: rows
};
//rows:
/*
"rows": [
{
"values": ["Lio", 30]
},
{
"values": ["Kali", 41]
},
...
]
*/
The problem is
I'm not able to model the nested JSON data in Google Data Studio. I
have the problem exactly in the "addresses" field.
Could anyone tell me what format should be for the rows in this case?
As you already know, for each name of your dataset, you clearly have more than one row (one person has multiple addresses). Data Studio only accepts a single data for each field, since arrays are not supported at all. So you need to work on this.
There are some ways to solve this, but always keep in mind that:
getSchema() should return all available fields for your connector (the order doesn't really matter, since Data Studio always sort alphabetically the available fields)
getData() should return a list of values. But here the order is relevant: it should be the same as the parameter passed to getData() (which means the results should be dynamic, sometimes you'll return all values, sometimes not, and the order may change).
Solution 1: Return multiple rows per record
Since you can produce multiple rows for each name, just do it.
To achieve this, your field definition (=getSchema()) should include fields address_id, address_city and address_primary (you can also add address_order if you need to know the position of the address in the list).
Supposing getData() is called with all fields in the same order they were discribed, rows array should look like this:
"rows": [
{
"values": ["Lio", 30, "7834", "ML", 1]
},
{
"values": ["Lio", 30, "5034", "MM", 1]
},
{
"values": ["Kali", 41, "3334", "WK", 1]
},
{
"values": ["Kali", 41, "1730", "DC", 1]
},
...
]
IMO, this is the best solution for your data.
Solution 2: Return one address only, ignoring others
If you prefer one row per person, you can get one of the addresses and display only it (usually the main/primary address, or the first one).
To achieve this, your field definition (=getSchema()) should include fields address_id, address_city and address_primary.
Supposing getData() is called with all fields in the same order they were discribed, rows array should look like this:
"rows": [
{
"values": ["Lio", 30, "7834", "ML", 1]
},
{
"values": ["Kali", 41, "3334", "WK", 1]
},
...
]
Solution 3: Return all addresses, serialized in a field
This is helpful if you really need all information but do not want a complex scheme.
Just create a field called addresses in your field definition (=getSchema()) and write the JSON there as a string (or any other format you want).
Supposing getData() is called with all fields in the same order they were discribed, rows array should look like this:
"rows": [
{
"values": ["Lio", 30, "[{\"id\": 7834, \"city\": "ML", \"primary\": 1}, {\"id\": 5034, \"city\": \"MM\", \"primary\": 1}]"]
},
{
"values": ["Kali", 41, "[{\"id\": 3334, \"city\": \"WK\", \"primary\": 1}, {\"id\": 1730, \"city\": \"DC\", \"primary\": 1}]"]
},
...
]
This solution may appear senseless, but it is possible to interact with this data later in DataStudio using REGEX if really needed.
Solution 4: Create a different field for each address
If you're sure all records has a maximum number of addresses (in you example, both names have 2 addresses, for example), you can create multiple fields.
Your field definition (=getSchema()) should include fields address_id1, address_city1, address_primary1, address_id2, ... address_primaryN.
I wouldn't explain how rows should look like in this situation, but it is not hard to guess with the other examples.

Recursive circle packing?

I have a JSON object that I want to be able to visualize as a hierarchy of circles like this (you can zoom in and out of the hierarchy using mouse clicks).
I'm just trying to figure out how to use the d3.layout.pack to generate the hierarchy for the JSON object below and access the data that sits under Franchise. Any pointers would be much appreciated. Thanks.
{
"Consultant":
[
{
"ConsultantID": 1,
"ConsultantName": "Test Consultant",
"Account":
[
{
"AccountID": 1,
"AccountName": "Test Account",
"Site":
[
{
"SiteID": 1,
"SiteName": "Test Site",
"Franchise":
[
{
"FranchiseID": 1,
"FranchiseName": "Test Franchise",
"Data":
{
// Data goes here
}
}
]
}
]
}
]
}
]
}
For the layout, you can use the built in circle packing layout as you suggest.
For formating the data to use it in this layout, you can use the d3.nest() function. If you want some more insight on how nest works, then I suggest you to have a look at the following question: D3 JSON data conversion

Categories

Resources