{"id":13407016,"url":"https://github.com/neuronetio/gantt-elastic","last_synced_at":"2025-09-27T05:31:48.726Z","repository":{"id":38359404,"uuid":"138396301","full_name":"neuronetio/gantt-elastic","owner":"neuronetio","description":"Gantt Chart  [ javascript gantt chart, gantt component, vue gantt, vue gantt chart,  responsive gantt, project manager , vue projects ]","archived":true,"fork":false,"pushed_at":"2022-01-04T19:02:54.000Z","size":78413,"stargazers_count":1315,"open_issues_count":16,"forks_count":315,"subscribers_count":45,"default_branch":"master","last_synced_at":"2025-01-16T04:06:42.455Z","etag":null,"topics":["gantt","gantt-chart","gantt-component","gantt-javascript","javascript","javascript-gantt","jquery","jquery-gantt","project","project-gantt","project-management","responsive","svg","task","task-manager","vue","vue-gantt","vue-gantt-chart","vue-gantt-component","vuejs"],"latest_commit_sha":null,"homepage":"https://neuronet.io/gantt-elastic/","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/neuronetio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"issuehunt":"neuronetio"}},"created_at":"2018-06-23T11:36:30.000Z","updated_at":"2025-01-15T15:46:44.000Z","dependencies_parsed_at":"2022-07-10T17:18:59.630Z","dependency_job_id":null,"html_url":"https://github.com/neuronetio/gantt-elastic","commit_stats":null,"previous_names":["neuronetio/elastigantt"],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuronetio%2Fgantt-elastic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuronetio%2Fgantt-elastic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuronetio%2Fgantt-elastic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/neuronetio%2Fgantt-elastic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/neuronetio","download_url":"https://codeload.github.com/neuronetio/gantt-elastic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":234296430,"owners_count":18810001,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gantt","gantt-chart","gantt-component","gantt-javascript","javascript","javascript-gantt","jquery","jquery-gantt","project","project-gantt","project-management","responsive","svg","task","task-manager","vue","vue-gantt","vue-gantt-chart","vue-gantt-component","vuejs"],"created_at":"2024-07-30T19:02:45.951Z","updated_at":"2025-09-27T05:31:42.986Z","avatar_url":"https://github.com/neuronetio.png","language":"Vue","funding_links":["https://issuehunt.io/r/neuronetio"],"categories":["Vue"],"sub_categories":[],"readme":"\u003ch1\u003eGantt-elastic - Javascript Gantt Chart (editable, responsive)\u003c/h1\u003e\n\u003ch2\u003eJavascript Gantt Chart for vue, jquery, vanilla js and other frameworks\u003c/h2\u003e\n\n\u003cbr\u003e\n\u003ch3\u003eProject moved as next major version to \u003ca href=\"https://github.com/neuronetio/gantt-schedule-timeline-calendar\"\u003egantt-schedule-timeline-calendar\u003c/a\u003e\u003c/h3\u003e\u003cbr\u003e\u003cbr\u003e\n\u003cbr\u003e\n\n\u003cstrong\u003eThis project is not suitable for use in a production environment as it runs very slowly even in standard medium projects. This project has been completely rewritten and built with super performance in mind and is available in the new repository as a \u003ca href=\"https://github.com/neuronetio/gantt-schedule-timeline-calendar\"\u003egantt-schedule-timeline-calendar\u003c/a\u003e.\u003c/strong\u003e\n\n\n\u003ch2\u003e\u003ca href=\"https://neuronet.io/gantt-elastic/\" target=\"_blank\"\u003eGantt-elastic demo here\u003c/a\u003e\u003c/h2\u003e\n\n![preview img](https://github.com/neuronetio/gantt-elastic/raw/master/gantt-elastic.jpg)\n![preview gif](https://github.com/neuronetio/gantt-elastic/raw/master/gantt-elastic.gif)\n![preview gif](https://github.com/neuronetio/gantt-elastic/raw/master/grab-scroll.gif)\n\n## Gantt-elastic\n\nis a vue component but it could be used in other frameworks or even with jQuery (vue is kind of elastic and lightweight framework).\n\n[WIKI](https://github.com/neuronetio/gantt-elastic/wiki)\n\n[Vue Example](https://github.com/neuronetio/vue-gantt-elastic)\n\n### Installation\n\n`npm install --save gantt-elastic` or download zip from github / clone repo\n\nand if you want default header\n\n`npm install --save gantt-elastic-header`\n\n### Usage\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml charset=\"utf-8\"\u003e\n  \u003chead\u003e\n    \u003cmeta charset=\"utf-8\" /\u003e\n    \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\" /\u003e\n    \u003ctitle\u003eGanttElastic editor demo\u003c/title\u003e\n    \u003cscript src=\"https://cdn.jsdelivr.net/npm/vue/dist/vue.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://cdn.jsdelivr.net/npm/dayjs\"\u003e\u003c/script\u003e\n\n    \u003cscript src=\"https://unpkg.com/gantt-elastic/dist/GanttElastic.umd.js\"\u003e\u003c/script\u003e\n    \u003cscript src=\"https://unpkg.com/gantt-elastic-header/dist/Header.umd.js\"\u003e\u003c/script\u003e\n  \u003c/head\u003e\n\n  \u003cbody\u003e\n    \u003cdiv style=\"width:100%;height:100%\"\u003e\n      \u003cdiv id=\"app\" v-if=\"!destroy\"\u003e\n        \u003cgantt-elastic :tasks=\"tasks\" :options=\"options\" :dynamic-style=\"dynamicStyle\"\u003e\n          \u003cgantt-header slot=\"header\"\u003e\u003c/gantt-header\u003e\n          \u003cgantt-footer slot=\"footer\"\u003e\u003c/gantt-footer\u003e\n        \u003c/gantt-elastic\u003e\n      \u003c/div\u003e\n    \u003c/div\u003e\n\n    \u003cscript\u003e\n      // just helper to get current dates\n      function getDate(hours) {\n        const currentDate = new Date();\n        const currentYear = currentDate.getFullYear();\n        const currentMonth = currentDate.getMonth();\n        const currentDay = currentDate.getDate();\n        const timeStamp = new Date(currentYear, currentMonth, currentDay, 0, 0, 0).getTime();\n        return new Date(timeStamp + hours * 60 * 60 * 1000).getTime();\n      }\n\n      let tasks = [\n        {\n          id: 1,\n          label: 'Make some noise',\n          user:\n            '\u003ca href=\"https://www.google.com/search?q=John+Doe\" target=\"_blank\" style=\"color:#0077c0;\"\u003eJohn Doe\u003c/a\u003e',\n          start: getDate(-24 * 5),\n          duration: 15 * 24 * 60 * 60 * 1000,\n          progress: 85,\n          type: 'project',\n          //collapsed: true,\n        },\n        {\n          id: 2,\n          label: 'With great power comes great responsibility',\n          user:\n            '\u003ca href=\"https://www.google.com/search?q=Peter+Parker\" target=\"_blank\" style=\"color:#0077c0;\"\u003ePeter Parker\u003c/a\u003e',\n          parentId: 1,\n          start: getDate(-24 * 4),\n          duration: 4 * 24 * 60 * 60 * 1000,\n          progress: 50,\n          type: 'milestone',\n          collapsed: true,\n          style: {\n            base: {\n              fill: '#1EBC61',\n              stroke: '#0EAC51',\n            },\n            /*'tree-row-bar': {\n              fill: '#1EBC61',\n              stroke: '#0EAC51'\n            },\n            'tree-row-bar-polygon': {\n              stroke: '#0EAC51'\n            }*/\n          },\n        },\n        {\n          id: 3,\n          label: 'Courage is being scared to death, but saddling up anyway.',\n          user:\n            '\u003ca href=\"https://www.google.com/search?q=John+Wayne\" target=\"_blank\" style=\"color:#0077c0;\"\u003eJohn Wayne\u003c/a\u003e',\n          parentId: 2,\n          start: getDate(-24 * 3),\n          duration: 2 * 24 * 60 * 60 * 1000,\n          progress: 100,\n          type: 'task',\n        },\n        {\n          id: 4,\n          label: 'Put that toy AWAY!',\n          user:\n            '\u003ca href=\"https://www.google.com/search?q=Clark+Kent\" target=\"_blank\" style=\"color:#0077c0;\"\u003eClark Kent\u003c/a\u003e',\n          start: getDate(-24 * 2),\n          duration: 2 * 24 * 60 * 60 * 1000,\n          progress: 50,\n          type: 'task',\n          dependentOn: [3],\n        },\n      ];\n\n      let options = {\n        maxRows: 100,\n        maxHeight: 300,\n        title: {\n          label: 'Your project title as html (link or whatever...)',\n          html: false,\n        },\n        row: {\n          height: 24,\n        },\n        calendar: {\n          hour: {\n            display: false,\n          },\n        },\n        chart: {\n          progress: {\n            bar: false,\n          },\n          expander: {\n            display: true,\n          },\n        },\n        taskList: {\n          expander: {\n            straight: false,\n          },\n          columns: [\n            {\n              id: 1,\n              label: 'ID',\n              value: 'id',\n              width: 40,\n            },\n            {\n              id: 2,\n              label: 'Description',\n              value: 'label',\n              width: 200,\n              expander: true,\n              html: true,\n              events: {\n                click({ data, column }) {\n                  alert('description clicked!\\n' + data.label);\n                },\n              },\n            },\n            {\n              id: 3,\n              label: 'Assigned to',\n              value: 'user',\n              width: 130,\n              html: true,\n            },\n            {\n              id: 3,\n              label: 'Start',\n              value: (task) =\u003e dayjs(task.start).format('YYYY-MM-DD'),\n              width: 78,\n            },\n            {\n              id: 4,\n              label: 'Type',\n              value: 'type',\n              width: 68,\n            },\n            {\n              id: 5,\n              label: '%',\n              value: 'progress',\n              width: 35,\n              style: {\n                'task-list-header-label': {\n                  'text-align': 'center',\n                  width: '100%',\n                },\n                'task-list-item-value-container': {\n                  'text-align': 'center',\n                  width: '100%',\n                },\n              },\n            },\n          ],\n        },\n        /*locale:{\n          name: 'pl', // name String\n          weekdays: 'Poniedziałek_Wtorek_Środa_Czwartek_Piątek_Sobota_Niedziela'.split('_'), // weekdays Array\n          weekdaysShort: 'Pon_Wto_Śro_Czw_Pią_Sob_Nie'.split('_'), // OPTIONAL, short weekdays Array, use first three letters if not provided\n          weekdaysMin: 'Pn_Wt_Śr_Cz_Pt_So_Ni'.split('_'), // OPTIONAL, min weekdays Array, use first two letters if not provided\n          months: 'Styczeń_Luty_Marzec_Kwiecień_Maj_Czerwiec_Lipiec_Sierpień_Wrzesień_Październik_Listopad_Grudzień'.split('_'), // months Array\n          monthsShort: 'Sty_Lut_Mar_Kwi_Maj_Cze_Lip_Sie_Wrz_Paź_Lis_Gru'.split('_'), // OPTIONAL, short months Array, use first three letters if not provided\n          ordinal: n =\u003e `${n}`, // ordinal Function (number) =\u003e return number + output\n          relativeTime: { // relative time format strings, keep %s %d as the same\n            future: 'za %s', // e.g. in 2 hours, %s been replaced with 2hours\n            past: '%s temu',\n            s: 'kilka sekund',\n            m: 'minutę',\n            mm: '%d minut',\n            h: 'godzinę',\n            hh: '%d godzin', // e.g. 2 hours, %d been replaced with 2\n            d: 'dzień',\n            dd: '%d dni',\n            M: 'miesiąc',\n            MM: '%d miesięcy',\n            y: 'rok',\n            yy: '%d lat'\n          }\n       }*/\n      };\n\n      // create instance\n      const app = new Vue({\n        components: {\n          'gantt-header': Header,\n          'gantt-elastic': GanttElastic,\n          'gantt-footer': {\n            template: `\u003cspan\u003ethis is a footer\u003c/span\u003e`,\n          },\n        },\n        data: {\n          tasks: tasks.map((task) =\u003e Object.assign({}, task)),\n          options,\n          dynamicStyle: {\n            'task-list-header-label': {\n              'font-weight': 'bold',\n            },\n          },\n          destroy: false,\n        },\n      });\n\n      // gantt state which will be updated in realtime\n      let ganttState, ganttInstance;\n\n      // listen to 'gantt-elastic.ready' or 'gantt-elastic.mounted' event\n      // to get the gantt state for real time modification\n      app.$on('gantt-elastic-ready', (ganttElasticInstance) =\u003e {\n        ganttInstance = ganttElasticInstance;\n\n        ganttInstance.$on('tasks-changed', (tasks) =\u003e {\n          app.tasks = tasks;\n        });\n        ganttInstance.$on('options-changed', (options) =\u003e {\n          app.options = options;\n        });\n        ganttInstance.$on('dynamic-style-changed', (style) =\u003e {\n          app.dynamicStyle = style;\n        });\n\n        ganttInstance.$on('chart-task-mouseenter', ({ data, event }) =\u003e {\n          console.log('task mouse enter', { data, event });\n        });\n        ganttInstance.$on('updated', () =\u003e {\n          //console.log('gantt view was updated');\n        });\n        ganttInstance.$on('destroyed', () =\u003e {\n          //console.log('gantt was destroyed');\n        });\n        ganttInstance.$on('times-timeZoom-updated', () =\u003e {\n          console.log('time zoom changed');\n        });\n        ganttInstance.$on('taskList-task-click', ({ event, data, column }) =\u003e {\n          console.log('task list clicked! (task)', { data, column });\n        });\n      });\n\n      // mount gantt to DOM\n      app.$mount('#app');\n    \u003c/script\u003e\n  \u003c/body\u003e\n\u003c/html\u003e\n```\n\n### gantt-elastic as vue component\n\nTake a look at the `vue.html` inside [examples folder](https://github.com/neuronetio/gantt-elastic/tree/master/examples) file to see how you could add gantt-elastic inside `\u003cscript\u003e` tag along with the Vue framework\n\nDemo project: https://github.com/neuronetio/vue-gantt-elastic\n\nYou can also import gantt-elastic as compiled js component in commonjs or umd format ([examples](https://github.com/neuronetio/gantt-elastic/tree/master/examples) folder) or just grab GanttElastic.vue from src directory and add to your existing vue project.\n\n```javascript\nimport Vue from 'vue';\nimport GanttElastic from \"gantt-elastic\";\nimport Header from \"gantt-elastic-header\"; // if you want standard header (npm i -s gantt-elastic-header)\nnew Vue({\n  el:'#gantt',\n  template:`\u003cgantt-elastic :tasks=\"tasks\" :options=\"options\"\u003e\n    \u003cgantt-elastic-header slot=\"header\"\u003e\u003c/gantt-elastic-header\u003e\n    \u003cgantt-elastic-footer slot=\"footer\"\u003e\u003c/gantt-elastic-footer\u003e\n  \u003c/gantt-elastic\u003e`,\n  components: {\n    ganttElasticHeader: {template:`\u003cspan\u003eyour header\u003c/span\u003e`}, // or Header\n    ganttElastic: GanttElastic\n    ganttElasticFooter: {template:`\u003cspan\u003eyour footer\u003c/span\u003e`},\n  },\n  data() {\n    return {\n      tasks: tasks,\n      options: options\n    };\n  }\n});\n```\n\nor\n\n```javascript\nimport Vue from 'vue';\nimport App from './App.vue'; // your app that uses gantt-elastic from 'gantt-elastic/src/GanttElastic.vue'\n\nnew Vue({\n  el: '#app',\n  render: (h) =\u003e h(App),\n});\n```\n\n### For webpack usage (pure javascript, inside other frameworks or Vue App/Component)\n\nTake a look at this demo project: https://github.com/neuronetio/gantt-elastic-webpack for other bundlers use umd or commonjs from dist folder.\n\n```javascript\nimport GanttElastic from 'gantt-elastic/dist/GantElastic.umd.js';\nimport GanttElastic from 'gantt-elastic/dist/GantElastic.common.js'; // same as import GanttElastic from 'gantt-elastic';\nimport GanttElastic from 'gantt-elastic/src/GantElastic.vue'; // if you want vue component directly without compilation - look above\n// and the same with require\nconst GanttElastic = require('gantt-elastic/dist/GantElastic.common.js');\n```\n\n### uglifyjs\n\nIf you are using uglifyjs in your project be sure to have es6 compatible version like [uglify-es](https://www.npmjs.com/package/uglify-es)\n\n### Licensce\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneuronetio%2Fgantt-elastic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fneuronetio%2Fgantt-elastic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fneuronetio%2Fgantt-elastic/lists"}