Skip to content

Commit

Permalink
Cyclic graph is up with backtrack calculation of coordinates of misal…
Browse files Browse the repository at this point in the history
…igned vertices
  • Loading branch information
mehulmpt committed Dec 24, 2018
1 parent c8b1425 commit e8e331e
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 57 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "reactjs-graphs",
"version": "1.0.4",
"version": "1.1.0",
"description": "Create branched graphs in ReactJS",
"main": "build/index.js",
"scripts": {
Expand Down
60 changes: 48 additions & 12 deletions source/Graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,13 @@ export default class Graph extends React.Component {
super(props)
this.state = {
list: [],
backtrackList: [],
vertexCoordinates: {}
}

props.vertices.forEach((vertex, index) => {
this.state.list.push({ name: vertex.label, next: [] })
this.state.backtrackList.push({ name: vertex.label, prev: [] })
})

props.edges.map(edge => {
Expand All @@ -24,12 +26,14 @@ export default class Graph extends React.Component {

let mainIndex = 1

let totalYAllowed = props.height
let totalYAllowed = props.orientation === "horizontal" ? props.height : props.width
let vertexGap = props.vertexGap

let horizontalMin = 0, horizontalMax = 0
let verticalMin = props.height/2, verticalMax = props.height/2

console.log(this.state.list)

this.state.list.map(mainVertex => {

const edgesTo = mainVertex.next
Expand All @@ -55,6 +59,8 @@ export default class Graph extends React.Component {

for(let i=0;i<edgesTo.length;i++) {

this.state.backtrackList.find(obj => obj.name == edgesTo[i]).prev.push(mainVertex.name)

const childVertex = edgesTo[i]

const childY = (i + 1)*partitionLength
Expand Down Expand Up @@ -97,10 +103,10 @@ export default class Graph extends React.Component {
if(vertex.label in this.state.vertexCoordinates) {
// ok
} else {
if(flag) throw new Error("Initializing the graph with multiple vertices? Only 1 vertex is supported for now")
if(flag) throw new Error(`Initializing the graph with multiple vertices (${vertex.label})? Only 1 vertex is supported for now`)
// this is the first vertex which was not registered in the for-loop above
flag = true
if(this.props.orientation === 'horizontal') {
if(props.orientation === 'horizontal') {
this.state.vertexCoordinates[vertex.label] = {
x: 0,
y: totalYAllowed/2
Expand All @@ -114,15 +120,40 @@ export default class Graph extends React.Component {
}
})

console.log(this.state.vertexCoordinates)
console.log(this.state.backtrackList)

console.log(verticalMin, verticalMax)
console.log(horizontalMin, horizontalMax)

this.state.backtrackList.forEach(mainVertex => {
// this is for correcting positions of multiple vertices joined to single vertex
const edgeTo = mainVertex.prev
if(edgeTo.length < 2) return

//debugger

//const { y:oldY } = this.state.vertexCoordinates[mainVertex.name]

let sumY = 0

edgeTo.forEach(vertex => {
sumY += this.state.vertexCoordinates[vertex].y
})

sumY /= edgeTo.length

this.state.vertexCoordinates[mainVertex.name].y = sumY

})

//this.state.horizontalShift = -(horizontalMin + horizontalMax)/2
this.state.verticalShift = ((verticalMin + verticalMax) - (props.height))/2
this.state.horizontalShift = ((horizontalMin + horizontalMax) - (props.width))/2


if(!props.perfectlyCenter) {
if(props.orientation === "vertical") this.state.horizontalShift = 0
else this.state.verticalShift = 0
}
}

getEdges(edgeProps) {
Expand All @@ -140,7 +171,7 @@ export default class Graph extends React.Component {
const { x, y } = vertexCoordinates[edgesTo[i]]
elems.push(<Edge
key={vertex + edgesTo[i]}
points={[parentX, parentY, (parentX + x)/2, (parentY + y + (Math.floor(Math.random()*20) - 10))/2, x, y]}
points={[parentX, parentY, (parentX + x + (Math.floor(Math.random()*20) - 10) )/2, (parentY + y + (Math.floor(Math.random()*20) - 10))/2, x, y]}
{...edgeProps}
/>)
}
Expand All @@ -151,26 +182,29 @@ export default class Graph extends React.Component {
render() {
const { vertexCoordinates, horizontalShift, verticalShift } = this.state

const { vertexStroke, vertexStrokeWidth, inactiveVertexFill, activeVertexFill, vertexRadius } = this.props
const vertexProps = { vertexStroke, vertexStrokeWidth, inactiveVertexFill, activeVertexFill, vertexRadius }
const { labelFontSize, vertexStroke, vertexStrokeWidth, inactiveVertexFill, activeVertexFill, vertexRadius } = this.props
const vertexProps = { labelFontSize, vertexStroke, vertexStrokeWidth, inactiveVertexFill, activeVertexFill, vertexRadius }

const { edgeStroke, edgeWidth } = this.props
const edgeProps = { edgeStroke, edgeWidth }

const { vertices, width, height } = this.props
const { vertices, width, height, orientation } = this.props

return (
<Stage width={width} height={height}>
<Layer>
<Group ref={k => this.group = k} offsetX={horizontalShift} offsetY={verticalShift}>
{this.getEdges(edgeProps)}

{this.getEdges(edgeProps)}
{vertices.map((vertex, index) => {
return <Vertex
key={index}
x={vertexCoordinates[vertex.label].x}
y={vertexCoordinates[vertex.label].y}
label={vertex.label}
orientation={orientation}
onClick={_ => vertex.onClick(vertex.label, index, vertex.extras)}
disabled={vertex.disabled}
{...vertexProps}
/>
})
Expand All @@ -186,10 +220,12 @@ Graph.propTypes = {
orientation: PropTypes.oneOf(['horizontal', 'vertical']).isRequired,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
vertexGap: PropTypes.number.isRequired
vertexGap: PropTypes.number.isRequired,
perfectlyCenter: PropTypes.bool.isRequired
}

Graph.defaultProps = {
orientation: 'horizontal',
vertexGap: 100
vertexGap: 100,
perfectlyCenter: false
}
68 changes: 47 additions & 21 deletions source/Vertex.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { Circle, Text } from 'react-konva'
import { Circle, Text, Group } from 'react-konva'
import PropTypes from 'prop-types'

export default class Vertex extends React.Component {
Expand All @@ -10,55 +10,79 @@ export default class Vertex extends React.Component {
this.mouseOutVertex = this.mouseOutVertex.bind(this)
this.state = {
vertexFill: props.inactiveVertexFill,
textOffsetX: 0
textOffsetX: 0,
textOffsetY: 0,
showTextNode: true
}
}

componentDidMount() {
this.setState({
textOffsetX: this.text.width() / 2
textOffsetX: this.text.width() / 2,
textOffsetY: this.text.height() / 2,
showTextNode: !this.props.disabled
})
}

shouldComponentUpdate(nextProps, nextState) {
return this.state != nextState
}

mouseOutVertex() {
document.body.style.cursor = 'default'
this.setState({
vertexFill: this.props.inactiveVertexFill
})

if(this.props.disabled) {
// disabled vertex
this.setState({
showTextNode: false
})
} else {
this.setState({
vertexFill: this.props.inactiveVertexFill
})
}
}

mouseInVertex() {
document.body.style.cursor = 'pointer'
this.setState({
vertexFill: this.props.activeVertexFill
})
if(this.props.disabled) {
this.setState({
showTextNode: true
})
} else {
this.setState({
vertexFill: this.props.activeVertexFill
})
}
}

render() {

const { x, y, label, onClick, vertexStroke, vertexStrokeWidth, vertexRadius } = this.props
const { vertexFill, textOffsetX } = this.state
const { disabled, x, y, label, onClick, vertexStroke, vertexStrokeWidth, vertexRadius, orientation, labelFontSize } = this.props
const { vertexFill, textOffsetX, textOffsetY, showTextNode } = this.state

return (
<>
<Text
<Group>
{showTextNode ? <Text
ref={node => this.text = node }
x={x}
y={y-30}
x={orientation === "horizontal" ? x : x - textOffsetX - vertexRadius - vertexStrokeWidth - 5 }
y={orientation === "horizontal" ? y - textOffsetY * 2 - vertexRadius - vertexStrokeWidth : y - textOffsetY }
offsetX={textOffsetX}
text={label} />
fontSize={labelFontSize}
text={label} /> : null }
<Circle
x={x}
onClick={onClick}
onMouseEnter={this.mouseInVertex}
onMouseLeave={this.mouseOutVertex}
y={y}
stroke={vertexStroke}
filter
stroke={!disabled ? vertexStroke : "gray" }
strokeWidth={vertexStrokeWidth}
fill={vertexFill}
fill={!disabled ? vertexFill : "gray" }
radius={vertexRadius}
/>
</>
</Group>
)
}
}
Expand All @@ -70,13 +94,15 @@ Vertex.propTypes = {
vertexStrokeWidth: PropTypes.number.isRequired,
inactiveVertexFill: PropTypes.string.isRequired,
activeVertexFill: PropTypes.string.isRequired,
vertexRadius: PropTypes.number.isRequired
vertexRadius: PropTypes.number.isRequired,
labelFontSize: PropTypes.number.isRequired
}

Vertex.defaultProps ={
vertexStroke: "#df6766",
vertexStrokeWidth: 3,
inactiveVertexFill: "white",
activeVertexFill: "#df6766",
vertexRadius: 10
vertexRadius: 10,
labelFontSize: 12
}
52 changes: 29 additions & 23 deletions source/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,39 @@ const onClick = (label, index, extras) => {
}

const vertices = [
{ label: "Here it begins", onClick, extras: "Some helper data" },
{ label: "HTML", onClick },
{ label: "CSS", onClick },
{ label: "Sass", onClick },
{ label: "JavaScript", onClick },
{ label: "Bootstrap", onClick },
{ label: "jQuery", onClick },
{ label: "ReactJS", onClick },
{ label: "Jest", onClick },
{ label: "Angular", onClick },
{ label: "Vue", onClick },
{ label: "Redux", onClick },
{ label: "React Material", onClick },
{ label: "Vuetify", onClick },
{ label: "Sass", onClick, disabled: false },
{ label: "JavaScript", onClick, disabled: false },
// { label: "Bootstrap", onClick, disabled: false },
// { label: "jQuery", onClick, disabled: false },
{ label: "React.js", onClick, disabled: false },
{ label: "Angular", onClick, disabled: false },
{ label: "Vue", onClick, disabled: false },
// { label: "Redux", onClick, disabled: false },
// { label: "Vuetify", onClick, disabled: false },
{ label: "Node.js", },
//{ label: "GitHub", },
/*{ label: "MongoDB", },
{ label: "MySQL", },
{ label: "PHP", },
{ label: "nginx", },
{ label: "Apache", },*/
]

const edges = [
["Here it begins", "HTML"],
["HTML", "CSS"],
["CSS", "JavaScript"],
["CSS", "Sass"],
["JavaScript", "jQuery"],
["jQuery", "Bootstrap"],
["jQuery", "ReactJS"],
["jQuery", "Angular"],
["jQuery", "Vue"],
["ReactJS", "Redux"],
["Redux", "React Material"],
["React Material", "Jest"],
["Vue", "Vuetify"],
["Sass", "Vue"],
["JavaScript", "React.js"],
["JavaScript", "Angular"],
["JavaScript", "Vue"],
["Angular", "Node.js"],
["React.js", "Node.js"],
["Vue", "Node.js"],
//["React.js", "Redux"],
//["Vue", "Vuetify"],
]


Expand All @@ -49,5 +52,8 @@ ReactDOM.render(<Graph
vertexStroke="#df6766"
edgeStroke="#ebb2b2"
edgeWidth={2}
vertexRadius={10}
vertexRadius={15}
vertexGap={200}
labelFontSize={20}
perfectlyCenter={true}
/>, document.getElementById('root'))
1 change: 1 addition & 0 deletions source/konva.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const Konva = require("../node_modules/konva/src/Core")
require("../node_modules/konva/src/shapes/Circle")
require("../node_modules/konva/src/shapes/Line")
require("../node_modules/konva/src/shapes/Text")
require("../node_modules/konva/src/shapes/Text")

require("../node_modules/konva/src/Animation")

Expand Down

0 comments on commit e8e331e

Please sign in to comment.