Skip to content

Commit ed4ac55

Browse files
authored
dia.attributes: use calc() in various SVG attributes (#1491)
1 parent 15a6429 commit ed4ac55

10 files changed

Lines changed: 641 additions & 11 deletions

File tree

demo/bandwidth/index.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
6+
<title>Carrier Frequency Bandwidth</title>
7+
8+
<link rel="stylesheet" type="text/css" href="../../build/joint.css" />
9+
</head>
10+
<body>
11+
<div id="paper"></div>
12+
13+
<script src="../../node_modules/jquery/dist/jquery.js"></script>
14+
<script src="../../node_modules/lodash/lodash.js"></script>
15+
<script src="../../node_modules/backbone/backbone.js"></script>
16+
17+
<script src="../../build/joint.js"></script>
18+
19+
<script src="src/bandwidth.js"></script>
20+
21+
</body>
22+
</html>

demo/bandwidth/src/bandwidth.js

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
const { dia, g: geometry, V: vectorizer } = joint;
2+
3+
const y = 200;
4+
const x1 = 100;
5+
const x2 = 700;
6+
7+
const graph = new dia.Graph();
8+
const paper = new dia.Paper({
9+
el: document.getElementById('paper'),
10+
width: 800,
11+
height: 300,
12+
model: graph,
13+
async: true,
14+
sorting: dia.Paper.sorting.APPROX,
15+
background: { color: '#F3F7F6' },
16+
defaultConnectionPoint: {
17+
name: 'boundary',
18+
},
19+
restrictTranslate: (elementView) => {
20+
// Restrict the element movement along the line only
21+
const { height } = elementView.model.size();
22+
return new geometry.Rect(x1, y - height, x2 - x1, 0);
23+
}
24+
});
25+
26+
paper.el.style.border = '1px solid #E5E5E5';
27+
28+
// Draw a line behind all cells into the paper
29+
const line = vectorizer('line', {
30+
'x1': x1,
31+
'y1': y,
32+
'x2': x2,
33+
'y2': y,
34+
'stroke': '#333',
35+
'stroke-width': 2
36+
});
37+
line.appendTo(paper.getLayerNode(dia.Paper.Layers.BACK));
38+
39+
// The style can be added in an external CSS file too
40+
const style = vectorizer.createSVGStyle(`
41+
.joint-type-bandwidth .bandwidth__halo,
42+
.joint-type-bandwidth:hover .bandwidth__sideband {
43+
stroke: #FC3465;
44+
}
45+
.joint-type-bandwidth.bandwidth--resizing .bandwidth__halo,
46+
.joint-type-bandwidth:hover .bandwidth__halo {
47+
opacity: 0.5;
48+
}
49+
`);
50+
paper.svg.appendChild(style);
51+
52+
// Bandwidth shape definition
53+
const Bandwidth = dia.Element.define('Bandwidth', {
54+
size: {
55+
width: 100,
56+
height: 50
57+
},
58+
attrs: {
59+
body: {
60+
width: 'calc(w)',
61+
height: 'calc(h)',
62+
strokeWidth: 4,
63+
stroke: '#A0A0A0',
64+
fill: '#FFFFFF'
65+
},
66+
topLabel: {
67+
x: 'calc(0.5*w)',
68+
y: -20,
69+
textVerticalAnchor: 'bottom',
70+
textAnchor: 'middle',
71+
text: 'Carrier\nFrequency',
72+
fontSize: 12,
73+
fontFamily: 'sans-serif',
74+
stroke: '#222222',
75+
},
76+
bottomLabel: {
77+
x: 'calc(0.5*w)',
78+
y: 'calc(h+20)',
79+
textVerticalAnchor: 'top',
80+
textAnchor: 'middle',
81+
text: '50 MHz',
82+
fontSize: 14,
83+
fontFamily: 'sans-serif',
84+
stroke: '#222222'
85+
},
86+
frequencyMarkers: {
87+
fill: 'none',
88+
stroke: '#4666E5',
89+
strokeWidth: 4
90+
},
91+
carrierFrequencyBandwidth: {
92+
d: 'M 10 calc(0.5*h) L calc(w-10) calc(0.5*h)',
93+
pointerEvents: 'none',
94+
sourceMarker: {
95+
'type': 'path',
96+
'd': 'M 10 -5 -1 0 10 5 z'
97+
},
98+
targetMarker: {
99+
'type': 'path',
100+
'd': 'M 10 -5 -1 0 10 5 z'
101+
}
102+
},
103+
carrierFrequency: {
104+
d: 'M calc(.5*w) calc(h+10) calc(.5*w) -20'
105+
},
106+
sidebands: {
107+
fill: 'none',
108+
stroke: '#222222',
109+
strokeWidth: 5,
110+
strokeLinecap: 'round',
111+
cursor: 'col-resize',
112+
event: 'bandwidth:resize'
113+
},
114+
lowerSideband: {
115+
d: 'M 0 0 0 calc(h)',
116+
},
117+
upperSideband: {
118+
d: 'M calc(w) 0 calc(w) calc(h)',
119+
},
120+
halo: {
121+
opacity: 0,
122+
fill: 'white',
123+
pointerEvents: 'none',
124+
r: 'calc(0.5*d+20)',
125+
cx: 'calc(0.5*w)',
126+
cy: 'calc(0.5*h)',
127+
128+
}
129+
}
130+
}, {
131+
markup: [{
132+
tagName: 'circle',
133+
className: 'bandwidth__halo',
134+
selector: 'halo'
135+
}, {
136+
tagName: 'rect',
137+
selector: 'body',
138+
}, {
139+
tagName: 'text',
140+
selector: 'topLabel'
141+
}, {
142+
tagName: 'text',
143+
selector: 'bottomLabel'
144+
}, {
145+
tagName: 'path',
146+
className: 'bandwidth__sideband',
147+
selector: 'lowerSideband',
148+
groupSelector: 'sidebands'
149+
}, {
150+
tagName: 'path',
151+
className: 'bandwidth__sideband',
152+
selector: 'upperSideband',
153+
groupSelector: 'sidebands'
154+
}, {
155+
tagName: 'path',
156+
selector: 'carrierFrequencyBandwidth',
157+
groupSelector: 'frequencyMarkers'
158+
}, {
159+
tagName: 'path',
160+
selector: 'carrierFrequency',
161+
groupSelector: 'frequencyMarkers',
162+
}],
163+
164+
updateFrequencyLabel(opt) {
165+
const { x } = this.getBBox().center();
166+
this.attr('bottomLabel/text', `${x} MHz`, opt);
167+
return this;
168+
}
169+
});
170+
171+
const b1 = new Bandwidth();
172+
b1.position(200, y - 50).updateFrequencyLabel().addTo(graph);
173+
174+
const b2 = new Bandwidth();
175+
b2.position(400, y - 50).updateFrequencyLabel().addTo(graph);
176+
177+
// Update the bandwidth label upon the position or size change
178+
graph.on('change', (bandwidth) => {
179+
if ('size' in bandwidth.changed || 'position' in bandwidth.changed) {
180+
bandwidth.updateFrequencyLabel();
181+
}
182+
});
183+
184+
paper.on('element:pointerdown', function(elementView) {
185+
elementView.model.toFront();
186+
});
187+
188+
// Drag & drop bandwidth resize
189+
paper.on('bandwidth:resize', function(bandwidthView, evt) {
190+
evt.stopPropagation();
191+
bandwidthView.model.toFront();
192+
bandwidthView.el.classList.add('bandwidth--resizing');
193+
bandwidthView.delegateDocumentEvents({
194+
'mousemove': function(evt) {
195+
const { paper, bandwidthView, center } = evt.data;
196+
const { model: bandwidth } = bandwidthView;
197+
const bbox = bandwidth.getBBox();
198+
const point = paper.clientToLocalPoint(evt.clientX, evt.clientY);
199+
const dx = Math.max(Math.abs(point.x - center.x), 1);
200+
const width = 2 * dx;
201+
const x = center.x - dx;
202+
if ((x >= x1) && (x + width <= x2 )) {
203+
bandwidth.set({
204+
size: { width, height: bbox.height },
205+
position: { x, y: bbox.y }
206+
});
207+
}
208+
},
209+
'mouseup': function(evt) {
210+
const { bandwidthView } = evt.data;
211+
bandwidthView.undelegateDocumentEvents();
212+
bandwidthView.el.classList.remove('bandwidth--resizing');
213+
}
214+
}, {
215+
center: bandwidthView.model.getBBox().center(),
216+
paper,
217+
bandwidthView
218+
});
219+
});

0 commit comments

Comments
 (0)