kececilayout 0.5.1__py3-none-any.whl → 0.5.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- kececilayout/__init__.py +8 -1
- kececilayout/_version.py +1 -1
- kececilayout/kececi_layout.py +61 -0
- {kececilayout-0.5.1.dist-info → kececilayout-0.5.2.dist-info}/METADATA +1 -1
- kececilayout-0.5.2.dist-info/RECORD +10 -0
- kececilayout-0.5.1.dist-info/RECORD +0 -10
- {kececilayout-0.5.1.dist-info → kececilayout-0.5.2.dist-info}/WHEEL +0 -0
- {kececilayout-0.5.1.dist-info → kececilayout-0.5.2.dist-info}/licenses/LICENSE +0 -0
- {kececilayout-0.5.1.dist-info → kececilayout-0.5.2.dist-info}/top_level.txt +0 -0
kececilayout/__init__.py
CHANGED
|
@@ -10,7 +10,7 @@ import inspect
|
|
|
10
10
|
import warnings
|
|
11
11
|
|
|
12
12
|
# Paket sürüm numarası
|
|
13
|
-
__version__ = "0.5.
|
|
13
|
+
__version__ = "0.5.2"
|
|
14
14
|
|
|
15
15
|
# =============================================================================
|
|
16
16
|
# OTOMATİK İÇE AKTARMA VE __all__ OLUŞTURMA
|
|
@@ -62,6 +62,9 @@ from .kececi_layout import ( # Veya fonksiyonların bulunduğu asıl modül
|
|
|
62
62
|
_compute_positions,
|
|
63
63
|
_extract_graph_data,
|
|
64
64
|
_validate_directions,
|
|
65
|
+
avg_edge_length,
|
|
66
|
+
_segments_intersect,
|
|
67
|
+
count_edge_crossings,
|
|
65
68
|
|
|
66
69
|
# Drawing functions
|
|
67
70
|
draw_kececi,
|
|
@@ -115,6 +118,9 @@ __all__ = [
|
|
|
115
118
|
'_compute_positions',
|
|
116
119
|
'_extract_graph_data',
|
|
117
120
|
'_validate_directions',
|
|
121
|
+
'avg_edge_length',
|
|
122
|
+
'_segments_intersect',
|
|
123
|
+
'count_edge_crossings',
|
|
118
124
|
|
|
119
125
|
# Drawing functions
|
|
120
126
|
'draw_kececi',
|
|
@@ -166,3 +172,4 @@ def old_function_placeholder():
|
|
|
166
172
|
# Eğer bu eski fonksiyonu da dışa aktarmak istiyorsanız, __all__ listesine ekleyin
|
|
167
173
|
# __all__.append('old_function_placeholder')
|
|
168
174
|
|
|
175
|
+
|
kececilayout/_version.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# _version.py
|
|
2
2
|
|
|
3
|
-
__version__ = "0.5.
|
|
3
|
+
__version__ = "0.5.2"
|
|
4
4
|
__license__ = "AGPL3.0-or-later"
|
|
5
5
|
__description__ = "A deterministic node placement algorithm used in graph visualization. In this layout, nodes are arranged sequentially along a defined primary axis. Each subsequent node is then alternately offset along a secondary, perpendicular axis, typically moving to one side of the primary axis and then the other. Often, the magnitude of this secondary offset increases as nodes progress along the primary axis, creating a characteristic zig-zag or serpentine pattern."
|
|
6
6
|
__author__ = "Mehmet Keçeci"
|
kececilayout/kececi_layout.py
CHANGED
|
@@ -355,6 +355,66 @@ def _compute_positions(nodes: List[Any],
|
|
|
355
355
|
pos[node] = (so, pc) if sa == 'x' else (pc, so)
|
|
356
356
|
return pos
|
|
357
357
|
|
|
358
|
+
def count_edge_crossings(pos, edges):
|
|
359
|
+
"""Basit ama etkili crossing sayacı: (bounding box kesişimi - yaklaşık) (O(m²))"""
|
|
360
|
+
crossings = 0
|
|
361
|
+
segments = []
|
|
362
|
+
|
|
363
|
+
# Tüm edge'leri segment olarak sakla
|
|
364
|
+
for u, v in edges:
|
|
365
|
+
x1, y1 = pos[u]
|
|
366
|
+
x2, y2 = pos[v]
|
|
367
|
+
segments.append(((x1, y1), (x2, y2)))
|
|
368
|
+
|
|
369
|
+
# Tüm segment çiftlerini kontrol et
|
|
370
|
+
for i in range(len(segments)):
|
|
371
|
+
for j in range(i+1, len(segments)):
|
|
372
|
+
if _segments_intersect(segments[i], segments[j]):
|
|
373
|
+
crossings += 1
|
|
374
|
+
return crossings
|
|
375
|
+
|
|
376
|
+
def _segments_intersect(seg1, seg2):
|
|
377
|
+
"""İki doğru parçasının kesişip kesişmediğini kontrol eder (Cohen-Sutherland değil, basit)"""
|
|
378
|
+
(x1, y1), (x2, y2) = seg1
|
|
379
|
+
(x3, y3), (x4, y4) = seg2
|
|
380
|
+
|
|
381
|
+
# Ortak uç noktaları crossing olarak sayma
|
|
382
|
+
if (x1, y1) in [(x3, y3), (x4, y4)] or (x2, y2) in [(x3, y3), (x4, y4)]:
|
|
383
|
+
return False
|
|
384
|
+
|
|
385
|
+
# Yönlendirme fonksiyonu
|
|
386
|
+
def orientation(ax, ay, bx, by, cx, cy):
|
|
387
|
+
val = (by - ay) * (cx - bx) - (bx - ax) * (cy - by)
|
|
388
|
+
if abs(val) < 1e-9: return 0 # colinear
|
|
389
|
+
return 1 if val > 0 else 2 # clockwise / counterclockwise
|
|
390
|
+
|
|
391
|
+
o1 = orientation(x1, y1, x2, y2, x3, y3)
|
|
392
|
+
o2 = orientation(x1, y1, x2, y2, x4, y4)
|
|
393
|
+
o3 = orientation(x3, y3, x4, y4, x1, y1)
|
|
394
|
+
o4 = orientation(x3, y3, x4, y4, x2, y2)
|
|
395
|
+
|
|
396
|
+
# Genel kesişim durumu
|
|
397
|
+
if o1 != o2 and o3 != o4:
|
|
398
|
+
return True
|
|
399
|
+
|
|
400
|
+
return False
|
|
401
|
+
|
|
402
|
+
edges_small = list(G_small.edges())
|
|
403
|
+
cross_basic = count_edge_crossings(pos_basic, edges_small)
|
|
404
|
+
cross_edge_aware = count_edge_crossings(pos_edge_aware, edges_small)
|
|
405
|
+
|
|
406
|
+
def avg_edge_length(pos, edges):
|
|
407
|
+
# Ortalama edge uzunluğu
|
|
408
|
+
total = 0.0
|
|
409
|
+
for u, v in edges:
|
|
410
|
+
x1, y1 = pos[u]
|
|
411
|
+
x2, y2 = pos[v]
|
|
412
|
+
total += math.hypot(x1 - x2, y1 - y2)
|
|
413
|
+
return total / len(edges) if edges else 0
|
|
414
|
+
|
|
415
|
+
avg_len_basic = avg_edge_length(pos_basic, edges_small)
|
|
416
|
+
avg_len_edge_aware = avg_edge_length(pos_edge_aware, edges_small)
|
|
417
|
+
|
|
358
418
|
# =============================================================================
|
|
359
419
|
# 1. TEMEL LAYOUT HESAPLAMA FONKSİYONU (2D)
|
|
360
420
|
# Bu fonksiyon sadece koordinatları hesaplar, çizim yapmaz.
|
|
@@ -2187,3 +2247,4 @@ if __name__ == '__main__':
|
|
|
2187
2247
|
|
|
2188
2248
|
|
|
2189
2249
|
|
|
2250
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
docs/conf.py,sha256=GCnObt4uegIychQdfaWy1ObNytxnf3tvot7PDVZR4mA,2831
|
|
2
|
+
kececilayout/__init__.py,sha256=6vzWAzeAUY88HPt7109i-f9-Oz-StBQRBqNfdZg-HyU,5238
|
|
3
|
+
kececilayout/_version.py,sha256=cUX_TUOh9BsLm15Tv7AWAQ7nrNLystkEoXWJry1ioIc,828
|
|
4
|
+
kececilayout/kececi_layout.py,sha256=T2vjUq77_pgC4swaECEN1U7r57aV058NqPW4KWaklZo,95523
|
|
5
|
+
kececilayout-0.5.2.dist-info/licenses/LICENSE,sha256=xdxzt6hFCDi0ssOOl4UK4E8yuf47W_POYGGnBjwkxaM,34518
|
|
6
|
+
tests/test_sample.py,sha256=dDwjPZyVH5GEOHc2WH-Zv8vFHvAKze0iLiH0HCishYI,10764
|
|
7
|
+
kececilayout-0.5.2.dist-info/METADATA,sha256=cHu9NRJ9NbBJj-rxobd2xMrhCL2jKuNzQcvle90iCpM,121051
|
|
8
|
+
kececilayout-0.5.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
9
|
+
kececilayout-0.5.2.dist-info/top_level.txt,sha256=BaQiBtdzk9y2bVscER5uJlQqSaXN0Wnyg0rTOnFfbqU,24
|
|
10
|
+
kececilayout-0.5.2.dist-info/RECORD,,
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
docs/conf.py,sha256=GCnObt4uegIychQdfaWy1ObNytxnf3tvot7PDVZR4mA,2831
|
|
2
|
-
kececilayout/__init__.py,sha256=_F4gZyKEaGSFDKDF1mmf9ecElnHZEPb8MpDR4ZC2DI0,5080
|
|
3
|
-
kececilayout/_version.py,sha256=5vsPnPaQQ8iUDKwvQ4w9iAPxGKWgS5QSCHmmafyg6b4,828
|
|
4
|
-
kececilayout/kececi_layout.py,sha256=tPxQzSSkVPlpuzI0dOEnLG7UNWAavt-40Om_xkcscxY,93453
|
|
5
|
-
kececilayout-0.5.1.dist-info/licenses/LICENSE,sha256=xdxzt6hFCDi0ssOOl4UK4E8yuf47W_POYGGnBjwkxaM,34518
|
|
6
|
-
tests/test_sample.py,sha256=dDwjPZyVH5GEOHc2WH-Zv8vFHvAKze0iLiH0HCishYI,10764
|
|
7
|
-
kececilayout-0.5.1.dist-info/METADATA,sha256=Lm6FWSftCrqcsMPXZHGT-M8IpXW2FLpq7qgiJBqUYkY,121051
|
|
8
|
-
kececilayout-0.5.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
9
|
-
kececilayout-0.5.1.dist-info/top_level.txt,sha256=BaQiBtdzk9y2bVscER5uJlQqSaXN0Wnyg0rTOnFfbqU,24
|
|
10
|
-
kececilayout-0.5.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|