甘特图控件DHTMLX Gantt教程:用PHP:Laravel实现Gantt(上)

news2024/11/18 16:53:44

DHTMLX Gantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的大部分开发需求,具备完善的甘特图图表库,功能强大,价格便宜,提供丰富而灵活的JavaScript API接口,与各种服务器端技术(PHP,ASP.NET,Java等)简单集成,满足多种定制开发需求。

DHTMLX JavaScript UI 库所开发的 JavaScript 组件易于使用且功能丰富,非常适合任何领域和任何复杂性的解决方案,能够节省创建和维护业务应用程序的时间,提高生产力。

DHTMLX Gantt 最新下载(qun:764148812)icon-default.png?t=N4HBhttps://www.evget.com/product/4213/download

本教程介绍如何将dhtmlx甘特添加到Laravel应用程序中。

第 1 步:初始化项目

创建项目

使用 Composer 创建新应用程序:

composer create-project laravel/laravel gantt-laravel-app

下载和创建所有必要的文件应该需要一分钟。 完成所有操作后,您可以检查到目前为止一切是否正确:

cd gantt-laravel-app
php artisan serve

在此步骤中,您应该获得一个默认的Laravel页面:

第 2 步:将甘特图添加到页面

添加视图

首先,我们将添加一个带有dhtmlxGantt的新页面到我们的应用程序中。 转到资源/视图文件夹并创建一个名为 gantt.blade.php 的新视图:

<!DOCTYPE html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">

<script src="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
<link href="https://cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.css" rel="stylesheet">

<style type="text/css">
html, body{
height:100%;
padding:0px;
margin:0px;
overflow: hidden;
}

</style>
</head>
<body>
<div id="gantt_here" style='width:100%; height:100%;'></div>
<script type="text/javascript">
gantt.init("gantt_here");
</script>
</body>

在这里,我们定义了一个简单的HTML布局,从CDN添加了dhtmlxGantt的源代码,并使用init方法初始化了gantt。

请注意,我们还为文档正文和甘特图容器指定了 100% 高度。甘特图将使用其容器的大小,因此需要一些初始大小。

更改默认路由

添加新页面后,我们需要使其可从浏览器访问。在本教程中,我们将甘特图设为应用的默认页面。

转到路由/网络.php并更改默认路由:

<?php

Route::get('/', function () {
return view('gantt');
});

再次运行应用以确保它能解决问题:

第 3 步:创建模型和迁移

所以,我们有一个空的甘特图。让我们将其连接到数据库并用数据填充它。

创建数据库

请务必更新 .env 中的数据库配置,例如:

.env
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=gantt-test
DB_USERNAME=root
DB_PASSWORD=

下一步是创建模型类和迁移。您可以使用 Artisan 命令生成类和迁移文件:

php artisan make:model Task --migration

php artisan make:model Link --migration

之后,在文件夹中找到迁移并定义数据库架构。 您可以在此处找到甘特图所需的数据库架构。database/migrations

“任务”表的代码如下所示:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateTasksTable extends Migration
{
public function up()
{
Schema::create('tasks', function (Blueprint $table){
$table->increments('id');
$table->string('text');
$table->integer('duration');
$table->float('progress');
$table->dateTime('start_date');
$table->integer('parent');
$table->timestamps();
});
}

public function down()
{
Schema::dropIfExists('tasks');
}
}

您将在下面找到链接表的代码:

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateLinksTable extends Migration
{
public function up()
{
Schema::create('links', function (Blueprint $table) {
$table->increments('id');
$table->string('type');
$table->integer('source');
$table->integer('target');
$table->timestamps();
});
}

public function down()
{
Schema::dropIfExists('links');
}
}

并运行迁移:

php artisan migrate

当我们使用它时,我们可以为我们的应用生成一些测试数据。 使用 artisan 命令生成播种器类:

php artisan make:seeder TasksTableSeeder
php artisan make:seeder LinksTableSeeder

现在,创建数据库/种子文件夹,打开它并将一些数据添加到 TasksTableSeeder:

<?php

use Illuminate\Database\Seeder;

class TasksTableSeeder extends Seeder
{
public function run()
{
DB::table('tasks')->insert([
['id'=>1, 'text'=>'Project #1', 'start_date'=>'2017-04-01 00:00:00',
'duration'=>5, 'progress'=>0.8, 'parent'=>0],
['id'=>2, 'text'=>'Task #1', 'start_date'=>'2017-04-06 00:00:00',
'duration'=>4, 'progress'=>0.5, 'parent'=>1],
['id'=>3, 'text'=>'Task #2', 'start_date'=>'2017-04-05 00:00:00',
'duration'=>6, 'progress'=>0.7, 'parent'=>1],
['id'=>4, 'text'=>'Task #3', 'start_date'=>'2017-04-07 00:00:00',
'duration'=>2, 'progress'=>0, 'parent'=>1],
['id'=>5, 'text'=>'Task #1.1', 'start_date'=>'2017-04-05 00:00:00',
'duration'=>5, 'progress'=>0.34, 'parent'=>2],
['id'=>6, 'text'=>'Task #1.2', 'start_date'=>'2017-04-11 00:00:00',
'duration'=>4, 'progress'=>0.5, 'parent'=>2],
['id'=>7, 'text'=>'Task #2.1', 'start_date'=>'2017-04-07 00:00:00',
'duration'=>5, 'progress'=>0.2, 'parent'=>3],
['id'=>8, 'text'=>'Task #2.2', 'start_date'=>'2017-04-06 00:00:00',
'duration'=>4, 'progress'=>0.9, 'parent'=>3]
]);
}
}

并从 DatabaseSeeder 调用表播种机.php:

<?php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
public function run()
{
$this->call(TasksTableSeeder::class);
$this->call(LinksTableSeeder::class);
}
}

之后,我们可以从命令行为数据库播种:

php artisan db:seed

定义模型类

数据通过 Eloquent 模型类进行管理。我们已经在上一步中为任务和链接生成了类。 它们已准备就绪,无需进行任何更改即可使用甘特图。

但是,我们可以做的是将 Task 类的开放属性添加到 JSON 响应中。它将在将任务加载到客户端时扩展项目树。 否则,所有分支最初都将关闭:

任务模型将如下所示:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Task extends Model
{
protected $appends = ["open"];

public function getOpenAttribute(){
return true;
}
}

链接模型不需要任何更改:

/app/Link.php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Link extends Model
{
}

第 4 步:加载数据

创建数据库并定义模型后,我们可以将数据加载到甘特图中。 客户端需要以下格式的日期,因此让我们创建一个控制器,其中包含生成此类 JSON 的操作:

<?php
namespace App\Http\Controllers;
use App\Task;
use App\Link;

class GanttController extends Controller
{
public function get(){
$tasks = new Task();
$links = new Link();

return response()->json([
"data" => $tasks->all(),
"links" => $links->all()
]);
}
}

并注册一个路由,以便客户端可以调用此操作。请注意,我们会将路由添加到 api.php routes 文件中:

<?php

use Illuminate\Http\Request;
use App\Http\Controllers\GanttController;

Route::get('/data', 'GanttController@get');

最后,从视图中调用此操作:

resources/views/gantt.blade.php
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";

gantt.init("gantt_here");

gantt.load("/api/data");

gantt.load 将 AJAX 请求发送到指定的 URL,并期望我们之前定义的 JSON 响应。

另请注意,我们已指定date_format值。 这就是我们如何告诉甘特图数据源将使用哪种日期格式,以便客户端可以解析它们。

如果您现在检查应用程序,您应该会看到我们的甘特图中现在有任务:

第5步:保存更改

目前,我们的甘特图可以从后端读取数据。让我们让它将更改写回数据库。

客户端将在 REST 模式下工作,这意味着它将发送任务和链接操作的 POST/PUT/DELETE 请求。 您可以在此处找到请求的格式以及甘特图将使用的所有路由。

我们现在需要的是定义在两个模型上处理操作的控制器,为它们创建路由并在客户端启用数据保存。

添加控制器

让我们从控制器开始。我们将为每个模型创建一个 RESTful 资源控制器。 它将包含用于添加/删除和更新模型的方法。

任务控制器

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Task;

class TaskController extends Controller
{
public function store(Request $request){

$task = new Task();

$task->text = $request->text;
$task->start_date = $request->start_date;
$task->duration = $request->duration;
$task->progress = $request->has("progress") ? $request->progress : 0;
$task->parent = $request->parent;

$task->save();

return response()->json([
"action"=> "inserted",
"tid" => $task->id
]);
}

public function update($id, Request $request){
$task = Task::find($id);

$task->text = $request->text;
$task->start_date = $request->start_date;
$task->duration = $request->duration;
$task->progress = $request->has("progress") ? $request->progress : 0;
$task->parent = $request->parent;

$task->save();

return response()->json([
"action"=> "updated"
]);
}

public function destroy($id){
$task = Task::find($id);
$task->delete();

return response()->json([
"action"=> "deleted"
]);
}
}

还有一条路线:

<?php

use Illuminate\Http\Request;

Route::get('/data', 'GanttController@get');
Route::resource('task', 'TaskController');

关于此代码的一些说明:

  • 当插入一个新任务时,我们在响应对象的 tid 属性中将其 id 返回给客户端
  • 我们为进度参数分配默认值。 许多请求参数是可选的,这意味着如果客户端任务未分配它们,则不会将它们发送到服务器操作。
  • 响应 JSON 可以具有任意数量的附加属性,它们都可以从客户端处理程序访问

现在让我们为 LinkController 实现相同的方法。

链路控制器

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Link;

class LinkController extends Controller
{
public function store(Request $request){
$link = new Link();

$link->type = $request->type;
$link->source = $request->source;
$link->target = $request->target;

$link->save();

return response()->json([
"action"=> "inserted",
"tid" => $link->id
]);
}

public function update($id, Request $request){
$link = Link::find($id);

$link->type = $request->type;
$link->source = $request->source;
$link->target = $request->target;

$link->save();

return response()->json([
"action"=> "updated"
]);
}

public function destroy($id){
$link = Link::find($id);
$link->delete();

return response()->json([
"action"=> "deleted"
]);
}
}

及其路线:

<?php

use Illuminate\Http\Request;

Route::get('/data', 'GanttController@get');
Route::resource('task', 'TaskController');
Route::resource('link', 'LinkController');

在客户端启用数据保存

最后,我们将配置客户端以使用我们刚刚实现的 API:

resources/views/gantt.blade.php
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";

gantt.init("gantt_here");

gantt.load("/api/data");

var dp = new gantt.dataProcessor("/api");
dp.init(gantt);
dp.setTransactionMode("REST");

现在,您有一个完全交互式的甘特图,能够查看,添加,更新和删除任务和链接。

请查看我们的更多指南,了解 dhtmlx甘特的更多功能。

DHTMLX Gantt享有超十年声誉,支持跨浏览器和跨平台,性价比高,可满足项目管理控件应用的所有需求,是较为完善的甘特图图表库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/543483.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国考省考行测:资料分析:增量减量计算公式,百分数化分数

国考省考行测&#xff1a;增量减量计算公式 2022找工作是学历、能力和运气的超强结合体! 公务员特招重点就是专业技能&#xff0c;附带行测和申论&#xff0c;而常规国考省考最重要的还是申论和行测&#xff0c;所以大家认真准备吧&#xff0c;我讲一起屡屡申论和行测的重要知…

医院安全(不良)事件管理系统源码,PHP语言开发

医院不良事件上报系统源码 医院安全(不良)事件管理系统 ,是以提高医院医疗服务质量为目的&#xff0c;收集、处理医院内发生的医院安全不良相关事件&#xff0c;进行统计分析&#xff0c;并持续整改&#xff0c;完成闭环管理&#xff1b;为医院医疗服务质量的提升提供信息支撑…

Minio有了这篇文章,比SDK要好入门多了

想学minio&#xff0c;看小编这边文章可以解决你很多问题 一、安装minio1.1、创建文件夹&#xff0c;并在指定文件夹中下载minio文件1.2、赋予minio文件执行权限1.3、启动minio1.4、修改环境变量1.5、指定端口启动minio服务1.6、访问界面 二、Springboot整合Minio2.1、引入mave…

NTBackup 是什么?Windows中如何使用?

NTBackup 已不是 Windows 的内置实用程序&#xff0c;在较新的系统中可以使用他吗&#xff1f;如何才能在 Windows 11/10 或 Windows 7 中恢复BKF文件呢&#xff1f; 什么是 NTBackup&#xff1f;其优势是什么&#xff1f; NTBackup是Windows早期的一个内置实用程序&#xf…

【开源项目】AOP框架Nepxion Matrix原理拆解

项目地址 项目地址&#xff1a;https://toscode.gitee.com/nepxion/Matrix 原理分析 Spring AutoProxy机制 它统一封装接口&#xff08;Spring&#xff09;代理和类代理&#xff08;CGLIB&#xff09;&#xff0c;注解无论在接口和类的头部或者方法上&#xff0c;都可以让业务…

c++ 11标准模板(STL) std::set(七)

定义于头文件 <set> template< class Key, class Compare std::less<Key>, class Allocator std::allocator<Key> > class set;(1)namespace pmr { template <class Key, class Compare std::less<Key>> using se…

CMS搭建篇:内容模型配置-用户管理模型

微信小程序云开发实战-答题积分赛小程序 CMS搭建篇:内容模型配置-用户管理模型 内容模型 内容模型是对数据库中存储的数据结构的描述,包含了内容的属性定义。通过内容模型,内容管理可以自动生成内容管理界面。 这里,我们需要建立一个内容模型,描述用户所具有的属性,如:微…

debounce(防抖)和throttle(节流)小结

前端工程师们都听过看起来很高级的词&#xff0c;节流和防抖&#xff0c;其实节流就是throttle&#xff0c;防抖就是debounce&#xff0c;其实这个也属于前端性能优化的一部分。 节流 像阀门一样控制水流&#xff0c;避免单位时间内流量过大防抖 防止抖动&#xff0c;比节流的…

2023-5-17-CPU架构学习(amd、ard等)

&#x1f37f;*★,*:.☆(&#xffe3;▽&#xffe3;)/$:*.★* &#x1f37f; &#x1f4a5;&#x1f4a5;&#x1f4a5;欢迎来到&#x1f91e;汤姆&#x1f91e;的csdn博文&#x1f4a5;&#x1f4a5;&#x1f4a5; &#x1f49f;&#x1f49f;喜欢的朋友可以关注一下&#xf…

Redis高可用性详解

目录 ​编辑 高可用性&#xff1a; 主从复制&#xff08;Master-Slave Replication&#xff09;&#xff1a; 主从复制的一般工作流程&#xff1a; 哨兵模式&#xff08;Sentinel Mode&#xff09;&#xff1a; 哨兵模式的一般工作流程&#xff1a; 集群模式&#xff08…

【大数据学习篇7】 热门品类Top10分析

在HBase命令行工具中执行“list”命令&#xff0c;查看HBase数据库中的所有数据表。学习目标/Target 掌握热门品类Top10分析实现思路 掌握如何创建Spark连接并读取数据集 掌握利用Spark获取业务数据 掌握利用Spark统计品类的行为类型 掌握利用Spark过滤品类的行为类型 掌握利用…

梯度消失和爆炸问题

一、为什么会产生梯度消失和梯度爆炸&#xff1f; 目前优化神经网络的方法都是基于BP&#xff0c;即根据损失函数计算的误差通过梯度反向传播的方式&#xff0c;指导深度网络权值的更新优化。其中将误差从末层往前传递的过程需要链式法则&#xff08;Chain Rule&#xff09;的…

自定义mysql函数之字符串逗号分割查询(find_in_set)

增强 find_in_set() 在mysql中&#xff0c;我们有时候设计数据库某个字段需要通过逗号进行分割&#xff0c;然后根据传入的字符串查询是否存在的方法进行判断&#xff0c;mysql默认的 find_in_set() 可以对比某个逗号分割的字符串中是否存在指定字符串&#xff0c;例如下面的例…

小程序技术,打开跨端管理的思路,提高客户满意度和忠诚度

小程序容器作为跨端管理的有效工具&#xff0c;已经成为越来越多企业的选择。通过小程序容器&#xff0c;企业可以实现跨平台部署&#xff0c;提供一致的用户体验&#xff0c;整合多种渠道实现全渠道协同&#xff0c;进行个性化营销&#xff0c;以及通过数据分析和监控等手段优…

手把手教你,用Auto-GPT自动写个网站(保姆级)

目录 一、什么是 Auto-GPT 二、用Auto-GPT自动给我实现了一个网站 1、运行过程 2、执行任务 3、运行结果 三、如何安装使用&#xff1f;怎么玩 1、注册OpenAI的账号&#xff0c;并获取key 2、下载Git和Python3&#xff08;无脑安装&#xff09; 3、克隆仓库到本地 4、…

【SVN】SVN常用操作

1、svn客户端安装 下载地址&#xff1a;https://tortoisesvn.net/downloads.zh.html 下SVN客户端及汉化包 &#xff08;根据提示安装即可&#xff09; 2、检查是否安装成功 在空白处&#xff0c;右键&#xff0c;可见TortoiseSVN&#xff0c;如下图所示 3、检出&#xff…

React Antd Typescript开发碰到的问题 DatePicker Radio should update 后端数据回显

需求&#xff1a; DatePicker控件 离职人员默认显示后端传过来的离职时间 有两种类型页面&#xff0c;编辑时可操作&#xff0c;详情时不可操作 进入编辑页面时&#xff0c;状态切换成在职时&#xff0c;清空离职时间框且离职时间框不可用&#xff0c;字段设置为 undefined 状态…

国际top5功能完善在线投资平台app软件最新排名(综合评测)

如今&#xff0c;随着科技的发展&#xff0c;越来越多的人选择使用在线投资app软件来进行投资。但是面对众多的选择&#xff0c;选择一款靠谱的在线投资app软件是非常重要的。首先&#xff0c;我们需要考虑该软件的安全性。投资是一项涉及资金的活动&#xff0c;因此&#xff0…

高精度示波器keysight是德DSOS054、MSOS054销售回收

安捷伦Keysight DSOS054A MSOS054 500MHZ高清晰度示波器 特征&#xff1a; 带宽&#xff1a;500 MHz&#xff0c;具有平坦的频率响应&#xff0c;可实现高信号保真度 频道&#xff1a;4 最大存储深度&#xff1a;800 Mpts&#xff08;2 通道&#xff09;&#xff0c;400 Mpt…

新工匠精神是啥

给工匠精神加入新的“工程师”文化 工程化是现代制造的内核 工程师是工程文化的承载人 趣讲大白话&#xff1a;新工匠精神&#xff0c;新在哪里&#xff1f; 【趣讲信息科技170期】 **************************** 工程师文化起源于硅谷 传承工匠精神的&#xff0c;也要加入工程…