GithubHelp home page GithubHelp logo

romanpolunin / orgchart Goto Github PK

View Code? Open in Web Editor NEW
19.0 1.0 6.0 2.11 MB

Organization chart layout library

License: MIT License

C# 13.65% JavaScript 84.45% HTML 1.90%
orgchart organizational chart diagram hierarchy chart-layout visual

orgchart's Introduction

OrgChart

Overview

A fast, robust and easily extensible organization chart layout library without any 3-rd party dependencies. Designed specifically for arrangement of rectangular boxes and connectors, for use by applications which represent hierarchical organizational structures in a user-friendly manner.

Supports combining arbitrary layout styles with some available out of the box and with open interfaces for extension/new styles, special layout rules for assistants, expand-collapse operations, pluggable box rendering algorithms. All calculations made using double-precision coordinates.

Available in C# and JavaScript (JS code is generated from C# using Bridge.Net). All code (including C# -> JS converter) is in one Visual Studio solution. C# version has advanced demo and debugging tool built on top of OrgChart as a Windows Universal application, that helps to visualize and debug layout computation process step-by-step.

JavaScript demo page generates a 200-box chart and renders it into a collection of pure HTML/div objects with absolute coordinates as computed by OrgChart library - you can build rich HTML5 user interfaces the way your users want it.

Use OrgChart if you need to:

  • Render rich interactive organizational charts in a cross-browser HTML5/CSS/JS client application, with your very own data adapters.
  • Implement advanced organizational charting UI in a native client Windows Forms, WPF, Universal, Xamarin application.
  • Render organizational charts in a .NET or JavaScript-based server application, for reporting or exporting purposes.
  • Implement and debug custom layout strategies and layout optimization behavior with minimal effort in C#, then instantly port them to JavaScript.

Author and license

(c) Roman Polunin 2016, MIT license. See https://opensource.org/licenses/MIT.

Copyright 2016 Roman Polunin.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Advantages

Absolutely free to use and modify in all types of applications, in source code and binary form.

Supports very sophisticated layout rules, supports assistants and multiple visual roots, step-by-step visualization of layout for debugging, produces double-precision coordinates and rich supplementary layout information.

Exactly same code is available both in C# and JavaScript, compiles to .NET 2.0 and 4.0, .NET Core, UWP, Silverlight etc. JavaScript code is generated automatically using Bridge.Net!

As non-intrusive as possible, you can have your data structured and rendered in any way you want.

Does not force you into any specific rendering technique/framework - use existing or implement your own.

Rich API for extensibility, supports development of custom layout strategies.

Usage: JavaScript

Converted JS libraries are under $\JScript\OrgChart.Layout.JScript.Bridge\Bridge\output.

See advanced demo page (multiple layout strategies, rendering, expand/collapse).

If you modify C# code and want to update JS, just re-build OrgChart.Layout.JScript.Bridge project from solution.

Also, there's now a great TypeScript/React project based on this source code, converted from C#.

https://awesome-react-org-chart.vercel.app/example.html

Usage: C#

To compute chart "fresh" see C# sample application:

  1. Either import source code or plug in this NuGet package: http://www.nuget.org/packages/RomanPolunin.OrgChart.Net/
  2. Implement two adapter interfaces: IChartDataSource and IChartDataItem.
  3. Create an object of type BoxContainer supplying your IChartDataSource. BoxContainer will produce a set of Box objects, one per IChartDataItem. It will also add one special box (SystemRoot) - to support multiple visible roots in the diagram.
  4. Either manually apply sizes on each Box (Box.Size property), or implement a callback function on LayoutState (see step 6). This depends on how and when you do rendering.
  5. Create an object of type Diagram and populate properties LayoutSettings, DefaultLayoutStrategyId and DefaultAssistantsLayoutStrategyId.
  6. Create an object of type LayoutState, optionally give it a callback function for box size, invoke LayoutAlgorithm.Apply on that state object.
  7. Consume computed coordinates from Diagram.VisualTree.

To re-compute layout after having some Box.IsCollapsed set to true, or some Box.Size property modified:

  1. Create a LayoutState object, invoke LayoutAlgorithm.Apply on it.
  2. Consume computed coordinates from Diagram.VisualTree.

LayoutAlgorithm.Apply will create a visual tree of BoxTree.Node objects that have all computed coordinates, available through VisualTree property of the Diagram object you created and supplied into LayoutAlgorithm.Apply. LayoutAlgorithm.Apply computes both coordinates of BoxTree.Node objects and connectors between them.

Box and its properties

Boxes serve four purposes:

  • rendering and content measurements. Rendering is a very different task from computing box's coordinates on screen and routing connectors. You might want to have some rich content, interactive UI etc. Also, the only way to know the size of a visual element in most UI frameworks is to render it - this is when all text sizes are measured and styles applied.
  • support data binding for rendering.
  • manage expand/collapse state: boxes are a natural place to store "is collapsed" state, because they survive layout runs.
  • support layout optimizations by customizing layout strategies on box level: you can design and implement rules to assign layout strategies on each individual box to make corresponding branches taller, wider, more compact, increase or decrease spacing etc. OrgChart library supports defaults and inherited settings, but you can get very specific when needed.

Most Box objects are automatically generated for each individual instance of IChartDataItem coming from your IChartDataSource. These boxes are called data-bound and have Box.IsDataBound property return true. All data-bound boxes should be stored in the BoxContainer.

While most boxes will be generated from your data, some others will be generated and handled by the algorithm. Such boxes will have their DataId set to null, IsSpecial set to true, their Id set to Box.None and they should not ever be added to BoxContainer (except BoxContainer.SystemRoot). They will only be referenced by TreeNode.Element property and live until chart layout is re-computed.

Properties of the Box:

  • LayoutStrategyId: to explicitly assign a layout strategy to a specific box.
  • DataId: identifier of the IChartDataItem used to create this Box.
  • Id: identifier of this Box in its parent BoxContainer.
  • Size: width and height of this box, as you want it to be. You only have to supply the size for data-bound boxes (generated from IChartDataSource).
  • IsCollapsed flag: set it to true if you want corresponding chart node to be collapsed, hiding all children.
  • IsAssistant flag: set it to true if you want corresponding chart node to be laid out using special assistant rule (visually separates from other normal children).
  • IsSpecial flag: is automatically set to true on boxes auto-generated by the algorithm.

BoxContainer will only store one special box for the SystemRoot. Other special boxes only exist within the generated visual tree.

Diagram.VisualTree is a tree of BoxTree.Node objects joined into a navigable tree structure. Each node is a visual object on a diagram. Some of the nodes represent real data-bound boxes, some others are generated for layout purposes (spacers).

Properties of the BoxTree.Node:

  • Element: reference to corresponding Box, which might be either data bound or auto-generated ("special").
  • AssistantsRoot: a node to separate children with IsAssistant flag set to true, along with their connectors. Supports seamless re-use of layout algorithms and separation of regular and assistant layout strategies.
  • State: instance of NodeLayoutInfo class, holds computed coordinates and flags.
  • Children: collection of child nodes.

Properties of NodeLayoutInfo (access via BoxTree.Node.State):

  • EffectiveLayoutStrategy reference, inferred from parent node or from explicit LayoutStrategyId on the bound Box. May also be supplied by your very own delegate specified by LayoutState.LayoutOptimizerFunc.
  • potentially modified Size of the data-bound Box bound to it (or auto-generated for special Nodes/Boxes). Sometimes the size of the node will be different from the size of the associated box - depends on layout strategy.
  • calculated TopLeft position of the box rectangle.
  • calculated BranchExterior - bounding rectangle of this node with all its children and spacers.
  • Connector, a collection of Edge objects that define visible connectors.

orgchart's People

Contributors

roman-polunin-medamerica avatar romanpolunin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

orgchart's Issues

Use in angular

How to use this in angular project, can you help me out?

(Support request) Canvas position warped & additional backgrounds&borders on connectors

Hi,

first off, thank you so very much for your library, it is a lifesaver. You've done great work I could never come up with!

I have the following two issues using the library with C# WPF.

  1. When placing your example code in a WPF Canvas element with a Gray background, the element itself seems to be pushed off to the side, rather than covering the diagram. This seems to have to do with the RenderTransforms being applied to shift everything into place. Would you know how to adjust your example code so this does not happen, and the diagram is correctly enframed in the dimensions of the Canvas?

image

image

  1. When rendering boxRectangle and boxFrameRectangle in your example code, their styling seems to apply to the connector brushes that connect the boxes together. This leads to a segmented appearance. To my understanding, the box and frame rectangles should not be affecting the lines drawn for the connectors. How could I fix that?

image

Thanks again!

Horizontal branch positions are wrong for specific box heights

When I set the height of all boxes at 0.7, the CenterH of the BranchExterior elements is correct (they range from -0.625 to 0.625)

With different box height values (ranging from 0.67 to 0.69), the CenterH values are wrong (they have a much greater spread, ranging from -12.5 to 12.5)

When it works correctly, this breakpoint is hit once, offense is set to 1.25, i and k get incremented, then ComputeOverlap returns 1.25 because k = other.Left.Count = 1
offense correct

But when it does not work correctly, this breakpoint is hit twice. After the first time the breakpoint is hit, k does not get updated because my.Bottom = 1.84 and th.Bottom = 1.86. The second time the breakpoint is hit, my.X = 25, diff = 25, and offense gets set to 25.
offense incorrect

I'd really appreciate it if you could fix this or point me in the right direction.
Thank you for developing and sharing this tool

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.