디렉토리
JointJS : 자바 스크립트 프레임 워크의 순서 도식
최근의 연구 프레임 워크는 JS 플로우 차트를 그릴, 그리고 마지막으로 공동을 선택했다. Dagre는 순서도 더 큰 방법을 그릴 수 있습니다.
JointJS 프로필
JointJS는 오픈 소스 프레임 워크 전단 도면이다 흐름도, 흐름 다이어그램 다양한 지원한다. 공동 Rappid는 상용 버전이 좀 더 플러그인을 제공합니다. JointJS 기능은 공식 웹 사이트에서 가져온 다음과 같은 몇 가지 있습니다 :
- 실시간으로 수백 (또는 수천) 요소와 연결을 렌더링 할 수있는
- 다양한 모양을 지원 (사각형, 원, 텍스트, 이미지, 경로 등)
- 높은 이벤트 기반, 사용자는 어떤 사고 대응 용지에서 발생하는 사용자 정의 할 수 있습니다
- 요소 간의 간단한 연결
- 사용자 정의 도면 연결 및 관계
- 평활화는 지능적 라우팅 및 (베 지어 보간 베 지어 보간법에 기초한)
- SVG 기반 맞춤형 프로그래머블 그래픽 렌더링
- NodeJS 지원
- 직렬화 및 JSON을 역 직렬화
짧은 JoingJS에서 오픈 소스 버전은 일상적인 사용을 위해 충분히있다, 강한 흐름도 만드는 프레임 워크입니다.
일반적인 주소 :
API : https://resources.jointjs.com/docs/jointjs/v1.1/joint.html
자습서 : https://resources.jointjs.com/tutorial
JointJS 안녕하세요 세계
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/2.1.0/joint.css" />
</head>
<body>
<!-- content -->
<div id="myholder"></div>
<!-- dependencies 通过CDN加载依赖-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/2.1.0/joint.js"></script>
<!-- code -->
<script type="text/javascript">
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: document.getElementById('myholder'),
model: graph,
width: 600,
height: 100,
gridSize: 1
});
var rect = new joint.shapes.standard.Rectangle();
rect.position(100, 30);
rect.resize(100, 40);
rect.attr({
body: {
fill: 'blue'
},
label: {
text: 'Hello',
fill: 'white'
}
});
rect.addTo(graph);
var rect2 = rect.clone();
rect2.translate(300, 0);
rect2.attr('label/text', 'World!');
rect2.addTo(graph);
var link = new joint.shapes.standard.Link();
link.source(rect);
link.target(rect2);
link.addTo(graph);
</script>
</body>
</html>
안녕하세요 세계 코드는 말할 것도 없다. 여기서 주목해야 할 것은 더 자동 레이아웃 패턴 없지만 수동 달성 번째 레이아웃 RECT을 움직여.
이전과 분리 아키텍처의 종료 후
지원 NodeJs 때문에, 당신은 서버에 무거운 그래픽 렌더링 작업을 넣어, 다음 HTTP 전송 객체를 통해 JSON 직렬화를 통해, 그래서 클라이언트의 압력을 줄일 수 있습니다.
NodeJS 백엔드
var express = require('express');
var joint = require('jointjs');
var app = express();
function get_graph(){
var graph = new joint.dia.Graph();
var rect = new joint.shapes.standard.Rectangle();
rect.position(100, 30);
rect.resize(100, 40);
rect.attr({
body: {
fill: 'blue'
},
label: {
text: 'Hello',
fill: 'white'
}
});
rect.addTo(graph);
var rect2 = rect.clone();
rect2.translate(300, 0);
rect2.attr('label/text', 'World!');
rect2.addTo(graph);
var link = new joint.shapes.standard.Link();
link.source(rect);
link.target(rect2);
link.addTo(graph);
return graph.toJSON();
}
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
next();
});
app.get('/graph', function(req, res){
console.log('[+] send graph json to client')
res.send(get_graph());
});
app.listen(8071);
HTML 프런트 엔드
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/2.1.0/joint.css" />
</head>
<body>
<!-- content -->
<div id="myholder"></div>
<!-- dependencies 通过CDN加载依赖-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/2.1.0/joint.js"></script>
<!-- code -->
<script type="text/javascript">
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: document.getElementById('myholder'),
model: graph,
width: 600,
height: 100,
gridSize: 1
});
$.get('http://192.168.237.128:8071/graph', function(data, statue){
graph.fromJSON(data);
});
</script>
</body>
</html>
다른
자동 레이아웃 자동 레이아웃
JointJS 자동 조판을위한 플러그인을 내장, 원칙 Dagre 라이브러리를 호출됩니다. 공식 API 샘플이 있습니다.
사용 방법 :
VAR graphBBox = joint.layout.DirectedGraph.layout (그래프 {
nodeSep : 50
edgeSep : 80
rankDir "TB"
});
구성 매개 변수 | 주의 |
---|---|
nodeSep | 동일한 랭크의 인접 노드로부터 |
edgeSep | 동일한 랭크의 인접 측에서 |
rankSep | 순위의 다양한 요소 사이의 거리는 |
RANK | 布局方向( "TB" (상하) / "BT" (아래에서 위로) / "LR" (왼쪽에서 오른쪽) / "RL" (오른쪽에서 왼쪽)) |
marginX | 화소 수는 그래프의 왼쪽과 오른쪽 가장자리 주위로 사용한다. |
marginY | 화소 수는 그래프의 상부 주위에 여백과 아래쪽으로 사용한다. |
열하는 사람 | 알고리즘을 정렬. : 가능한 값 'network-simplex' (기본값), 'tight-tree' 또는 'longest-path' . |
resizeClusters | 로 설정 false 하면 부모 요소가 모든 임베디드 아이들을 맞추기 위해 스트레칭하지 않으려면. 기본값은 true . |
clusterPadding | 부모 요소와 임베디드 아이들의 경계 사이의 간격. 그것은 숫자 또는 객체 예를 들어, 수 { left: 10, right: 10, top: 30, bottom: 10 } . 그것은 기본값으로 10 . |
로 setPosition (엘리먼트 위치) | 레이아웃의 마지막 요소의 위치를 설정하는 데 사용되는 함수. 기본값을 사용하지 않으려는 경우에 유용 element.set('position', position) 하지만 통해 애니메이션 방식으로 위치를 설정하려면 전환 . |
setVertices (링크, 정점) | 로 설정하면 true 레이아웃 자신의 정점을 설정하여 링크를 조정합니다. 그것은 기본값으로 false . 이 옵션을 함수로 정의되어있는 경우는 레이아웃의 끝 부분에 링크의 정점을 설정하는 데 사용됩니다. 기본값을 사용하지 않으려는 경우에 유용 link.set('vertices', vertices) 하지만 통해 애니메이션 방식으로 정점을 설정하려면 전환 . |
setLabels (링크 labelPosition, 점) | 로 설정하면 true 레이아웃 자신의 위치를 설정하여 라벨을 조정합니다. 그것은 기본값으로 false . 이 옵션을 함수로 정의되어있는 경우는 레이아웃의 끝 부분에 링크의 레이블을 설정하는 데 사용됩니다. 주 : 첫 번째 라벨 (link.label (0)) 레이아웃으로 배치된다. |
DAGRE | 기본적으로 dagre하는 글로벌 네임 스페이스에 있어야하지만 당신은 또한 매개 변수로 전달할 수 있습니다 |
graphlib | 기본적 graphlib으로 전역 네임 스페이스에 있어야하는,하지만 당신은 매개 변수로 전달할 수 있습니다 |
이제 해보자. NodeJS 백엔드
var express = require('express');
var joint = require('jointjs');
var dagre = require('dagre')
var graphlib = require('graphlib');
var app = express();
function get_graph(){
var graph = new joint.dia.Graph();
var rect = new joint.shapes.standard.Rectangle();
rect.position(100, 30);
rect.resize(100, 40);
rect.attr({
body: {
fill: 'blue'
},
label: {
text: 'Hello',
fill: 'white'
}
});
rect.addTo(graph);
var rect2 = rect.clone();
rect2.translate(300, 0);
rect2.attr('label/text', 'World!');
rect2.addTo(graph);
for(var i=0; i<10; i++){
var cir = new joint.shapes.standard.Circle();
cir.resize(100, 100);
cir.position(10, 10);
cir.attr('root/title', 'joint.shapes.standard.Circle');
cir.attr('label/text', 'Circle' + i);
cir.attr('body/fill', 'lightblue');
cir.addTo(graph);
var ln = new joint.shapes.standard.Link();
ln.source(cir);
ln.target(rect2);
ln.addTo(graph);
}
var link = new joint.shapes.standard.Link();
link.source(rect);
link.target(rect2);
link.addTo(graph);
//auto layout
joint.layout.DirectedGraph.layout(graph, {
nodeSep: 50,
edgeSep: 50,
rankDir: "TB",
dagre: dagre,
graphlib: graphlib
});
return graph.toJSON();
}
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
next();
});
app.get('/graph', function(req, res){
console.log('[+] send graph json to client')
res.send(get_graph());
});
app.listen(8071);
HTML 프런트 엔드
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/jointjs/2.1.0/joint.css" />
</head>
<body>
<!-- content -->
<div id="myholder"></div>
<!-- dependencies 通过CDN加载依赖-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.1/lodash.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.3.3/backbone.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jointjs/2.1.0/joint.js"></script>
<!-- code -->
<script type="text/javascript">
var graph = new joint.dia.Graph;
var paper = new joint.dia.Paper({
el: document.getElementById('myholder'),
model: graph,
width: 2000,
height: 2000,
gridSize: 1
});
$.get('http://192.168.237.128:8071/graph', function(data, statue){
graph.fromJSON(data);
});
</script>
</body>
</html>
결과 :
사용자 정의 HTML 요소를 사용하여
즉 소자 흐름도의 각 포인트는, 사용자 정의 할 수 있고, HTML 코드 버튼, 필드, 및 다른 코드 블록 물품에 직접 첨가 될 수있다.
내 블록 데모는 유사한 효과 highlight.js IDA 제어 흐름 그래프에 의해 달성 될 수있다. 이 기능은 매우 높은 리플레이입니다.
joint.shapes.BBL = {};
joint.shapes.BBL.Element = joint.shapes.basic.Rect.extend({
defaults: joint.util.deepSupplement({
type: 'BBL.Element',
attrs: {
rect: { stroke: 'none', 'fill-opacity': 0 }
}
}, joint.shapes.basic.Rect.prototype.defaults)
});
// Create a custom view for that element that displays an HTML div above it.
// -------------------------------------------------------------------------
joint.shapes.BBL.ElementView = joint.dia.ElementView.extend({
template: [
'<div class="html-element" data-collapse>',
'<label></label><br/>',
'<div class="hljs"><pre><code></code></pre></span></div>',
'</div>'
].join(''),
initialize: function() {
_.bindAll(this, 'updateBox');
joint.dia.ElementView.prototype.initialize.apply(this, arguments);
this.$box = $(_.template(this.template)());
// Prevent paper from handling pointerdown.
this.$box.find('h3').on('mousedown click', function(evt) {
evt.stopPropagation();
});
// Update the box position whenever the underlying model changes.
this.model.on('change', this.updateBox, this);
// Remove the box when the model gets removed from the graph.
this.model.on('remove', this.removeBox, this);
this.updateBox();
},
render: function() {
joint.dia.ElementView.prototype.render.apply(this, arguments);
this.paper.$el.prepend(this.$box);
this.updateBox();
return this;
},
updateBox: function() {
// Set the position and dimension of the box so that it covers the JointJS element.
var bbox = this.model.getBBox();
// Example of updating the HTML with a data stored in the cell model.
this.$box.find('label').text(this.model.get('label'));
this.$box.find('code').html(this.model.get('code'));
var color = this.model.get('color');
this.$box.css({
width: bbox.width,
height: bbox.height,
left: bbox.x,
top: bbox.y,
background: color,
"border-color": color
});
},
removeBox: function(evt) {
this.$box.remove();
}
});