Skip to content

caballerofelipe/vuejs_tree

Repository files navigation

vuejs_tree

A tree graph made using Vue.js and html+css.

See the demo.

Simple tree displayed

Requirements

  • Requirements
    • (Node.js)
    • npm (Should come with node)
  • Used Vue CLI version: 4.2.2 .

Intro

This is a small project which shows a part of a larger project. The idea is to create an example of how to create a graphical tree structure using Vue.js.

This project uses:

Functionalities

This is what this project does:

  • Creates a graphical tree structure (graph) based on a JSON structure managed in the store (Vuex).
  • Allows zoom (with buttons).
  • Shows current store (toggle with a button).
  • Add lines to join the bottom of the parent node to the top of a node creating a hierarchical structure.
  • Using drag and drop, allows nodes movement from one location to another. A node can be moved on the sides of an existing node with children and can be moved below a node without children.
  • Add new nodes using drag and drop with the '+' node above.

To do

This are some functionalities that would be nice and maybe will be done in the future:

  • Add a small box showing the full tree with a box showing the current view.

Using CSS for the tree

I've tested two ways of implementing the tree using only CSS: using flexbox and using inline-block.

Note: I also thought about using CSS grid but that requires knowing the column count and changing CSS accordingly which would complicate things.

Using Flexbox

This is how the tree is constructed using Flexbox.

/* Only relevant parts displayed */

.nodeRow {
	overflow: auto;
	display: flex;
	flex-direction: row;
	flex-wrap: nowrap;
	justify-content: stretch;
	align-items: flex-start;
}

Pro:

  • The structure is rigid.

Con:

  • When the content is not bigger than the container it's taken to the left (not centered).
  • Using justify-content: center; does work when the zoom is far but when the zoom is at initial state and the content is larger than the container it gets cut off (This happens in Chrome version 80).

Here's an idea to avoid the cons but I haven't tried it:

When zooming there could be a JavaScript computation to see if the tree is smaller than its container, in that case use justify-content: center;. The calculation would take the first .nodeRow children and would sum their full width (withh padding, outline, margin, etc.) and if their sum is smaller use justify-content: center;; if it's not use justify-content: strech;.

Using inline-block

This is how the tree is constructed using inline-block.

/* Only relevant parts displayed */

.nodeRow {
	white-space: nowrap; /* Whithout this the tree is unordered when there is not enough space. */
	overflow: auto;
}

.node {
	display: inline-block;
	vertical-align: top;
}

Possible con:

  • Maybe with inline-block the tree could be unordered easily when changing outside CSS but I haven't done any testing.

Project setup

# To see the project in action, after getting the files on hard drive (git, download or whatever), run:
npm install

# Compiles and hot-reloads for development:
npm run serve

# Compiles and minifies for production:
npm run build

# Lints and fixes files:
npm run lint

Custom configuration, see Configuration Reference.

Initial Installation

This is what I did on the initial installation.

Vue CLI install

Install Vue CLI (Installation | Vue CLI):

npm install -g @vue/cli

Creating the project

This is how I created the Vue.js project (Creating a Project | Vue CLI):

vue create vuejs_tree

And these are the selections made:

Vue CLI v4.5.4
? Please pick a preset:
  Default ([Vue 2] babel, eslint)
  Default (Vue 3 Preview) ([Vue 3] babel, eslint)
❯ Manually select features
? Check the features needed for your project:
 ◉ Choose Vue version
 ◉ Babel
 ◯ TypeScript
 ◯ Progressive Web App (PWA) Support
 ◉ Router
 ◉ Vuex
 ◉ CSS Pre-processors
 ◉ Linter / Formatter
❯◉ Unit Testing
 ◯ E2E Testing
? Choose a version of Vue.js that you want to start the project with
❯ 2.x
  3.x (Preview)
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n)
 n
? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default):
❯ Sass/SCSS (with dart-sass)
  Sass/SCSS (with node-sass)
  Less
  Stylus
? Pick a linter / formatter config:
❯ ESLint with error prevention only
  ESLint + Airbnb config
  ESLint + Standard config
  ESLint + Prettier
? Pick additional lint features:
❯◉ Lint on save
 ◯ Lint and fix on commit
? Pick a unit testing solution:
  Mocha + Chai
❯ Jest
? Where do you prefer placing config for Babel, ESLint, etc.?
❯ In dedicated config files
  In package.json
? Save this as a preset for future projects? (y/N) n

Extras

How to access a variable in the console

If you need to see or play with some variable in the console or elsewhere in the code, you can link it to the window as inside Vue.js variables are scoped.

// This is just an example, theState can be changed to whatever
// careful it doesn't class with something else.
// In this example we want to expose the state but it can be anything.
window.theState = state;

About the '@' symbol

It can be used in two ways:

- As v-on More info: ([API — Vue.js](https://vuejs.org/v2/api/#v-on)).

Process Tree

You can do whatever you want with the process tree but if you want to try different structures here are a large one and a small one.

Small version

processTree: [
  {nodeValue: 'value', id: '', processTree: [
	{nodeValue: 'value', id: '', processTree: []}
  ]},
  {nodeValue: 'value', id: '', processTree: [
	{nodeValue: 'value', id: '', processTree: [
	  {nodeValue: 'value', id: '', processTree: []},
	  {nodeValue: 'value', id: '', processTree: []}
	]}
  ]}
]

Large version

processTree: [
  // {nodeValue: 'value', id: '', processTree: [  // Uncomment this to get one main node
	{nodeValue: 'value', id: '', processTree: [
	  {nodeValue: 'value', id: '', processTree: []}
	]},
	{nodeValue: 'value', id: '', processTree: [
	  {nodeValue: 'value', id: '', processTree: []}
	]},
	{nodeValue: 'value', id: '', processTree: [
	  {nodeValue: 'value', id: '', processTree: [
		{nodeValue: 'value', id: '', processTree: [
		  {nodeValue: 'value', id: '', processTree: [
			{nodeValue: 'value', id: '', processTree: []},
			{nodeValue: 'value', id: '', processTree: []}
		  ]}
		]}
	  ]}
	]},
	{nodeValue: 'value', id: '', processTree: [
	  {nodeValue: 'value', id: '', processTree: []}
	]},
	{nodeValue: 'value', id: '', processTree: [
	  {nodeValue: 'value', id: '', processTree: []}
	]},
	{nodeValue: 'value', id: '', processTree: [
	  {nodeValue: 'value', id: '', processTree: [
		{nodeValue: 'value', id: '', processTree: []},
		{nodeValue: 'value', id: '', processTree: [
		  {nodeValue: 'value', id: '', processTree: [
			{nodeValue: 'value', id: '', processTree: [
			  {nodeValue: 'value', id: '', processTree: []},
			  {nodeValue: 'value', id: '', processTree: []}
			]}
		  ]},
		  {nodeValue: 'value', id: '', processTree: [
			{nodeValue: 'value', id: '', processTree: [
			  {nodeValue: 'value', id: '', processTree: []},
			  {nodeValue: 'value', id: '', processTree: []}
			]}
		  ]}
		]}
	  ]}
	]}
  // ]} // Uncomment this to get one main node
]

About

A tree graph made using Vue.js and html+css.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages