I have been doing research on several free organizational chart libraries. There are some that I tried: orgchart (by dabeng), d3-mitch-tree and Treant.js. I was successful in using the former two in my React app, although only for basic usage.
I just tried hard to do the same with Treant.js. It is not straight-forward. I had to learn quickly about CommonJs before working around the problems with Treant.js.
After walking through its source code, I saw that it used CommonJs module system, so its javascript module have to be included using require statement, not import statement. You can see my code below.
But, when running the app, it displayed error:
"Raphael is not defined"
When debugging, I found the cause of the error. Treant.js file depends on raphael library, which is used in its handleOverflow function. So I added one line in that function of Treant.js file to include the dependency as follows:
// Create Raphael instance, set scrollbars if necessary
handleOverflow: function(treeWidth, treeHeight) {
// I added this statement which didn't exist in original file
var Raphael = require("./vendor/raphael")
// ...
Here is my code :
import React from "react";
import "treant-js/Treant.css"
import "treant-js/basic-example.css"
var Treant = require("treant-js/Treant")
export default class MyTreantJs extends React.Component {
constructor(props) {
super(props);
this.treant = null
this.chart_config = null
}
componentDidMount() {
const loginpathname = window.sessionStorage.getItem("appHomePathName", homepathname)
const index = loginpathname.indexOf("public")
const homepathname = loginpathname.substring(0,index)
const imageurl = homepathname + "/public/images/headshots/"
const config = {
container: "#basic-example",
connectors: {
type: 'step'
},
node: {
HTMLclass: 'nodeExample1'
}
},
ceo = {
text: {
name: "Mark Hill",
title: "Chief executive officer",
contact: "Tel: 01 213 123 134",
},
image: imageurl + "2.jpg"
},
cto = {
parent: ceo,
text:{
name: "Joe Linux",
title: "Chief Technology Officer",
},
stackChildren: true,
image: imageurl + "1.jpg"
},
cbo = {
parent: ceo,
stackChildren: true,
text:{
name: "Linda May",
title: "Chief Business Officer",
},
image: imageurl + "5.jpg"
},
cdo = {
parent: ceo,
text:{
name: "John Green",
title: "Chief accounting officer",
contact: "Tel: 01 213 123 134",
},
image: imageurl + "6.jpg"
},
cio = {
parent: cto,
text:{
name: "Ron Blomquist",
title: "Chief Information Security Officer"
},
image: imageurl + "8.jpg"
},
ciso = {
parent: cto,
text:{
name: "Michael Rubin",
title: "Chief Innovation Officer",
contact: {val: "we@aregreat.com", href: "mailto:we@aregreat.com"}
},
image: imageurl + "9.jpg"
},
cio2 = {
parent: cdo,
text:{
name: "Erica Reel",
title: "Chief Customer Officer"
},
link: {
href: "http://www.google.com"
},
image: imageurl + "10.jpg"
},
ciso2 = {
parent: cbo,
text:{
name: "Alice Lopez",
title: "Chief Communications Officer"
},
image: imageurl + "7.jpg"
},
ciso3 = {
parent: cbo,
text:{
name: "Mary Johnson",
title: "Chief Brand Officer"
},
image: imageurl + "4.jpg"
},
ciso4 = {
parent: cbo,
text:{
name: "Kirk Douglas",
title: "Chief Business Development Officer"
},
image: imageurl + "11.jpg"
}
this.chart_config = [
config,
ceo,
cto,
cbo,
cdo,
cio,
ciso,
cio2,
ciso2,
ciso3,
ciso4
];
this.treant = new Treant(this.chart_config)
}
render(){
return (
<div id="basic-example" style={{height:"600px", width:"1200px"}}></div>
);
}
}
Here, the basic-example.css file was copied from the examples folder.
The configuration for the chart was taken from the examples folder too. I used sessionStorage of the browser to find location of the images.
So far, my code worked well.
EDIT :
The above code still doesn't work. Do not modify the Treant.js source code. Instead, use the following :
import React from "react";
import "treant-js/Treant.css"
import "treant-js/examples/basic-example/basic-example.css"
import Raphael from "raphael";
window.Raphael = Raphael
var Treant = require("treant-js/Treant")
Treant = Treant.Treant
Treant doesn't import raphael, but it expects raphael instance to be globally available. That's why after importing raphael in our app we need the statement :
window.Raphael = Raphael
Notice the statement :
Treant = Treant.Treant
This is necessary, as Treant (when looking at the console) is an object that has property also named Treant.