Related
I'm attempting to write a function to recursively delete nodes based on Parent-child relationships.
function recursiveDelete(parentNode, deleteStack) {
let toDelete = allNodes.filter(function (node) {
return node.Parent !== undefined && node.Parent[0] === parentNode.ID;
})
toDelete.forEach((childNode) => {
deleteStack.push(...recursiveDelete(childNode, toDelete));
});
return deleteStack;
}
When I run this code, it create arrays with multiple copies of each node to be deleted, which seems to correspond to the height of the tree. It still seems to be running in polynomial time, but it isn't ideal.
edit - below is an example of what gets returned when I run the function on allNodes, with the duplicates.
[
{
"ID": "recymaQKcdrGzAqRM",
"Name": "Depth 1",
"Type": "task",
"Duration": 0.1,
"Priority": "6",
"Parent": [
"recQT9BPQtqs7Cg0U"
],
"Predecessors": [
"recKwlRnVhKik3SZF"
],
"depth": 2
},
{
"ID": "recRcn1t2Nkupcb9L",
"Name": "Start",
"Type": "start",
"Duration": 0.1,
"Priority": "5",
"Parent": [
"recymaQKcdrGzAqRM"
]
},
{
"ID": "recBmEBC1bo1CcJ8i",
"Name": "Depth 2",
"Type": "task",
"Duration": 0.1,
"Priority": "5",
"Parent": [
"recymaQKcdrGzAqRM"
],
"Predecessors": [
"recRcn1t2Nkupcb9L"
]
},
{
"ID": "recRcn1t2Nkupcb9L",
"Name": "Start",
"Type": "start",
"Duration": 0.1,
"Priority": "5",
"Parent": [
"recymaQKcdrGzAqRM"
]
},
{
"ID": "recBmEBC1bo1CcJ8i",
"Name": "Depth 2",
"Type": "task",
"Duration": 0.1,
"Priority": "5",
"Parent": [
"recymaQKcdrGzAqRM"
],
"Predecessors": [
"recRcn1t2Nkupcb9L"
]
},
{
"ID": "rec7qUgu7kpnQ06s7",
"Name": "Start",
"Type": "start",
"Duration": 0.1,
"Priority": "5",
"Parent": [
"recBmEBC1bo1CcJ8i"
]
},
{
"ID": "rec5Lyx3zuAsCPv9W",
"Name": "Depth 3",
"Type": "task",
"Duration": 0.1,
"Priority": "5",
"Parent": [
"recBmEBC1bo1CcJ8i"
],
"Predecessors": [
"rec7qUgu7kpnQ06s7"
]
},
{
"ID": "rec7qUgu7kpnQ06s7",
"Name": "Start",
"Type": "start",
"Duration": 0.1,
"Priority": "5",
"Parent": [
"recBmEBC1bo1CcJ8i"
]
},
{
"ID": "rec5Lyx3zuAsCPv9W",
"Name": "Depth 3",
"Type": "task",
"Duration": 0.1,
"Priority": "5",
"Parent": [
"recBmEBC1bo1CcJ8i"
],
"Predecessors": [
"rec7qUgu7kpnQ06s7"
]
}
]
My current hack is to just remove duplicates:
[...new Set(recursiveDelete(allNode, [allNode]))]
But I'd like to figure out what I'm doing wrong. Thanks!
edit, I think I figured it out. Instead of passing toDelete to the recursive function, I should've only been passing [childNode], so the correct code looks like this:
function recursiveDelete(parentNode, deleteStack) {
let toDelete = allNodes.filter(function (node) {
return node.Parent !== undefined && node.Parent[0] === parentNode.ID;
});
toDelete.forEach((childNode) => {
deleteStack.push(...recursiveDelete(childNode, [childNode]));
});
return deleteStack;
}
Here, I want to render a dynamic fusion Gantt chart. On the below example, I have hard-coded the data for rendering the chart. But I need in an dynamic format. My data is coming from an API, so how can I get that data and pass dynamically?
Also, I want x-axis and y-axis in an dynamic format.
FusionCharts.ready(function() {
var smoPlan = new FusionCharts({
type: 'gantt',
renderAt: 'chart-container',
width: '750',
height: '300',
dataFormat: 'json',
dataSource: {
"chart": {
"theme": "fusion",
"dateformat": "mm/dd/yyyy",
"caption": " ",
"captionFontSize": "14",
"subCaption": "Project Plan",
"subCaptionFontSize": "12",
"milestoneFont": "Times New Roman",
"milestoneFontSize": "15"
},
"categories": [{
"category": [{
"start": "08/01/2014",
"end": "08/31/2014",
"label": "Aug '14"
}, {
"start": "09/01/2014",
"end": "09/30/2014",
"label": "Sep '14"
}, {
"start": "10/01/2014",
"end": "10/31/2014",
"label": "Oct '14"
}]
}],
"processes": {
"fontsize": "12",
"isbold": "1",
"align": "left",
"process": [{
"label": "Identify Customers"
}, {
"label": "Survey 500 Customers"
}, {
"label": "Interpret Requirements"
}
]
},
"tasks": {
"task": [{
"id": "1",
"start": "08/04/2014",
"end": "08/10/2014"
}, {
"id": "2",
"start": "08/08/2014",
"end": "08/19/2014"
}, {
"id": "3",
"start": "08/19/2014",
"end": "09/02/2014"
}]
},
//Adding milestones to task with id 1 and 3
"milestones": {
"milestone": [{
"date": "8/06/2014",
"taskid": "1",
"color": "#f8bd19",
"shape": "rhombus",
"tooltext": "Successful Completion of Development",
"label": " ",
"color": "#587B17"
}, {
"date": "8/25/2014",
"taskid": "3",
"color": "#f8bd19",
"shape": "triangle",
"tooltext": "Successful Completion of Campaign",
"label": " ",
"color": "#4838D2"
}]
}
}
}).render();
});
Please help me to solve this! Thanks in advance.
I am trying to implement Gantt Chart in Fusion Chart. But, I am not able to find few customizing options. Following are the options I require to implement on the Fusion Gantt Chart,
How to customize or reduce the size of the milestone?
How to customize the Y-axis data label as hyperlink? [with reference to picture, the labels such as Identify Customers, Survey 500 customers, etc. must be an hyperlink which will help us to drilldown to data level information]
Is there any possible way to change the shape of the milestone to triangle other than polygon or star?
FusionCharts.ready(function() {
var smoPlan = new FusionCharts({
type: 'gantt',
renderAt: 'chart-container',
width: '750',
height: '500',
dataFormat: 'json',
dataSource: {
"chart": {
"theme": "fusion",
"dateformat": "mm/dd/yyyy",
"caption": "Social Media Optimization",
"captionFontSize": "14",
"subCaption": "Project Plan",
"subCaptionFontSize": "12",
"milestoneFont": "Times New Roman",
"milestoneFontSize": "15",
"labelLink": "http://www.fusioncharts.com/"
},
"categories": [{
"category": [{
"start": "08/01/2014",
"end": "08/31/2014",
"label": "Aug '14"
}, {
"start": "09/01/2014",
"end": "09/30/2014",
"label": "Sep '14"
}, {
"start": "10/01/2014",
"end": "10/31/2014",
"label": "Oct '14"
}, {
"start": "11/01/2014",
"end": "11/30/2014",
"label": "Nov '14"
}, {
"start": "12/01/2014",
"end": "12/31/2014",
"label": "Dec '14"
}, {
"start": "01/01/2015",
"end": "01/31/2015",
"label": "Jan '15"
}, {
"start": "02/01/2015",
"end": "02/28/2015",
"label": "Feb '15"
}, {
"start": "03/01/2015",
"end": "03/31/2015",
"label": "Mar '15"
}]
}],
"processes": {
"fontsize": "12",
"isbold": "1",
"align": "left",
"process": [{
"label": "Identify Customers"
}, {
"label": "Survey 500 Customers"
}, {
"label": "Interpret Requirements"
}, {
"label": "Market Analysis"
}, {
"label": "Brainstorm concepts"
}, {
"label": "Define Ad Requirements"
}, {
"label": "Design & Develop"
}, {
"label": "Mock test"
}, {
"label": "Documentation"
}, {
"label": "Start Campaign"
}]
},
"tasks": {
"task": [{
"id": "1",
"start": "08/04/2014",
"end": "08/10/2014",
"color": "#000000",
}, {
"id": "2",
"start": "08/08/2014",
"end": "08/19/2014"
}, {
"id": "3",
"start": "08/19/2014",
"end": "09/02/2014"
}, {
"id": "4",
"start": "08/24/2014",
"end": "09/02/2014"
}, {
"id": "5",
"start": "09/02/2014",
"end": "09/21/2014"
}, {
"id": "6",
"start": "09/21/2014",
"end": "10/06/2014"
}, {
"id": "7",
"start": "10/06/2014",
"end": "01/21/2015"
}, {
"id": "8",
"start": "01/21/2015",
"end": "02/19/2015"
}, {
"id": "9",
"start": "01/28/2015",
"end": "02/24/2015"
}, {
"id": "10",
"start": "02/24/2015",
"end": "03/27/2015"
}]
},
//Adding milestones to task with id 7 and 10
"milestones": {
"milestone": [{
"date": "1/21/2015",
"taskid": "7",
"color": "#f8bd19",
"shape": "star",
"tooltext": "Successful Completion of Development",
"label": "Development Complete",
"color": "#587B17"
}, {
"date": "3/28/2015",
"taskid": "10",
"color": "#f8bd19",
"shape": "star",
"tooltext": "Successful Completion of Campaign",
"label": "Campaign Complete",
"color": "#4838D2"
}]
}
}
}).render();
});
HTML Code
-->
<div id="chart-container">FusionCharts will render here</div>
You can customize or reduce the size of the milestone by using the "radius" attribute under the "milestone" object like radius: 5
You can customize the Y-axis data label as hyperlink by using the "link" attribute under the "process" object like link: "https://www.fusioncharts.com/". This attribute supports all kinds of FusionCharts link formats.
Reference:
https://www.fusioncharts.com/dev/chart-guide/chart-configurations/drill-down#simple-links
To change the shape of the milestone to triangle you need to set the "shape" attribute to "polygon" and set the "numSides" attribute to "3" under the "milestone" object like numSides: 3
Reference sample: http://jsfiddle.net/srishti_fc/w9bnt24L/3/
This is my data and I am trying to map the name of the nodes to the sources and targets of the links.
var x = {
"nodes": [
{
"name": "Decision 3a"
},
{
"name": "Req 1"
},
{
"name": "Req 3c"
},
{
"name": "Cloud Services"
}
],
"links": [
{
"source": "0",
"target": "3",
"value": 100
},
{
"source": "4",
"target": "2",
"value": 100
}
]
};
I want the object to look like this for my visualization--
var x = {
"nodes": [
{
"name": "Decision 3a"
},
{
"name": "Req 3"
},
{
"name": "Req 3c"
},
{
"name": "Req 3b"
}
],
"links": [
{
"source": "Decision 3a",
"target": "Req 3c",
"value": 100
},
{
"source": "Cloud Services",
"target": "Req 1",
"value": 100
}
]
};
I tried adding the id to the nodes and then map them but in that case the id remain there in the nodes object.
you need to loop through the each object in the links array and get the index from the nodes array and assign that value to the links array.
i hope the below code solves the issue
var x = {
"nodes": [
{
"name": "Decision 3a"
},
{
"name": "Req 1"
},
{
"name": "Req 3c"
},
{
"name": "Req 4"
},
{
"name": "Cloud Services"
}
],
"links": [
{
"source": "0",
"target": "3",
"value": 100
},
{
"source": "4",
"target": "2",
"value": 100
}
]
};
x.links.forEach(o => {
let name = x.nodes[parseInt(o.source)].name;
o["source"] = name;
})
console.log("output",x)
I have a script for full calendar listed below. Every thing is working fine. I returned events stored in database from controller in JSON format. Now that the format of json data is changed slightly, i could not parse to show events in calendar. Following is my script;
$('#calendar').fullCalendar({
editable: true,
events: {
url: "{{ route('event_calendar.data') }}"
},
eventDrop: function(event,dayDelta,minuteDelta,allDay,revertFunc) {
var data = event.title;
var start = event.start.format();
var end = event.end.format();
var csrf= "{{csrf_token()}}"
$.post("{{ route('event_update') }}",{title: data, start: start, end: end, _token: csrf}, function (info) { $("#result").html(info); });
},
header: {
center: 'month,thisWeek' // buttons for switching between views
},
views: {
thisWeek: {
type: 'agenda',
duration: { week: 1 },
buttonText: 'This week'
}
}
});
This is my previous data in JSON format which is acquired from url i.e {{ route('event_calendar.data') }}
[{
"id": 9,
"title": "Event 1",
"color": "#af2e0e",
"start": "2017-09-18",
"end": "2017-09-20"
}, {
"id": 10,
"title": "Event 2",
"color": "#0b7c0d",
"start": "2017-09-04",
"end": "0000-00-00"
}, {
"id": 11,
"title": "Event 3",
"color": "#378006",
"start": "2017-09-10",
"end": "2017-09-12"
}, {
"id": 13,
"title": "Publication",
"color": "#378006",
"start": "2017-09-15",
"end": "2017-09-16"
}, {
"id": 14,
"title": "other",
"color": "#378006",
"start": "2017-09-05",
"end": "2017-09-06"
}, {
"id": 18,
"title": "other",
"color": "#378006",
"start": "2017-09-18",
"end": "2017-09-19"
}, {
"id": 19,
"title": "Apple",
"color": "#378006",
"start": "2017-09-08",
"end": "2017-09-09"
}, {
"id": 20,
"title": "Developer",
"color": "#378006",
"start": "0000-00-00",
"end": "0000-00-00"
}, {
"id": 21,
"title": "New event",
"color": "#af2e0e",
"start": "2017-09-28",
"end": "2017-09-30"
}, {
"id": 22,
"title": "asdasd",
"color": "#0b7c0d",
"start": "2017-08-28",
"end": "2017-08-31"
}]
This is my new JSON data acquired from same url. Now as you can see there is a 'data' added at top events didn't show in the calendar. How to parse this form to show events in calendar?
{
"data": [{
"id": 9,
"title": "Event 1",
"color": "#af2e0e",
"start": "2017-09-18",
"end": "2017-09-20"
}, {
"id": 10,
"title": "Event 2",
"color": "#0b7c0d",
"start": "2017-09-04",
"end": "0000-00-00"
}, {
"id": 11,
"title": "Event 3",
"color": "#378006",
"start": "2017-09-10",
"end": "2017-09-12"
}, {
"id": 13,
"title": "Publication",
"color": "#378006",
"start": "2017-09-15",
"end": "2017-09-16"
}, {
"id": 14,
"title": "other",
"color": "#378006",
"start": "2017-09-05",
"end": "2017-09-06"
}, {
"id": 18,
"title": "other",
"color": "#378006",
"start": "2017-09-18",
"end": "2017-09-19"
}, {
"id": 19,
"title": "Apple",
"color": "#378006",
"start": "2017-09-08",
"end": "2017-09-09"
}, {
"id": 20,
"title": "Developer",
"color": "#378006",
"start": "0000-00-00",
"end": "0000-00-00"
}, {
"id": 21,
"title": "New event",
"color": "#af2e0e",
"start": "2017-09-28",
"end": "2017-09-30"
}, {
"id": 22,
"title": "asdasd",
"color": "#0b7c0d",
"start": "2017-08-28",
"end": "2017-08-31"
}]
}
It is probably a better option to have your source return properly formatted data, but if for some reason you can't do that, you can do it in Javascript.
The Fullcalendar docs describe that you can pass normal $.ajax options in your events source. So you can specify a success callback which returns the data in the format you need.
I tried this with your data locally and it works:
$('#calendar').fullCalendar({
// ... your code
events: {
url: "{{ route('event_calendar.data') }}",
success: function(response) {
// Instead of returning the raw response, return only the data
// element Fullcalendar wants
return response.data;
}
},
// ... rest of your Fullcalendar code