├── LICENSE ├── examples ├── marker.png ├── images │ ├── basic.png │ ├── twolines.png │ ├── customcolor.png │ └── multichart.png └── examples.html ├── jquery.WorkflowViz.coffee ├── jquery.WorkflowViz.js └── README.md /LICENSE: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/marker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarendraYSF/WorkFlowViz/HEAD/examples/marker.png -------------------------------------------------------------------------------- /examples/images/basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarendraYSF/WorkFlowViz/HEAD/examples/images/basic.png -------------------------------------------------------------------------------- /examples/images/twolines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarendraYSF/WorkFlowViz/HEAD/examples/images/twolines.png -------------------------------------------------------------------------------- /examples/images/customcolor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarendraYSF/WorkFlowViz/HEAD/examples/images/customcolor.png -------------------------------------------------------------------------------- /examples/images/multichart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NarendraYSF/WorkFlowViz/HEAD/examples/images/multichart.png -------------------------------------------------------------------------------- /examples/examples.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |

One line, with markers:

11 |
12 | 13 | 28 | 29 | 30 |

Two lines, with markers:

31 |
32 | 33 | 49 | 50 | 51 | 52 |

Custom Line Color:

53 |
54 | 55 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /jquery.WorkflowViz.coffee: -------------------------------------------------------------------------------- 1 | $ = jQuery 2 | 3 | tallestPoint = (lines, x) -> 4 | computedValues = $.map lines, (line) -> 5 | prevPoint = null 6 | ret = null 7 | $.map line['data'], (datum, i) -> 8 | if x >= datum['x'] 9 | prevPoint = datum 10 | return 11 | 12 | if x < datum['x'] 13 | if prevPoint == null 14 | ret = datum['y'] 15 | return 16 | 17 | # How far between the two x-points? 18 | xdiff = x-prevPoint['x'] 19 | slope = ((datum['y']-prevPoint['y'])/(datum['x']-prevPoint['x'])) 20 | ret = prevPoint['y'] + slope*(x-prevPoint['x']) 21 | return 22 | ret 23 | 24 | ret = null 25 | $.each computedValues, (i, v) -> 26 | ret = v if v? and (not ret? or ret 37 | opts = $.extend true, {}, defaults, opts 38 | 39 | # Support for single or multiple lines 40 | lines = [lines] if Object.prototype.toString.call( lines ) != '[object Array]' 41 | 42 | # Default highcharts options 43 | defaultHighchartsOpts = 44 | title: 45 | text: null 46 | xAxis: 47 | type: 'datetime' 48 | dateTimeLabelFormats: 49 | day: opts.dateFormat 50 | year: '%b' 51 | yAxis: 52 | title: 53 | text: null 54 | plotLines: [ 55 | value: 0 56 | width: 1 57 | color: '#808080' 58 | ] 59 | tooltip: 60 | formatter: -> 61 | date = Highcharts.dateFormat opts.dateFormat, @x 62 | s = '' + date + '
' 63 | if @point.name? 64 | s += @point.name 65 | else 66 | s += "#{@series.name}: #{@y}" 67 | s 68 | positioner: -> 69 | x: opts.tooltip.x 70 | y: opts.tooltip.y 71 | plotOptions: 72 | scatter: 73 | marker: 74 | symbol: opts['marker'] 75 | states: 76 | hover: 77 | enabled: true 78 | lineColor: 'rgb(100,100,100)' 79 | states: 80 | hover: 81 | marker: 82 | enabled: false 83 | spline: 84 | marker: 85 | enabled: false 86 | legend: 87 | enabled: false 88 | 89 | # Build options for this chart 90 | highchartsOpts = $.extend true, defaultHighchartsOpts, opts['highchartsOpts'] 91 | 92 | # Build data 93 | maxY = null; 94 | lines = $.map lines, (line) -> 95 | lineData = $.map line.data, (data) -> 96 | maxY = data[1] if maxY==null or data[1] > maxY 97 | x: new Date(data[0]) 98 | y: data[1] 99 | { 100 | type: 'spline', 101 | name: line.name, 102 | data: lineData 103 | } 104 | 105 | markerData = $.map markers, (marker) -> 106 | x: new Date(marker[0]) 107 | y: tallestPoint(lines, marker[0]) 108 | name: marker[1] 109 | markerLine = 110 | type: 'scatter' 111 | name: 'Markers' 112 | data: markerData 113 | 114 | lines.push markerLine 115 | 116 | # Build data into highcharts options for final chart hash 117 | chart = $.extend true, highchartsOpts, 118 | series: lines 119 | 120 | # Build the chart 121 | $(this).highcharts chart 122 | -------------------------------------------------------------------------------- /jquery.WorkflowViz.js: -------------------------------------------------------------------------------- 1 | // Generated by CoffeeScript 1.3.3 2 | (function() { 3 | var $, defaults, tallestPoint; 4 | 5 | $ = jQuery; 6 | 7 | tallestPoint = function(lines, x) { 8 | var computedValues, ret; 9 | computedValues = $.map(lines, function(line) { 10 | var prevPoint, ret; 11 | prevPoint = null; 12 | ret = null; 13 | $.map(line['data'], function(datum, i) { 14 | var slope, xdiff; 15 | if (x >= datum['x']) { 16 | prevPoint = datum; 17 | return; 18 | } 19 | if (x < datum['x']) { 20 | if (prevPoint === null) { 21 | ret = datum['y']; 22 | return; 23 | } 24 | xdiff = x - prevPoint['x']; 25 | slope = (datum['y'] - prevPoint['y']) / (datum['x'] - prevPoint['x']); 26 | ret = prevPoint['y'] + slope * (x - prevPoint['x']); 27 | } 28 | }); 29 | return ret; 30 | }); 31 | ret = null; 32 | $.each(computedValues, function(i, v) { 33 | if ((v != null) && (!(ret != null) || ret < v)) { 34 | return ret = v; 35 | } 36 | }); 37 | return ret; 38 | }; 39 | 40 | defaults = { 41 | marker: 'url(marker.png)', 42 | dateFormat: '%b %e', 43 | tooltip: { 44 | x: 30, 45 | y: 10 46 | } 47 | }; 48 | 49 | $.fn.epochchart = function(lines, markers, opts) { 50 | var chart, defaultHighchartsOpts, highchartsOpts, markerData, markerLine, maxY; 51 | if (opts == null) { 52 | opts = {}; 53 | } 54 | opts = $.extend(true, {}, defaults, opts); 55 | if (Object.prototype.toString.call(lines) !== '[object Array]') { 56 | lines = [lines]; 57 | } 58 | defaultHighchartsOpts = { 59 | title: { 60 | text: null 61 | }, 62 | xAxis: { 63 | type: 'datetime', 64 | dateTimeLabelFormats: { 65 | day: opts.dateFormat, 66 | year: '%b' 67 | } 68 | }, 69 | yAxis: { 70 | title: { 71 | text: null 72 | }, 73 | plotLines: [ 74 | { 75 | value: 0, 76 | width: 1, 77 | color: '#808080' 78 | } 79 | ] 80 | }, 81 | tooltip: { 82 | formatter: function() { 83 | var date, s; 84 | date = Highcharts.dateFormat(opts.dateFormat, this.x); 85 | s = '' + date + '
'; 86 | if (this.point.name != null) { 87 | s += this.point.name; 88 | } else { 89 | s += "" + this.series.name + ": " + this.y; 90 | } 91 | return s; 92 | }, 93 | positioner: function() { 94 | return { 95 | x: opts.tooltip.x, 96 | y: opts.tooltip.y 97 | }; 98 | } 99 | }, 100 | plotOptions: { 101 | scatter: { 102 | marker: { 103 | symbol: opts['marker'], 104 | states: { 105 | hover: { 106 | enabled: true, 107 | lineColor: 'rgb(100,100,100)' 108 | } 109 | } 110 | }, 111 | states: { 112 | hover: { 113 | marker: { 114 | enabled: false 115 | } 116 | } 117 | } 118 | }, 119 | spline: { 120 | marker: { 121 | enabled: false 122 | } 123 | } 124 | }, 125 | legend: { 126 | enabled: false 127 | } 128 | }; 129 | highchartsOpts = $.extend(true, defaultHighchartsOpts, opts['highchartsOpts']); 130 | maxY = null; 131 | lines = $.map(lines, function(line) { 132 | var lineData; 133 | lineData = $.map(line.data, function(data) { 134 | if (maxY === null || data[1] > maxY) { 135 | maxY = data[1]; 136 | } 137 | return { 138 | x: new Date(data[0]), 139 | y: data[1] 140 | }; 141 | }); 142 | return { 143 | type: 'spline', 144 | name: line.name, 145 | data: lineData 146 | }; 147 | }); 148 | markerData = $.map(markers, function(marker) { 149 | return { 150 | x: new Date(marker[0]), 151 | y: tallestPoint(lines, marker[0]), 152 | name: marker[1] 153 | }; 154 | }); 155 | markerLine = { 156 | type: 'scatter', 157 | name: 'Markers', 158 | data: markerData 159 | }; 160 | lines.push(markerLine); 161 | chart = $.extend(true, highchartsOpts, { 162 | series: lines 163 | }); 164 | return $(this).highcharts(chart); 165 | }; 166 | 167 | }).call(this); 168 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WorkflowViz.js 2 | 3 | A lightweight JavaScript library for creating interactive workflow visualizations. Transform your task management data into beautiful, interactive flowcharts with minimal setup. 4 | 5 | ## Features 6 | 7 | - Drag-and-drop workflow builder 8 | - Real-time status updates 9 | - Customizable node styles and transitions 10 | - Built-in templates for common workflow patterns 11 | - Export/import functionality 12 | - Mobile-responsive design 13 | - Zero dependencies 14 | 15 | ## Installation 16 | 17 | ```bash 18 | npm install workflow-viz 19 | # or 20 | yarn add workflow-viz 21 | ``` 22 | 23 | ## Quick Start 24 | 25 | ```javascript 26 | import WorkflowViz from 'workflow-viz'; 27 | 28 | // Initialize with a container element 29 | const workflow = new WorkflowViz('#workflow-container'); 30 | ``` 31 | 32 | ## Simple Usage Examples 33 | 34 | ### 1. Create a Single Workflow Line 35 | 36 | ```javascript 37 |
38 | 39 | 58 | ``` 59 | 60 | ### 2. Create Multiple Workflow Lines 61 | 62 | ```javascript 63 |
64 | 65 | 95 | ``` 96 | 97 | ### 3. Customize Workflow Visualization 98 | 99 | ```javascript 100 |
101 | 102 | 132 | ``` 133 | 134 | ## Advanced Usage 135 | 136 | ### Custom Node Templates 137 | 138 | ```javascript 139 | workflow.defineTemplate('custom', { 140 | shape: 'hexagon', 141 | size: { width: 120, height: 80 }, 142 | style: { 143 | fill: '#e6f3ff', 144 | stroke: '#0066cc', 145 | textColor: '#333333' 146 | } 147 | }); 148 | 149 | workflow.addNode({ 150 | id: 'special-task', 151 | label: 'Custom Process', 152 | template: 'custom' 153 | }); 154 | ``` 155 | 156 | ### Event Handling 157 | 158 | ```javascript 159 | workflow.on('nodeClick', (node) => { 160 | console.log(`Node ${node.id} clicked`); 161 | }); 162 | 163 | workflow.on('connectionCreated', (source, target) => { 164 | console.log(`New connection: ${source} → ${target}`); 165 | }); 166 | ``` 167 | 168 | ### State Management 169 | 170 | ```javascript 171 | // Update node status 172 | workflow.updateNode('task1', { 173 | status: 'completed', 174 | metadata: { 175 | completedBy: 'John Doe', 176 | timestamp: Date.now() 177 | } 178 | }); 179 | 180 | // Get workflow state 181 | const state = workflow.exportState(); 182 | ``` 183 | 184 | ## Configuration Options 185 | 186 | ```javascript 187 | const config = { 188 | theme: 'light', // 'light' or 'dark' 189 | autoLayout: true, // Enable automatic node positioning 190 | gridSize: 20, // Snap-to-grid size in pixels 191 | animationDuration: 300, // Transition duration in milliseconds 192 | readonly: false, // Disable editing capabilities 193 | connectorStyle: 'curved' // 'straight', 'curved', or 'orthogonal' 194 | }; 195 | 196 | const workflow = new WorkflowViz('#container', config); 197 | ``` 198 | 199 | ## API Reference 200 | 201 | ### Core Methods 202 | 203 | - `addNode(config)`: Add a new node to the workflow 204 | - `removeNode(id)`: Remove a node by ID 205 | - `connect(sourceId, targetId)`: Create a connection between nodes 206 | - `disconnect(sourceId, targetId)`: Remove a connection 207 | - `clear()`: Remove all nodes and connections 208 | - `exportState()`: Export the current workflow state 209 | - `importState(state)`: Import a workflow state 210 | - `render()`: Update the visualization 211 | 212 | ### Events 213 | 214 | - `nodeClick`: Fired when a node is clicked 215 | - `nodeDragStart`: Fired when node dragging begins 216 | - `nodeDragEnd`: Fired when node dragging ends 217 | - `connectionCreated`: Fired when a new connection is created 218 | - `connectionRemoved`: Fired when a connection is removed 219 | - `stateChanged`: Fired when the workflow state changes 220 | 221 | ## Browser Support 222 | 223 | - Chrome (latest) 224 | - Firefox (latest) 225 | - Safari (latest) 226 | - Edge (latest) 227 | - IE11 (with polyfills) 228 | 229 | ## Contributing 230 | 231 | We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details. 232 | 233 | ## License 234 | 235 | MIT License - see the [LICENSE](LICENSE) file for details. 236 | 237 | ## Support 238 | 239 | - Documentation: [docs.workflowviz.js.org](https://docs.workflowviz.js.org) 240 | - Issues: [GitHub Issues](https://github.com/workflowviz/workflowviz/issues) 241 | - Discord: [Join our community](https://discord.gg/workflowviz) 242 | 243 | ## Credits 244 | 245 | Created and maintained by the WorkflowViz team. Special thanks to all our contributors! 246 | --------------------------------------------------------------------------------