Is it possible if I can directly connect all children to 1 parent in Balkan OrgChart.js?
This is what I have as a starting point from the documentation of OrgChart.js.
window.onload = function () {
OrgChart.templates.family_template = Object.assign({}, OrgChart.templates.ana);
OrgChart.templates.family_template.size = [86, 86];
OrgChart.templates.family_template.plus = "";
OrgChart.templates.family_template.minus = "";
OrgChart.templates.family_template.rippleRadius = 40;
OrgChart.templates.family_template.name = '<text style="font-size: 12px;" fill="#000000" x="43" y="100" text-anchor="middle">{val}</text>';
OrgChart.templates.family_template.title = '<text style="font-size: 12px;" fill="#aeaeae" x="43" y="115" text-anchor="middle">{val}</text>';
OrgChart.templates.family_template.img = '<clipPath id="{randId}"><circle cx="43" cy="43" r="38.5"></circle></clipPath></circle><image preserveAspectRatio="xMidYMid slice" clip-path="url(#{randId})" xlink:href="{val}" x="3" y="3" width="80" height="80"></image>';
OrgChart.templates.family_template.node = '<circle stroke-width="3" fill="none" stroke="#aeaeae" cx="43" cy="43" r="41.5"></circle>';
OrgChart.templates.family_template.defs = '<g transform="matrix(0.05,0,0,0.05,-13,-15.5)" id="baby"><circle cx="260" cy="310" r="200" fill="#ffffff"></circle><path fill="#aeaeae" d="m468.64 268.32h-13.591c-18.432-89.348-95.612-157.432-189.139-161.798-.501-.185-1.015-.348-1.545-.482-18.363-4.622-31.188-22.595-31.188-43.707 0-17.828 14.468-32.333 32.252-32.333 12.573 0 22.802 10.258 22.802 22.866 0 8.284 6.716 15 15 15s15-6.716 15-15c0-29.15-23.687-52.866-52.802-52.866-34.326 0-62.252 27.962-62.252 62.333 0 17.876 5.828 34.443 15.769 47.432-80.698 15.127-144.725 78.25-161.291 158.555h-13.591c-24.103 0-43.712 19.596-43.712 43.683 0 24.086 19.609 43.682 43.712 43.682h14.692c20.935 89.871 101.582 157.018 197.596 157.018s176.66-67.148 197.596-157.018h14.692c24.103 0 43.712-19.596 43.712-43.682 0-24.087-19.609-43.683-43.712-43.683zm-265.054 55.257c-8.284-.024-14.981-6.758-14.958-15.043.007-2.337-.708-13.999-15.481-14.041-.026 0-.053 0-.08 0-14.697 0-15.475 11.62-15.481 13.953-.023 8.284-6.75 15.007-15.043 14.957-8.284-.024-14.98-6.759-14.957-15.043.038-13.322 5.349-25.101 14.955-33.166 8.223-6.904 19.065-10.702 30.543-10.702h.148c11.534.033 22.412 3.896 30.63 10.876 9.559 8.12 14.803 19.928 14.765 33.25-.023 8.27-6.735 14.957-14.999 14.957-.013.002-.027.002-.042.002zm52.766 129.374c-26.485 0-48.033-21.533-48.033-48.002 0-8.284 6.716-15 15-15s15 6.716 15 15c0 9.926 8.089 18.002 18.033 18.002s18.033-8.076 18.033-18.002c0-8.284 6.716-15 15-15s15 6.716 15 15c-.001 26.469-21.548 48.002-48.033 48.002zm113.765-129.374c-.015 0-.029 0-.044 0-8.284-.024-14.98-6.759-14.957-15.043.016-5.445-1.993-9.263-6.14-11.673-5.407-3.142-13.27-3.165-18.695-.053-4.161 2.387-6.191 6.193-6.207 11.638-.023 8.27-6.735 14.957-14.999 14.957-.015 0-.029 0-.043 0-8.284-.024-14.981-6.758-14.958-15.043.046-16.149 7.802-29.845 21.281-37.576 14.814-8.497 33.929-8.443 48.695.138 13.434 7.807 21.112 21.547 21.066 37.696-.023 8.271-6.735 14.959-14.999 14.959z"/> </g>';
OrgChart.templates.family_template_blue = Object.assign({}, OrgChart.templates.family_template);
OrgChart.templates.family_template_blue.node = '<circle stroke-width="3" fill="none" stroke="#039BE5" cx="43" cy="43" r="41.5"></circle>';
var chart = new OrgChart(document.getElementById("tree"), {
template: "family_template",
enableSearch: false,
siblingSeparation: 100,
nodeBinding: {
field_0: 'id',
name: "name",
title: "title",
img: "img",
},
tags: {
blue: {
template: "family_template_blue"
}
}
});
chart.on('render-link', function(sender, args){
if (args.cnode.ppid != undefined){
args.html += '<use xlink:href="#baby" x="'+ args.p.xa +'" y="'+ args.p.ya +'"/>';
}
});
chart.load([
{ id: 1, tags: ["blue"], name: "King George VI", img: "https://cdn.balkan.app/shared/f1.png"},
{ id: 2, pid: 1, tags: ["left-partner"], name: "Queen Elizabeth", img: "https://cdn.balkan.app/shared/f2.png" },
{ id: 3, pid: 1, tags: ["partner"], name: "Queen Elizabeth", img: "https://cdn.balkan.app/shared/f2.png" },
{ id: 4, pid: 1, name: "Queen Elizabeth", title: "The Queen Mother", img: "https://cdn.balkan.app/shared/f2.png" },
{ id: 5, pid: 1, tags: ["right-partner"], name: "Queen Elizabeth", img: "https://cdn.balkan.app/shared/f2.png" },
{ id: 6, pid: 1, tags: ["partner"], name: "Queen Elizabeth", img: "https://cdn.balkan.app/shared/f2.png" },
]);
};
And this is the result for that one.
Is there a possibilty to have a result like this?
I'm stuck on this point and I don't know where to proceed next.
You can not do this with Org Chart JS.
It will be possible to do it with some of the future products of Balkan APP.
For now you can choose one of the libraries here:
https://code.tutsplus.com/articles/best-free-javascript-graph-visualization-libraries--cms-41710
Related
I have state data like that:
const IssuesList = () => {
const [issuesList, setIssuesList] = useState([
{
groupId: 0,
groupData: "19-07-2016",
groupIssues: [
{
id: 0,
title: "Page changes",
star: true,
},
{
id: 1,
title: "Review of last issues",
star: true,
},
],
},
{
groupId: 1,
groupData: "18-07-2016",
groupIssues: [
{
id: 2,
title: "Visual UI Update Review",
star: false,
},
{
id: 3,
title: "Sidebar changes",
star: false,
},
],
},
{
groupId: 2,
groupData: "15-07-2016",
groupIssues: [
{
id: 4,
title: "Crash update",
star: false,
},
{
id: 5,
title: "Page visual UI Update Review",
star: true,
},
{
id: 6,
title: "Sidebar update",
star: false,
},
],
},
{
groupId: 3,
groupData: "14-07-2016",
groupIssues: [
{
id: 7,
title: "Crash issue",
star: true,
},
{
id: 8,
title: "Visual update & Crash resolve",
star: true,
},
{
id: 9,
title: "Header changes",
star: false,
},
],
},
]);
return (
<div className="issuesList">
{issuesList.map((group) => (
<IssueGroup
key={group.groupId}
group={group}
setIssuesList={setIssuesList}
issuesList={issuesList}
/>
))}
</div>
);
};
export default IssuesList;
I want to change only the star parameter in groupIssues when I click an specyfic icon in a StarIcon component:
const StarIcon = ({ star, index, id, setIssuesList, issuesList, group }) => {
const issueStar = group.groupIssues[index].star;
return (
<svg
xmlns="http://www.w3.org/2000/svg"
//xmlns:xlink="http://www.w3.org/1999/xlink"
preserveAspectRatio="xMidYMid"
width="17"
height="16"
viewBox="0 0 17 16"
className={star ? "staricon filled" : "staricon unfilled"}
onClick={() => {
// setIssuesList() TODO
}}
>
<path
d="M8.500,0.000 L11.301,5.028 L16.999,6.112 L13.033,10.302 L13.753,16.000 L8.500,13.561 L3.247,16.000 L3.967,10.302 L0.001,6.112 L5.699,5.028 L8.500,0.000"
fill={star ? "#21233d" : "#fff"}
stroke={star ? "none" : "#e0e0e0"}
/>
</svg>
);
};
export default StarIcon;
What is the best way to do that in that set of data. I know that spread operator can be helpfull there but i have no idea how to implement that in this data structure when We have array of objects and then we need to get into another array in specyfic object. Maybe changing the data structure will be better or breaking it into two arrays?
Ui view here
You should use a deep copy of the object, spread operator creates only a shallow copy.
Example:
const changeStar = (grpId, issueId) => {
setIssuesList(list => (
list.map(item => (
item.groupId === grpId ?
{...item, groupIssues: item.groupIssues.map(issue => (
issue.id === issueId ? {...issue, star: !issue.star} : issue
))}
: item
)
))
}
Explanation:
map function creates an entirely new array. It will return the elements as it is unless you have matching groupIds. Inside the groupIds, you will change the item based on the id. In the end, you deep copied the object and set an entirely new array with the desired result.
I think you need something like this: copy of current issuesList state. Update the specific star from that copy of state. Set the updated state.
Here is a working sandbox example: https://codesandbox.io/s/bold-browser-cnfw3?file=/src/App.js
I'm playing around with E-commerce application. I have API call, api call returns Data like below, I want to paint all images inside products to HTML using map function, now it's returns single generated element, what I am doing wrong? thanks in advance
var Result = {
purchases: [{
products: [{
product_id: 264772179145,
name: "Acer Chromebook 315 15.6",
image_url: "https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F"
},
{
product_id: 264772179145,
name: "Acer Chromebook 315 15.6",
image_url: "https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F"
},
],
timestamp: 1618215999,
amount: 73457
},
{
products: [{
product_id: 264772179145,
name: "Acer Chromebook 315 15.6",
image_url: "https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F"
}],
timestamp: 1618216092,
amount: 73457
},
{
products: [{
product_id: 154061997658,
name: "adidas Wheeled Team Bag Men`s",
image_url: "https://i.ebayimg.com/00/s/MTYwMFgxNjAw/z/JYAAAOSwwRZf9n2L/$_1.JPG?set_id=880000500F"
}],
timestamp: 1618217956,
amount: 34566
}
],
};
function getProducts() {
var res;
var purchases = Result.purchases.map(purchases => {
var x = purchases.amount;
res = purchases.products.map(el => {
return `<div class="all-img"><img style="height:50px"; width:50px; src="${el.image_url}">
<div class="amount">${x}</div>
</div>`
})
})
document.getElementById("transactionBoxes").innerHTML = res.join('')
}
<div id="transactionBoxes">
</div>
<button onclick="getProducts()">append</button>
I shortened the function so you won't have to use the return keyword and the extra variables
var Result = {"purchases":[{"products":[{"product_id":264772179145,"name":"Acer Chromebook 315 15.6","image_url":"https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F"},{"product_id":264772179145,"name":"Acer Chromebook 315 15.6","image_url":"https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F"},{"product_id":264772179145,"name":"Acer Chromebook 315 15.6","image_url":"https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F"},{"product_id":264772179145,"name":"Acer Chromebook 315 15.6","image_url":"https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F"}],"timestamp":1618215999,"amount":73457},{"products":[{"product_id":264772179145,"name":"Acer Chromebook 315 15.6","image_url":"https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F"}],"timestamp":1618216092,"amount":73457},{"products":[{"product_id":154061997658,"name":"adidas Wheeled Team Bag Men`s","image_url":"https://i.ebayimg.com/00/s/MTYwMFgxNjAw/z/JYAAAOSwwRZf9n2L/$_1.JPG?set_id=880000500F"}],"timestamp":1618217956,"amount":34566}]};
function getProducts() {
const purchases = Result.purchases.map(purchase => purchase.products.map(el => `<div class="all-img"><img style="height:50px"; width:50px; src="${el.image_url}"><div class="amount">${purchase.amount}</div></div>`).join(''));
document.getElementById("transactionBoxes").innerHTML = purchases.join('');
}
document.querySelector('button').addEventListener('click', getProducts);
<div id="transactionBoxes"></div>
<button>append</button>
You can improve two things here:
You can nest map functions to be sure to render your whole collection
style="height:50px"; width:50px; => style="height:50px; width:50px;"
var Result = {
purchases: [
{
products: [
{
product_id: 264772179145,
name: 'Acer Chromebook 315 15.6',
image_url: 'https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F',
},
{
product_id: 264772179145,
name: 'Acer Chromebook 315 15.6',
image_url: 'https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F',
},
],
timestamp: 1618215999,
amount: 73457,
},
{
products: [
{
product_id: 264772179145,
name: 'Acer Chromebook 315 15.6',
image_url: 'https://i.ebayimg.com/00/s/MTAwMFgxMDAw/z/EAcAAOSw6pJe8Lwo/$_1.JPG?set_id=880000500F',
}],
timestamp: 1618216092,
amount: 73457,
},
{
products: [
{
product_id: 154061997658,
name: "adidas Wheeled Team Bag Men's",
image_url: 'https://i.ebayimg.com/00/s/MTYwMFgxNjAw/z/JYAAAOSwwRZf9n2L/$_1.JPG?set_id=880000500F',
}],
timestamp: 1618217956,
amount: 34566,
},
],
};
function getProducts() {
var res = Result.purchases
.map((purchases) => {
return purchases.products
.map((product) => {
return (`
<div class="all-img">
<img style="height:50px; width:50px;" src="${product.image_url}" alt="${product.name}" />
<div class="amount">${purchases.amount}</div>
</div>
`)
})
.join('')
})
.join('');
document.getElementById('transactionBoxes').innerHTML = res;
}
<div id="transactionBoxes"></div>
<button onclick="getProducts()">append</button>
You should also read the map documentation, you tried to use it as a for/forEach function.
Try surrounding the return statement with parentheses. I program in React Native and it is required to surround the return with parentheses if it has multiple lines.
res = purchases.products.map(el => {
return (`<div class="all-img"><img style="height:50px"; width:50px; src="${el.image_url}">
<div class="amount">${x}</div>
</div>`)
})
I try to access to 0th index of the array in my following object:
let spaceship = {
passengers: null,
telescope: {
yearBuilt: 2018,
model: "91031-XLT",
focalLength: 2032
},
crew: {
captain: {
name: 'Sandra',
degree: 'Computer Engineering',
encourageTeam() {
console.log('We got this!')
},
'favorite foods': ['cookies', 'cakes', 'candy', 'spinach']
}
},
engine: {
model: "Nimbus2000"
},
nanoelectronics: {
computer: {
terabytes: 100,
monitors: "HD"
},
'back-up': {
battery: "Lithium",
terabytes: 50
}
}
};
I tried following code:
let capFave=spaceship.crew.captain['favorite foods']['favorite foods[0]'];
and
let capFave=spaceship.crew.captain['favorite foods[0]'];
but it returns undefined or shows syntax error.
Just use [0] after spaceship.crew.captain['favorite foods'], like spaceship.crew.captain['favorite foods'][0], since spaceship.crew.captain['favorite foods'] returns an array, and [0] returns the value in the 0th index of an array.
let spaceship = {
passengers: null,
telescope: {
yearBuilt: 2018,
model: "91031-XLT",
focalLength: 2032
},
crew: {
captain: {
name: 'Sandra',
degree: 'Computer Engineering',
encourageTeam() { console.log('We got this!') },
'favorite foods': ['cookies', 'cakes', 'candy', 'spinach']
}
},
engine: {
model: "Nimbus2000"
},
nanoelectronics: {
computer: {
terabytes: 100,
monitors: "HD"
},
'back-up': {
battery: "Lithium",
terabytes: 50
}
}
};
console.log(spaceship.crew.captain['favorite foods']);
console.log(spaceship.crew.captain['favorite foods'][0]);
I'm looking for a way to remove array other elements.
But I don't know how to do it.
This is my array:
musics: [
{
id: 1,
cover: require('~/assets/images/cover/music/ali_zand_vakili_jadeh_shab.jpg'),
title: 'جاده شب',
artist: 'علی زند وکیلی',
source: 'http://media.mtvpersian.net/2019/Mar/21/Ali%20Zand%20Vakili%20-%20Jadeh%20Shab.mp3'
},
{
id: 2,
cover: require('~/assets/images/cover/music/amin_hayaei_divoone_misazi.jpg'),
title: 'دیوونه میسازی',
artist: 'امین حیایی',
source: 'https://cdnmrtehran.ir/media/mp3s_128/Amin_Hayaei/Singles/amin_hayaei_divoone_misazi.mp3'
},
{
id: 3,
cover: require('~/assets/images/cover/music/emad_talebzadeh_maghrour.jpg'),
title: 'مغرور',
artist: 'عماد طالب زاده',
source: 'https://cdnmrtehran.ir/media/mp3s_128/Emad_Talebzadeh/Singles/emad_talebzadeh_maghrour.mp3'
},
{
id: 4,
cover: require('~/assets/images/cover/music/farzad_farzin_jazzab.jpg'),
title: 'جذاب',
artist: 'فرزاد فرزین',
source: 'https://cdnmrtehran.ir/media/mp3s_128/Farzad_Farzin/Singles/farzad_farzin_jazzab.mp3'
},
{
id: 5,
cover: require('~/assets/images/cover/music/hamid_sefat_ajayeb_shahr_merat_remix.jpg'),
title: 'عجایب شهر رمیکس',
artist: 'حمید صفت',
source: 'https://cdnmrtehran.ir/media/mp3s_128/Hamid_Sefat/Singles/hamid_sefat_ajayeb_shahr_merat_remix.mp3'
}
],
How to remove all elements except element with id of 3 ?
To remove all the even indexed elements you could use the following:
musics = musics.filter((e, i) => i % 2 == 0)
To remove the odd ones simply change the == with !=
var musics= [{id: 1,cover: '~/assets/images/cover/music/ali_zand_vakili_jadeh_shab.jpg',title: 'جاده شب',artist: 'علی زند وکیلی',source: 'http://media.mtvpersian.net/2019/Mar/21/Ali%20Zand%20Vakili%20-%20Jadeh%20Shab.mp3'},
{id: 2,cover: '~/assets/images/cover/music/amin_hayaei_divoone_misazi.jpg',title: 'دیوونه میسازی',artist: 'امین حیایی',source: 'https://cdnmrtehran.ir/media/mp3s_128/Amin_Hayaei/Singles/amin_hayaei_divoone_misazi.mp3'},
{id: 3,cover: '~/assets/images/cover/music/emad_talebzadeh_maghrour.jpg',title: 'مغرور',artist: 'عماد طالب زاده',source: 'https://cdnmrtehran.ir/media/mp3s_128/Emad_Talebzadeh/Singles/emad_talebzadeh_maghrour.mp3'},
{id: 4,cover: '~/assets/images/cover/music/farzad_farzin_jazzab.jpg',title: 'جذاب',artist: 'فرزاد فرزین',source: 'https://cdnmrtehran.ir/media/mp3s_128/Farzad_Farzin/Singles/farzad_farzin_jazzab.mp3'},
{id: 5,cover:'~/assets/images/cover/music/hamid_sefat_ajayeb_shahr_merat_remix.jpg',title: 'عجایب شهر رمیکس',artist: 'حمید صفت',source: 'https://cdnmrtehran.ir/media/mp3s_128/Hamid_Sefat/Singles/hamid_sefat_ajayeb_shahr_merat_remix.mp3'}]
var result =[];
musics.forEach(function(item){
if(item.id == 3){
result.push(item);
}
});
console.log(result);
You can use filter: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
musics = musics.filter (x => x.id == 3)
I have a section on my website that is 100% wide and 450 pixels tall.
My html looks like so...
<section class="interactive-banner">
<figure></figure>
</section>
I want each 'figure' element to be 150 pixels wide and 150 pixels tall, I want to generate the 'figure' html automatically and randomly with jQuery, and to consist of some inner html.
I have the following...
$(function(){
var people = [
{ id: 1 },
{ id: 2 }
];
var figure = $('figure');
w = 1500;
h = 450;
var counter = 0;
var data = people[Math.floor(Math.random()*people.length)];
(function nextFade() {
counter++;
figure.clone().html(data.name).appendTo('.interactive-banner').hide().fadeIn(150, function() {
if(counter < 30) nextFade();
});
})();
});
I want each figure element to fade in 1 after the other, in total I will only have 7 original figures, only these 7 will be randomly cloned until i have 30 iterations in total, I want the figure html to contain the data inside each object in my people array, so each figure is an object so to speak, output as so...
<figure>
<img src="[image src from object inside array]" />
<div class="information">
<h5>[name from object inside of array ]</h5>
<p>[job title from object inside of array ]</p>
</div>
</figure>
only at the minute its being output as so...
<figure style="display: block;">
Chris
</figure>
Ive created an example here, as you see however each figure contains the same information...
http://jsfiddle.net/pGmeE/
http://jsbin.com/isopin/1/edit
Don't populate your section initially and don't clone your figure element with jQ. Rather create a new one at every loop iteration.
<section class="interactive-banner"></section>
jQ:
$(function(){
var people = [
{ id: 1, name: 'Justin', title: 'Head Designer', bio: 'This is Justin\'s Biography.', image: 'justin.jpg' },
{ id: 2, name: 'Chris', title: 'Head Developer', bio: 'This is Chris\' Biography.', image: 'chris.jpg' },
{ id: 3, name: 'Sam', title: 'Developer', bio: 'This is Sam\'s Biography.', image: 'sam.jpg' },
{ id: 4, name: 'Haythem', title: 'Developer', bio: 'This is Haythem\'s Biography.', image: 'haythem.jpg' },
{ id: 5, name: 'Geoff', title: 'Designer', bio: 'This is Geoff\'s Biography.', image: 'geoff.jpg' },
{ id: 6, name: 'Liam', title: 'Designer', bio: 'This is Liam\'s Biography.', image: 'liam.jpg' }
];
w = 1500;
h = 450;
var counter = 0;
(function nextFade() {
counter++;
// Give "random" a chance to get random again
var data = people[Math.floor(Math.random()*people.length)];
// Now create a new Figure element:
var figure = $('<figure />');
figure.html(data.name).appendTo('.interactive-banner').hide().fadeIn(150, function() {
if(counter < 30) nextFade();
});
})();
});