Wantomo commited on
Commit
a3588cc
·
verified ·
1 Parent(s): 226eee8

please create electrical drawing single line diagram simulator

Browse files
Files changed (2) hide show
  1. index.html +9 -6
  2. singleline.html +332 -0
index.html CHANGED
@@ -76,12 +76,15 @@
76
  <body class="bg-gray-100 min-h-screen">
77
  <div class="container mx-auto px-4 py-8">
78
  <header class="mb-8 text-center">
79
- <h1 class="text-4xl font-bold text-gray-800 mb-2">PLC Logic Simulator</h1>
80
- <p class="text-gray-600">Drag, drop, and simulate industrial control logic</p>
81
- </header>
82
-
83
- <div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
84
- <!-- Toolbox -->
 
 
 
85
  <div class="bg-white rounded-lg shadow-md p-4 lg:col-span-1">
86
  <h2 class="text-xl font-semibold mb-4 text-gray-800">Components</h2>
87
  <div class="space-y-3">
 
76
  <body class="bg-gray-100 min-h-screen">
77
  <div class="container mx-auto px-4 py-8">
78
  <header class="mb-8 text-center">
79
+ <h1 class="text-4xl font-bold text-gray-800 mb-2">Industrial Control Simulators</h1>
80
+ <p class="text-gray-600">Drag, drop, and simulate industrial control systems</p>
81
+ <div class="mt-4 flex justify-center space-x-4">
82
+ <a href="index.html" class="px-4 py-2 bg-blue-500 text-white rounded-lg">PLC Simulator</a>
83
+ <a href="singleline.html" class="px-4 py-2 bg-green-500 text-white rounded-lg">Single Line Diagram</a>
84
+ </div>
85
+ </header>
86
+ <div class="grid grid-cols-1 lg:grid-cols-4 gap-6 mt-8">
87
+ <!-- Toolbox -->
88
  <div class="bg-white rounded-lg shadow-md p-4 lg:col-span-1">
89
  <h2 class="text-xl font-semibold mb-4 text-gray-800">Components</h2>
90
  <div class="space-y-3">
singleline.html ADDED
@@ -0,0 +1,332 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Single Line Diagram Simulator</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://unpkg.com/feather-icons"></script>
9
+ <style>
10
+ .workspace {
11
+ background-color: #f8fafc;
12
+ background-image: linear-gradient(#e2e8f0 1px, transparent 1px),
13
+ linear-gradient(90deg, #e2e8f0 1px, transparent 1px);
14
+ background-size: 20px 20px;
15
+ }
16
+ .component {
17
+ cursor: move;
18
+ transition: all 0.2s;
19
+ }
20
+ .component:hover {
21
+ filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.2));
22
+ }
23
+ .busbar {
24
+ height: 10px;
25
+ background-color: #4B5563;
26
+ }
27
+ .transformer {
28
+ width: 60px;
29
+ height: 60px;
30
+ position: relative;
31
+ }
32
+ .circuit-breaker {
33
+ width: 30px;
34
+ height: 30px;
35
+ }
36
+ .generator {
37
+ width: 60px;
38
+ height: 30px;
39
+ border-radius: 4px;
40
+ }
41
+ .load {
42
+ width: 40px;
43
+ height: 40px;
44
+ }
45
+ .wire {
46
+ stroke: #4B5563;
47
+ stroke-width: 2;
48
+ }
49
+ </style>
50
+ </head>
51
+ <body class="bg-gray-100 min-h-screen">
52
+ <div class="container mx-auto px-4 py-8">
53
+ <header class="mb-8 text-center">
54
+ <h1 class="text-4xl font-bold text-gray-800 mb-2">Single Line Diagram Simulator</h1>
55
+ <p class="text-gray-600">Design and simulate electrical power systems</p>
56
+ </header>
57
+
58
+ <div class="grid grid-cols-1 lg:grid-cols-4 gap-6">
59
+ <!-- Toolbox -->
60
+ <div class="bg-white rounded-lg shadow-md p-4 lg:col-span-1">
61
+ <h2 class="text-xl font-semibold mb-4 text-gray-800">Components</h2>
62
+ <div class="space-y-3">
63
+ <div class="bg-gray-100 p-3 rounded-lg flex flex-col items-center cursor-move component" draggable="true" data-type="busbar">
64
+ <svg width="60" height="10">
65
+ <rect width="60" height="10" fill="#4B5563" />
66
+ </svg>
67
+ <span class="mt-2">Busbar</span>
68
+ </div>
69
+ <div class="bg-gray-100 p-3 rounded-lg flex flex-col items-center cursor-move component" draggable="true" data-type="transformer">
70
+ <svg width="60" height="60" viewBox="0 0 60 60">
71
+ <rect x="10" y="10" width="40" height="40" fill="#F59E0B" />
72
+ <text x="30" y="35" text-anchor="middle" fill="white">T</text>
73
+ </svg>
74
+ <span class="mt-2">Transformer</span>
75
+ </div>
76
+ <div class="bg-gray-100 p-3 rounded-lg flex flex-col items-center cursor-move component" draggable="true" data-type="generator">
77
+ <svg width="60" height="30" viewBox="0 0 60 30">
78
+ <rect width="60" height="30" rx="4" fill="#10B981" />
79
+ <text x="30" y="18" text-anchor="middle" fill="white">G</text>
80
+ </svg>
81
+ <span class="mt-2">Generator</span>
82
+ </div>
83
+ <div class="bg-gray-100 p-3 rounded-lg flex flex-col items-center cursor-move component" draggable="true" data-type="circuit-breaker">
84
+ <svg width="30" height="30" viewBox="0 0 30 30">
85
+ <circle cx="15" cy="15" r="12" fill="#EF4444" />
86
+ <line x1="8" y1="8" x2="22" y2="22" stroke="white" stroke-width="2" />
87
+ </svg>
88
+ <span class="mt-2">Circuit Breaker</span>
89
+ </div>
90
+ <div class="bg-gray-100 p-3 rounded-lg flex flex-col items-center cursor-move component" draggable="true" data-type="load">
91
+ <svg width="40" height="40" viewBox="0 0 40 40">
92
+ <circle cx="20" cy="20" r="15" fill="#3B82F6" />
93
+ <text x="20" y="25" text-anchor="middle" fill="white">L</text>
94
+ </svg>
95
+ <span class="mt-2">Load</span>
96
+ </div>
97
+ </div>
98
+ </div>
99
+
100
+ <!-- Workspace -->
101
+ <div class="bg-white rounded-lg shadow-md p-4 lg:col-span-3">
102
+ <div class="flex justify-between items-center mb-4">
103
+ <h2 class="text-xl font-semibold text-gray-800">Diagram Workspace</h2>
104
+ <div class="flex space-x-2">
105
+ <button class="bg-green-500 hover:bg-green-600 text-white px-4 py-2 rounded-lg flex items-center">
106
+ <i data-feather="play" class="mr-2"></i>
107
+ Simulate
108
+ </button>
109
+ <button class="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded-lg flex items-center">
110
+ <i data-feather="save" class="mr-2"></i>
111
+ Save
112
+ </button>
113
+ <button class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg flex items-center">
114
+ <i data-feather="trash-2" class="mr-2"></i>
115
+ Clear
116
+ </button>
117
+ </div>
118
+ </div>
119
+
120
+ <div class="workspace border-2 border-gray-300 rounded-lg p-6 min-h-[500px]" id="diagram-workspace">
121
+ <svg id="diagram-svg" width="100%" height="100%"></svg>
122
+ </div>
123
+ </div>
124
+ </div>
125
+
126
+ <!-- Properties Panel -->
127
+ <div class="mt-8 bg-white rounded-lg shadow-md p-4">
128
+ <h2 class="text-xl font-semibold mb-4 text-gray-800">Component Properties</h2>
129
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
130
+ <div>
131
+ <label class="block text-gray-700 mb-2">Name</label>
132
+ <input type="text" class="w-full px-3 py-2 border border-gray-300 rounded-md" placeholder="Component name">
133
+ </div>
134
+ <div>
135
+ <label class="block text-gray-700 mb-2">Voltage (kV)</label>
136
+ <input type="number" class="w-full px-3 py-2 border border-gray-300 rounded-md" placeholder="11">
137
+ </div>
138
+ <div>
139
+ <label class="block text-gray-700 mb-2">Power (MVA)</label>
140
+ <input type="number" class="w-full px-3 py-2 border border-gray-300 rounded-md" placeholder="50">
141
+ </div>
142
+ <div>
143
+ <label class="block text-gray-700 mb-2">Status</label>
144
+ <select class="w-full px-3 py-2 border border-gray-300 rounded-md">
145
+ <option>Online</option>
146
+ <option>Offline</option>
147
+ <option>Fault</option>
148
+ </select>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ </div>
153
+
154
+ <script>
155
+ document.addEventListener('DOMContentLoaded', function() {
156
+ feather.replace();
157
+
158
+ const svg = document.getElementById('diagram-svg');
159
+ let selectedElement = null;
160
+
161
+ // Simple drag and drop
162
+ const components = document.querySelectorAll('[draggable="true"]');
163
+ const workspace = document.getElementById('diagram-workspace');
164
+
165
+ components.forEach(component => {
166
+ component.addEventListener('dragstart', function(e) {
167
+ e.dataTransfer.setData('type', this.dataset.type);
168
+ });
169
+ });
170
+
171
+ workspace.addEventListener('dragover', function(e) {
172
+ e.preventDefault();
173
+ });
174
+
175
+ workspace.addEventListener('drop', function(e) {
176
+ e.preventDefault();
177
+ const type = e.dataTransfer.getData('type');
178
+ const rect = workspace.getBoundingClientRect();
179
+ const x = e.clientX - rect.left - 30;
180
+ const y = e.clientY - rect.top - 30;
181
+
182
+ switch(type) {
183
+ case 'busbar':
184
+ createBusbar(x, y);
185
+ break;
186
+ case 'transformer':
187
+ createTransformer(x, y);
188
+ break;
189
+ case 'generator':
190
+ createGenerator(x, y);
191
+ break;
192
+ case 'circuit-breaker':
193
+ createCircuitBreaker(x, y);
194
+ break;
195
+ case 'load':
196
+ createLoad(x, y);
197
+ break;
198
+ }
199
+ });
200
+
201
+ function createBusbar(x, y) {
202
+ const busbar = document.createElementNS("http://www.w3.org/2000/svg", "rect");
203
+ busbar.setAttribute('x', x);
204
+ busbar.setAttribute('y', y);
205
+ busbar.setAttribute('width', '120');
206
+ busbar.setAttribute('height', '10');
207
+ busbar.setAttribute('fill', '#4B5563');
208
+ busbar.setAttribute('class', 'component');
209
+ busbar.addEventListener('click', selectElement);
210
+ svg.appendChild(busbar);
211
+ }
212
+
213
+ function createTransformer(x, y) {
214
+ const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
215
+ group.setAttribute('transform', `translate(${x}, ${y})`);
216
+
217
+ const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
218
+ rect.setAttribute('x', '10');
219
+ rect.setAttribute('y', '10');
220
+ rect.setAttribute('width', '40');
221
+ rect.setAttribute('height', '40');
222
+ rect.setAttribute('fill', '#F59E0B');
223
+
224
+ const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
225
+ text.setAttribute('x', '30');
226
+ text.setAttribute('y', '35');
227
+ text.setAttribute('text-anchor', 'middle');
228
+ text.setAttribute('fill', 'white');
229
+ text.textContent = 'T';
230
+
231
+ group.appendChild(rect);
232
+ group.appendChild(text);
233
+ group.setAttribute('class', 'component');
234
+ group.addEventListener('click', selectElement);
235
+ svg.appendChild(group);
236
+ }
237
+
238
+ function createGenerator(x, y) {
239
+ const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
240
+ group.setAttribute('transform', `translate(${x}, ${y})`);
241
+
242
+ const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
243
+ rect.setAttribute('width', '60');
244
+ rect.setAttribute('height', '30');
245
+ rect.setAttribute('rx', '4');
246
+ rect.setAttribute('fill', '#10B981');
247
+
248
+ const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
249
+ text.setAttribute('x', '30');
250
+ text.setAttribute('y', '18');
251
+ text.setAttribute('text-anchor', 'middle');
252
+ text.setAttribute('fill', 'white');
253
+ text.textContent = 'G';
254
+
255
+ group.appendChild(rect);
256
+ group.appendChild(text);
257
+ group.setAttribute('class', 'component');
258
+ group.addEventListener('click', selectElement);
259
+ svg.appendChild(group);
260
+ }
261
+
262
+ function createCircuitBreaker(x, y) {
263
+ const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
264
+ group.setAttribute('transform', `translate(${x}, ${y})`);
265
+
266
+ const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
267
+ circle.setAttribute('cx', '15');
268
+ circle.setAttribute('cy', '15');
269
+ circle.setAttribute('r', '12');
270
+ circle.setAttribute('fill', '#EF4444');
271
+
272
+ const line = document.createElementNS("http://www.w3.org/2000/svg", "line");
273
+ line.setAttribute('x1', '8');
274
+ line.setAttribute('y1', '8');
275
+ line.setAttribute('x2', '22');
276
+ line.setAttribute('y2', '22');
277
+ line.setAttribute('stroke', 'white');
278
+ line.setAttribute('stroke-width', '2');
279
+
280
+ group.appendChild(circle);
281
+ group.appendChild(line);
282
+ group.setAttribute('class', 'component');
283
+ group.addEventListener('click', selectElement);
284
+ svg.appendChild(group);
285
+ }
286
+
287
+ function createLoad(x, y) {
288
+ const group = document.createElementNS("http://www.w3.org/2000/svg", "g");
289
+ group.setAttribute('transform', `translate(${x}, ${y})`);
290
+
291
+ const circle = document.createElementNS("http://www.w3.org/2000/svg", "circle");
292
+ circle.setAttribute('cx', '20');
293
+ circle.setAttribute('cy', '20');
294
+ circle.setAttribute('r', '15');
295
+ circle.setAttribute('fill', '#3B82F6');
296
+
297
+ const text = document.createElementNS("http://www.w3.org/2000/svg", "text");
298
+ text.setAttribute('x', '20');
299
+ text.setAttribute('y', '25');
300
+ text.setAttribute('text-anchor', 'middle');
301
+ text.setAttribute('fill', 'white');
302
+ text.textContent = 'L';
303
+
304
+ group.appendChild(circle);
305
+ group.appendChild(text);
306
+ group.setAttribute('class', 'component');
307
+ group.addEventListener('click', selectElement);
308
+ svg.appendChild(group);
309
+ }
310
+
311
+ function selectElement(e) {
312
+ if (selectedElement) {
313
+ selectedElement.setAttribute('stroke', 'none');
314
+ }
315
+ selectedElement = e.target;
316
+ selectedElement.setAttribute('stroke', '#6366F1');
317
+ selectedElement.setAttribute('stroke-width', '2');
318
+ e.stopPropagation();
319
+ }
320
+
321
+ // Click on empty space to deselect
322
+ svg.addEventListener('click', function(e) {
323
+ if (e.target === svg && selectedElement) {
324
+ selectedElement.setAttribute('stroke', 'none');
325
+ selectedElement = null;
326
+ }
327
+ });
328
+ });
329
+ </script>
330
+ <script>feather.replace();</script>
331
+ </body>
332
+ </html>