彩票走势图

甘特图控件DHTMLX Gantt教程:用Node.js实现Gantt(上)

翻译|使用教程|编辑:颜馨|2023-05-12 11:28:27.883|阅读 151 次

概述:本章介绍用Node.js实现Gantt(上),欢迎查阅~

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

相关链接:

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

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

DHTMLX Gantt 最新下载

甘特图控件交流群:764148812

我们用Node.js实现Gantt将基于REST API,用于与服务器通信。Node.js有一套现成的解决方案,所以我们不必从一开始就编写所有的代码。我们还将使用MySQL作为数据存储。

第1步:创建项目

首先,我们将创建一个项目文件夹,然后添加所需的依赖项。我们将使用以下模块:

  • Express - 一个用于 Node 的微型框架.js
  • 正文解析器 - 节点.js解析工具

因此,让我们创建一个项目文件夹并将其命名为“dhx-gantt-app”:

mkdir dhx-gantt-app
cd dhx-gantt-app
添加依赖项

现在我们将创建 package.json 文件。我们将使用以下命令在其中指定依赖项:

npm init -y

文件准备就绪后,打开它并将上面列出的依赖项放入其中。结果将类似于这个:

{
"name": "dhx-gantt-app",
"version": "1.0.2",
"description": "",
"main": "server.js",
"dependencies": {
"body-parser": "^1.19.1",
"express": "^4.17.2"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server.js"
},
"keywords": [],
"author": "",
"license": "MIT"
}

最后,我们需要使用以下命令安装添加的依赖项:

npm install
准备后端

我们将遵循一个基本的快速设置:我们将为我们的应用程序后端提供一个 js 文件(我们称之为“server.js”), 静态文件(名为“公共”)和单个 HTML 页面的文件夹。

整个项目结构如下:

dhx-gantt-app
├── node_modules
├── server.js
├── package.json
└── public
└── index.html

创建一个名为 server 的新文件.js并将以下代码添加到其中:

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');

const port = 1337;
const app = express();

app.use(express.static(path.join(__dirname, "public")));
app.use(bodyParser.urlencoded({ extended: true }));

app.listen(port, () =>{
console.log("Server is running on port "+port+"...");
});

我们在此代码中所做的:

  • 定义了静态文件将从“公共”文件夹提供
  • 将应用程序附加到本地主机的 1337 端口

在下一步中,我们将创建“公共”文件夹。此文件夹将包含我们应用程序的主页 - index.html

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

让我们创建公用文件夹并向其中添加一个索引.html文件。然后打开 index.html 文件并填充以下内容:

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

<script src="//cdn.dhtmlx.com/gantt/edge/dhtmlxgantt.js"></script>
<link href="//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>

让我们检查一下我们目前得到了什么。转到项目文件夹并从命令行运行以下命令:

node server.js

然后在浏览器中打开 //127.0.0.1:1337。您应该会看到一个带有空甘特图的页面,如下所示:

空甘特图

第 3 步:准备数据库

下一步是创建数据库。我们将创建一个简单的数据库,其中包含两个用于任务和链接的表:

CREATE TABLE `gantt_links` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`source` int(11) NOT NULL,
`target` int(11) NOT NULL,
`type` varchar(1) NOT NULL,
PRIMARY KEY (`id`)
);
CREATE TABLE `gantt_tasks` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`text` varchar(255) NOT NULL,
`start_date` datetime NOT NULL,
`duration` int(11) NOT NULL,
`progress` float NOT NULL,
`parent` int(11) NOT NULL,
PRIMARY KEY (`id`)
);

并添加一些测试数据:

INSERT INTO `gantt_tasks` VALUES ('1', 'Project #1', '2017-04-01 00:00:00',
'5', '0.8', '0');
INSERT INTO `gantt_tasks` VALUES ('2', 'Task #1', '2017-04-06 00:00:00',
'4', '0.5', '1');
INSERT INTO `gantt_tasks` VALUES ('3', 'Task #2', '2017-04-05 00:00:00',
'6', '0.7', '1');
INSERT INTO `gantt_tasks` VALUES ('4', 'Task #3', '2017-04-07 00:00:00',
'2', '0', '1');
INSERT INTO `gantt_tasks` VALUES ('5', 'Task #1.1', '2017-04-05 00:00:00',
'5', '0.34', '2');
INSERT INTO `gantt_tasks` VALUES ('6', 'Task #1.2', '2017-04-11 13:22:17',
'4', '0.5', '2');
INSERT INTO `gantt_tasks` VALUES ('7', 'Task #2.1', '2017-04-07 00:00:00',
'5', '0.2', '3');
INSERT INTO `gantt_tasks` VALUES ('8', 'Task #2.2', '2017-04-06 00:00:00',
'4', '0.9', '3');
第 4 步:加载数据

现在我们需要实现数据加载。

由于我们使用MySQL,因此我们需要安装可用于访问它的必要模块。在本教程中,CRUD 操作将基于承诺方法实现。 因此,我们将使用 promise-mysql - 一个 Node.js 包,用于使用 promise 和 蓝鸟承诺图书馆。

要安装它们,我们可以使用控制台。我们需要指定以下组件版本,因为较新的组件版本彼此不兼容或没有旧函数:

npm install bluebird@3.7.2 --save
npm install promise-mysql@5.1.0 --save
npm install date-format-lite@17.7.0 --save

您可以选择任何其他适当的模块。代码相当简单,您可以使用一组不同的工具实现相同的逻辑。

客户端需要 JSON 格式的数据。因此,我们将创建一个返回此类数据的路由。

正如您可能已经提到的,数据中有“start_date”属性,该属性保留为日期对象。因此,它应该在 格式正确。为此,我们将使用另一个模块 - date-format-lite。

npm install date-format-lite --save

现在,您应该打开 server.js 文件并使用以下内容更新其代码:

const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');

const port = 1337;
const app = express();

app.use(express.static(path.join(__dirname, "public")));
app.use(bodyParser.urlencoded({ extended: true }));

app.listen(port, () =>{
console.log("Server is running on port "+port+"...");
});

const Promise = require('bluebird');
require("date-format-lite");

const mysql = require('promise-mysql');
async function serverСonfig() {
const db = await mysql.createPool({
host: 'localhost',
user: 'root',
password: '',
database: 'gantt_howto_node'
});
app.get("/data", (req, res) => {
Promise.all([
db.query("SELECT * FROM gantt_tasks"),
db.query("SELECT * FROM gantt_links")
]).then(results => {
let tasks = results[0],
links = results[1];

for (let i = 0; i < tasks.length; i++) {
tasks[i].start_date = tasks[i].start_date.format("YYYY-MM-DD hh:mm:ss");
tasks[i].open = true;
}

res.send({
data: tasks,
collections: { links: links }
});

}).catch(error => {
sendResponse(res, "error", null, error);
});
});

function sendResponse(res, action, tid, error) {

if (action == "error")
console.log(error);

let result = {
action: action
};
if (tid !== undefined && tid !== null)
result.tid = tid;

res.send(result);
}
};

我们在此代码中所做的:

  • 打开了与我们的数据库的 MySql 连接
  • 定义在 GET /data 请求中,我们将从任务和链接表中读取数据并格式化它们,以便它们可以在客户端上解析

请注意,我们还添加了 open 属性,以确保任务树最初将展开。

现在,我们可以从客户端调用此路由:

gantt.config.date_format = "%Y-%m-%d %H:%i:%s";

gantt.init("gantt_here");

gantt.load("/data");

请注意,date_format配置指定来自服务器的日期(任务start_date)的格式。

现在让我们通过打开 //127.0.0.1:1337 来运行应用程序。甘特图将加载我们之前添加到数据库中的测试数据。

测试数据

第5步:保存更改

我们应该实现的最后一件事是数据保存。 为此,我们需要一个代码,它将客户端发生的更新发送回服务器。 转到 public/index.html 并将gantt.dataProcessor添加到页面:

public/index.html
gantt.config.date_format = "%Y-%m-%d %H:%i:%s";

gantt.init("gantt_here");

gantt.load("/data");

const dp = new gantt.dataProcessor("/data");
dp.init(gantt);
dp.setTransactionMode("REST");

让我们更深入地看看它扮演什么角色。

请求和响应

在每个用户操作上:添加、更改或删除新任务或链接,DataProcessor 将通过向 AJAX 发送请求来做出反应 相应的网址。该请求将包含将更改保存在数据库中所需的所有参数。

由于DataProcessor是在REST模式下初始化的,因此它将对每种类型的操作使用不同的HTTP动词。 服务器端集成一文中提供了 HTTP 谓词列表以及请求和响应详细信息。

好吧,我们现在需要做的是添加所需的路由和处理程序,这会将对客户端所做的更改放入数据库,放入服务器.js文件中。 生成的代码将相当宽敞:

// add a new task
app.post("/data/task", (req, res) => {
let task = getTask(req.body);

db.query("INSERT INTO gantt_tasks(text, start_date, duration, progress, parent)"
+ " VALUES (?,?,?,?,?)",
[task.text, task.start_date, task.duration, task.progress, task.parent])
.then(result => {
sendResponse(res, "inserted", result.insertId);
})
.catch(error => {
sendResponse(res, "error", null, error);
});
});

// update a task
app.put("/data/task/:id", (req, res) => {
let sid = req.params.id,
task = getTask(req.body);

db.query("UPDATE gantt_tasks SET text = ?, start_date = ?, "
+ "duration = ?, progress = ?, parent = ? WHERE id = ?",
[task.text, task.start_date, task.duration, task.progress, task.parent, sid])
.then(result => {
sendResponse(res, "updated");
})
.catch(error => {
sendResponse(res, "error", null, error);
});
});


// delete a task
app.delete("/data/task/:id", (req, res) => {
let sid = req.params.id;
db.query("DELETE FROM gantt_tasks WHERE id = ?", [sid])
.then(result => {
sendResponse(res, "deleted");
})
.catch(error => {
sendResponse(res, "error", null, error);
});
});

// add a link
app.post("/data/link", (req, res) => {
let link = getLink(req.body);

db.query("INSERT INTO gantt_links(source, target, type) VALUES (?,?,?)",
[link.source, link.target, link.type])
.then(result => {
sendResponse(res, "inserted", result.insertId);
})
.catch(error => {
sendResponse(res, "error", null, error);
});
});

// update a link
app.put("/data/link/:id", (req, res) => {
let sid = req.params.id,
link = getLink(req.body);

db.query("UPDATE gantt_links SET source = ?, target = ?, type = ? WHERE id = ?",
[link.source, link.target, link.type, sid])
.then(result => {
sendResponse(res, "updated");
})
.catch(error => {
sendResponse(res, "error", null, error);
});
});

// delete a link
app.delete("/data/link/:id", (req, res) => {
let sid = req.params.id;
db.query("DELETE FROM gantt_links WHERE id = ?", [sid])
.then(result => {
sendResponse(res, "deleted");
})
.catch(error => {
sendResponse(res, "error", null, error);
});
});


function getTask(data) {
return {
text: data.text,
start_date: data.start_date.date("YYYY-MM-DD"),
duration: data.duration,
progress: data.progress || 0,
parent: data.parent
};
}

function getLink(data) {
return {
source: data.source,
target: data.target,
type: data.type
};
}

我们创建了两组路由:一组用于任务实体,另一组用于链接实体。 相应地,“/data/task”URL 将用于与 到具有任务的操作,并且“/data/link”URL将用于处理包含带有链接的操作的数据的请求。

请求类型非常简单:

  • POST - 将新项目插入数据库
  • PUT - 更新现有记录
  • 删除 - 删除项目

响应将是一个 JSON 对象,具有执行的操作类型或“错误”,以防代码失败。

POST 请求的响应还将包含新记录的数据库 ID。 它将应用于客户端,因此可以将新项映射到数据库实体。

就这样。打开 //127.0.0.1:1337,您将看到一个完全可操作的甘特图。

可操作的甘特图

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


甘特图控件交流群:764148812

欢迎进群交流讨论,获取更多帮助请联系


标签:

本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn


为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP