kececilayout 0.2.4__tar.gz → 0.2.5__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kececilayout
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: 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.
5
5
  Home-page: https://github.com/WhiteSymmetry/kececilayout
6
6
  Author: Mehmet Keçeci
@@ -64,6 +64,8 @@ Dynamic: summary
64
64
  [![PyPI version](https://badge.fury.io/py/kececilayout.svg)](https://badge.fury.io/py/kececilayout)
65
65
  [![PyPI Downloads](https://static.pepy.tech/badge/kececilayout)](https://pepy.tech/projects/kececilayout)
66
66
  [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
67
+ [![CI/CD](https://github.com/WhiteSymmetry/kececilayout/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/WhiteSymmetry/kececilayout/actions/workflows/ci-cd.yml)
68
+ [![Linted with Ruff](https://img.shields.io/badge/Linted%20with-Ruff-green?logo=python&logoColor=white)](https://github.com/astral-sh/ruff)
67
69
 
68
70
  ---
69
71
 
@@ -762,6 +764,10 @@ If this library was useful to you in your research, please cite us. Following th
762
764
 
763
765
  ```
764
766
 
767
+ Keçeci, M. (2025). The Keçeci Layout: A Deterministic Visualisation Framework for the Structural Analysis of Ordered Systems in Chemistry and Environmental Science. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.16696713
768
+
769
+ Keçeci, M. (2025). The Keçeci Layout: A Deterministic, Order-Preserving Visualization Algorithm for Structured Systems. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.16526798
770
+
765
771
  Keçeci, M. (2025). Keçeci Deterministic Zigzag Layout. WorkflowHub. https://doi.org/10.48546/workflowhub.document.31.1
766
772
 
767
773
  Keçeci, M. (2025). Keçeci Zigzag Layout Algorithm. Authorea. https://doi.org/10.22541/au.175087581.16524538/v1
@@ -780,7 +786,7 @@ Keçeci, M. (2025, July 3). The Keçeci Layout: A Structural Approach for Interd
780
786
 
781
787
  Keçeci, M. (2025). Beyond Topology: Deterministic and Order-Preserving Graph Visualization with the Keçeci Layout. WorkflowHub. https://doi.org/10.48546/workflowhub.document.34.4
782
788
 
783
- Keçeci, M. (2025). A Graph-Theoretic Perspective on the Keçeci Layout: Structuring Cross-Disciplinary Inquiry. Preprints. https://doi.org/10.20944/preprints202507.0589
789
+ Keçeci, M. (2025). A Graph-Theoretic Perspective on the Keçeci Layout: Structuring Cross-Disciplinary Inquiry. Preprints. https://doi.org/10.20944/preprints202507.0589.v1
784
790
 
785
791
  Keçeci, M. (2025). Keçeci Layout. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.15314328
786
792
 
@@ -793,9 +799,16 @@ Keçeci, M. (2025, May 1). Kececilayout. Open Science Articles (OSAs), Zenodo. h
793
799
  ### Chicago
794
800
 
795
801
  ```
802
+
803
+ Keçeci, Mehmet. The Keçeci Layout: A Deterministic Visualisation Framework for the Structural Analysis of Ordered Systems in Chemistry and Environmental Science. Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.16696713
804
+
805
+ Keçeci, Mehmet. The Keçeci Layout: A Deterministic, Order-Preserving Visualization Algorithm for Structured Systems. Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.16526798
806
+
796
807
  Keçeci, Mehmet. kececilayout [Data set]. WorkflowHub, 2025. https://doi.org/10.48546/workflowhub.datafile.17.1
797
808
 
798
- Keçeci, Mehmet. "Kececilayout". Zenodo, 01 May 2025. https://doi.org/10.5281/zenodo.15313946.
809
+ Keçeci, Mehmet. "Kececilayout". Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.15313946.
799
810
 
800
- Keçeci, Mehmet. "Keçeci Layout", 01 May 2025. https://doi.org/10.5281/zenodo.15314329.
811
+ Keçeci, Mehmet. "Keçeci Layout". Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.15314329.
801
812
  ```
813
+
814
+
@@ -26,6 +26,8 @@
26
26
  [![PyPI version](https://badge.fury.io/py/kececilayout.svg)](https://badge.fury.io/py/kececilayout)
27
27
  [![PyPI Downloads](https://static.pepy.tech/badge/kececilayout)](https://pepy.tech/projects/kececilayout)
28
28
  [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
29
+ [![CI/CD](https://github.com/WhiteSymmetry/kececilayout/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/WhiteSymmetry/kececilayout/actions/workflows/ci-cd.yml)
30
+ [![Linted with Ruff](https://img.shields.io/badge/Linted%20with-Ruff-green?logo=python&logoColor=white)](https://github.com/astral-sh/ruff)
29
31
 
30
32
  ---
31
33
 
@@ -724,6 +726,10 @@ If this library was useful to you in your research, please cite us. Following th
724
726
 
725
727
  ```
726
728
 
729
+ Keçeci, M. (2025). The Keçeci Layout: A Deterministic Visualisation Framework for the Structural Analysis of Ordered Systems in Chemistry and Environmental Science. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.16696713
730
+
731
+ Keçeci, M. (2025). The Keçeci Layout: A Deterministic, Order-Preserving Visualization Algorithm for Structured Systems. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.16526798
732
+
727
733
  Keçeci, M. (2025). Keçeci Deterministic Zigzag Layout. WorkflowHub. https://doi.org/10.48546/workflowhub.document.31.1
728
734
 
729
735
  Keçeci, M. (2025). Keçeci Zigzag Layout Algorithm. Authorea. https://doi.org/10.22541/au.175087581.16524538/v1
@@ -742,7 +748,7 @@ Keçeci, M. (2025, July 3). The Keçeci Layout: A Structural Approach for Interd
742
748
 
743
749
  Keçeci, M. (2025). Beyond Topology: Deterministic and Order-Preserving Graph Visualization with the Keçeci Layout. WorkflowHub. https://doi.org/10.48546/workflowhub.document.34.4
744
750
 
745
- Keçeci, M. (2025). A Graph-Theoretic Perspective on the Keçeci Layout: Structuring Cross-Disciplinary Inquiry. Preprints. https://doi.org/10.20944/preprints202507.0589
751
+ Keçeci, M. (2025). A Graph-Theoretic Perspective on the Keçeci Layout: Structuring Cross-Disciplinary Inquiry. Preprints. https://doi.org/10.20944/preprints202507.0589.v1
746
752
 
747
753
  Keçeci, M. (2025). Keçeci Layout. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.15314328
748
754
 
@@ -755,9 +761,16 @@ Keçeci, M. (2025, May 1). Kececilayout. Open Science Articles (OSAs), Zenodo. h
755
761
  ### Chicago
756
762
 
757
763
  ```
764
+
765
+ Keçeci, Mehmet. The Keçeci Layout: A Deterministic Visualisation Framework for the Structural Analysis of Ordered Systems in Chemistry and Environmental Science. Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.16696713
766
+
767
+ Keçeci, Mehmet. The Keçeci Layout: A Deterministic, Order-Preserving Visualization Algorithm for Structured Systems. Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.16526798
768
+
758
769
  Keçeci, Mehmet. kececilayout [Data set]. WorkflowHub, 2025. https://doi.org/10.48546/workflowhub.datafile.17.1
759
770
 
760
- Keçeci, Mehmet. "Kececilayout". Zenodo, 01 May 2025. https://doi.org/10.5281/zenodo.15313946.
771
+ Keçeci, Mehmet. "Kececilayout". Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.15313946.
761
772
 
762
- Keçeci, Mehmet. "Keçeci Layout", 01 May 2025. https://doi.org/10.5281/zenodo.15314329.
773
+ Keçeci, Mehmet. "Keçeci Layout". Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.15314329.
763
774
  ```
775
+
776
+
@@ -0,0 +1,76 @@
1
+ # __init__.py
2
+ # Bu dosya paketin başlangıç noktası olarak çalışır.
3
+ # Alt modülleri yükler, sürüm bilgileri tanımlar ve geriye dönük uyumluluk için uyarılar sağlar.
4
+
5
+ from __future__ import annotations
6
+ import importlib
7
+ import warnings
8
+ import os
9
+ # if os.getenv("DEVELOPMENT") == "true":
10
+ # importlib.reload(kececi_layout) # F821 undefined name 'kececi_layout'
11
+
12
+ # Dışa aktarılacak semboller listesi
13
+ __all__ = [
14
+ 'kececi_layout_v4',
15
+ 'kececi_layout',
16
+ 'kececi_layout_v4_nx',
17
+ 'kececi_layout_v4_networkx',
18
+ 'kececi_layout_v4_ig',
19
+ 'kececi_layout_v4_igraph',
20
+ 'kececi_layout_v4_nk',
21
+ 'kececi_layout_v4_networkit',
22
+ 'kececi_layout_v4_gg',
23
+ 'kececi_layout_v4_graphillion',
24
+ 'kececi_layout_v4_rx',
25
+ 'kececi_layout_v4_rustworkx',
26
+ 'generate_random_rx_graph',
27
+ 'kececi_layout_v4_pure',
28
+ 'generate_random_graph',
29
+ 'generate_random_graph_ig'
30
+ ]
31
+
32
+ # Göreli modül içe aktarmaları
33
+ # F401 hatasını önlemek için sadece kullanacağınız şeyleri dışa aktarın
34
+ # Aksi halde linter'lar "imported but unused" uyarısı verir
35
+ try:
36
+ #from .kececi_layout import * # gerekirse burada belirli fonksiyonları seçmeli yapmak daha güvenlidir
37
+ #from . import kececi_layout # Modülün kendisine doğrudan erişim isteniyorsa
38
+ from .kececi_layout import (
39
+ kececi_layout_v4,
40
+ kececi_layout,
41
+ kececi_layout_v4_nx,
42
+ kececi_layout_v4_networkx,
43
+ kececi_layout_v4_ig,
44
+ kececi_layout_v4_igraph,
45
+ kececi_layout_v4_nk,
46
+ kececi_layout_v4_networkit,
47
+ kececi_layout_v4_gg,
48
+ kececi_layout_v4_graphillion,
49
+ kececi_layout_v4_rx,
50
+ kececi_layout_v4_rustworkx,
51
+ generate_random_rx_graph,
52
+ kececi_layout_v4_pure,
53
+ generate_random_graph,
54
+ generate_random_graph_ig
55
+ )
56
+ except ImportError as e:
57
+ warnings.warn(f"Gerekli modül yüklenemedi: {e}", ImportWarning)
58
+
59
+ # Eski bir fonksiyonun yer tutucusu - gelecekte kaldırılacak
60
+ def eski_fonksiyon():
61
+ """
62
+ Kaldırılması planlanan eski bir fonksiyondur.
63
+ Lütfen alternatif fonksiyonları kullanın.
64
+ """
65
+ warnings.warn(
66
+ "eski_fonksiyon() artık kullanılmamaktadır ve gelecekte kaldırılacaktır. "
67
+ "Lütfen yeni alternatif fonksiyonları kullanın. "
68
+ "Keçeci Layout; Python 3.7-3.14 sürümlerinde sorunsuz çalışmalıdır.",
69
+ category=DeprecationWarning,
70
+ stacklevel=2
71
+ )
72
+
73
+ # Paket sürüm numarası
74
+ __version__ = "0.2.5"
75
+
76
+
@@ -1,9 +1,10 @@
1
1
  # _version.py
2
2
 
3
- __version__ = "0.2.2"
3
+ __version__ = "0.2.5"
4
4
  __license__ = "MIT"
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"
7
7
  __url__ = "https://github.com/WhiteSymmetry/kececilayout"
8
8
  __docs__ = "https://github.com/WhiteSymmetry/kececilayout" # Opsiyonel: Dokümantasyon linki
9
9
  __dependencies__ = ["python>=3.9"] # Diğer bağımlılıkları da ekleyebilirsiniz
10
+
@@ -108,11 +108,16 @@ def kececi_layout_v4(graph, primary_spacing=1.0, secondary_spacing=1.0,
108
108
  else:
109
109
  # Desteklenmeyen tip veya kütüphane kurulu değilse
110
110
  supported_types = []
111
- if nx: supported_types.append("NetworkX")
112
- if rx: supported_types.append("Rustworkx")
113
- if ig: supported_types.append("igraph")
114
- if nk: supported_types.append("Networkit")
115
- if gg: supported_types.append("Graphillion.GraphSet")
111
+ if nx:
112
+ supported_types.append("NetworkX")
113
+ if rx:
114
+ supported_types.append("Rustworkx")
115
+ if ig:
116
+ supported_types.append("igraph")
117
+ if nk:
118
+ supported_types.append("Networkit")
119
+ if gg:
120
+ supported_types.append("Graphillion.GraphSet")
116
121
  raise TypeError(f"Unsupported graph type: {type(graph)}. Desteklenen türler: {', '.join(supported_types)}")
117
122
 
118
123
  # ----- Buradan sonrası tüm kütüphaneler için ortak -----
@@ -141,16 +146,21 @@ def kececi_layout_v4(graph, primary_spacing=1.0, secondary_spacing=1.0,
141
146
 
142
147
  # 1. Ana eksen koordinatını hesapla
143
148
  if primary_direction == 'top-down':
144
- primary_coord = i * -primary_spacing; secondary_axis = 'x'
149
+ primary_coord = i * -primary_spacing;
150
+ secondary_axis = 'x'
145
151
  elif primary_direction == 'bottom-up':
146
- primary_coord = i * primary_spacing; secondary_axis = 'x'
152
+ primary_coord = i * primary_spacing;
153
+ secondary_axis = 'x'
147
154
  elif primary_direction == 'left-to-right':
148
- primary_coord = i * primary_spacing; secondary_axis = 'y'
155
+ primary_coord = i * primary_spacing;
156
+ secondary_axis = 'y'
149
157
  else: # right-to-left
150
- primary_coord = i * -primary_spacing; secondary_axis = 'y'
158
+ primary_coord = i * -primary_spacing;
159
+ secondary_axis = 'y'
151
160
 
152
161
  # 2. Yan eksen ofsetini hesapla (zigzag)
153
- if i == 0: secondary_offset_multiplier = 0.0
162
+ if i == 0:
163
+ secondary_offset_multiplier = 0.0
154
164
  else:
155
165
  start_mult = 1.0 if secondary_start in ['right', 'up'] else -1.0
156
166
  magnitude = math.ceil(i / 2.0)
@@ -159,8 +169,10 @@ def kececi_layout_v4(graph, primary_spacing=1.0, secondary_spacing=1.0,
159
169
  secondary_coord = secondary_offset_multiplier * secondary_spacing
160
170
 
161
171
  # 3. (x, y) koordinatlarını ata
162
- if secondary_axis == 'x': x, y = secondary_coord, primary_coord
163
- else: x, y = primary_coord, secondary_coord
172
+ if secondary_axis == 'x':
173
+ x, y = secondary_coord, primary_coord
174
+ else:
175
+ x, y = primary_coord, secondary_coord
164
176
 
165
177
  # Sonuç sözlüğüne ekle
166
178
  pos[node_id] = (x, y)
@@ -230,11 +242,16 @@ def kececi_layout(graph, primary_spacing=1.0, secondary_spacing=1.0,
230
242
  else:
231
243
  # Desteklenmeyen tip veya kütüphane kurulu değilse
232
244
  supported_types = []
233
- if nx: supported_types.append("NetworkX")
234
- if rx: supported_types.append("Rustworkx")
235
- if ig: supported_types.append("igraph")
236
- if nk: supported_types.append("Networkit")
237
- if gg: supported_types.append("Graphillion.GraphSet")
245
+ if nx:
246
+ supported_types.append("NetworkX")
247
+ if rx:
248
+ supported_types.append("Rustworkx")
249
+ if ig:
250
+ supported_types.append("igraph")
251
+ if nk:
252
+ supported_types.append("Networkit")
253
+ if gg:
254
+ supported_types.append("Graphillion.GraphSet")
238
255
  raise TypeError(f"Unsupported graph type: {type(graph)}. Desteklenen türler: {', '.join(supported_types)}")
239
256
 
240
257
  # ----- Buradan sonrası tüm kütüphaneler için ortak -----
@@ -263,16 +280,21 @@ def kececi_layout(graph, primary_spacing=1.0, secondary_spacing=1.0,
263
280
 
264
281
  # 1. Ana eksen koordinatını hesapla
265
282
  if primary_direction == 'top-down':
266
- primary_coord = i * -primary_spacing; secondary_axis = 'x'
283
+ primary_coord = i * -primary_spacing;
284
+ secondary_axis = 'x'
267
285
  elif primary_direction == 'bottom-up':
268
- primary_coord = i * primary_spacing; secondary_axis = 'x'
286
+ primary_coord = i * primary_spacing;
287
+ secondary_axis = 'x'
269
288
  elif primary_direction == 'left-to-right':
270
- primary_coord = i * primary_spacing; secondary_axis = 'y'
289
+ primary_coord = i * primary_spacing;
290
+ secondary_axis = 'y'
271
291
  else: # right-to-left
272
- primary_coord = i * -primary_spacing; secondary_axis = 'y'
292
+ primary_coord = i * -primary_spacing;
293
+ secondary_axis = 'y'
273
294
 
274
295
  # 2. Yan eksen ofsetini hesapla (zigzag)
275
- if i == 0: secondary_offset_multiplier = 0.0
296
+ if i == 0:
297
+ secondary_offset_multiplier = 0.0
276
298
  else:
277
299
  start_mult = 1.0 if secondary_start in ['right', 'up'] else -1.0
278
300
  magnitude = math.ceil(i / 2.0)
@@ -281,8 +303,10 @@ def kececi_layout(graph, primary_spacing=1.0, secondary_spacing=1.0,
281
303
  secondary_coord = secondary_offset_multiplier * secondary_spacing
282
304
 
283
305
  # 3. (x, y) koordinatlarını ata
284
- if secondary_axis == 'x': x, y = secondary_coord, primary_coord
285
- else: x, y = primary_coord, secondary_coord
306
+ if secondary_axis == 'x':
307
+ x, y = secondary_coord, primary_coord
308
+ else:
309
+ x, y = primary_coord, secondary_coord
286
310
 
287
311
  # Sonuç sözlüğüne ekle
288
312
  pos[node_id] = (x, y)
@@ -299,19 +323,26 @@ def kececi_layout_v4_nx(graph, primary_spacing=1.0, secondary_spacing=1.0,
299
323
  # NetworkX 2.x ve 3.x uyumluluğu için listeye çevirme
300
324
  nodes = sorted(list(graph.nodes()))
301
325
  num_nodes = len(nodes)
302
- if num_nodes == 0: return {}
326
+ if num_nodes == 0:
327
+ return {}
303
328
 
304
329
  is_vertical = primary_direction in ['top-down', 'bottom-up']
305
330
  is_horizontal = primary_direction in ['left-to-right', 'right-to-left']
306
- if not (is_vertical or is_horizontal): raise ValueError(f"Invalid primary_direction: {primary_direction}")
307
- if is_vertical and secondary_start not in ['right', 'left']: raise ValueError(f"Invalid secondary_start for vertical: {secondary_start}")
308
- if is_horizontal and secondary_start not in ['up', 'down']: raise ValueError(f"Invalid secondary_start for horizontal: {secondary_start}")
331
+ if not (is_vertical or is_horizontal):
332
+ raise ValueError(f"Invalid primary_direction: {primary_direction}")
333
+ if is_vertical and secondary_start not in ['right', 'left']:
334
+ raise ValueError(f"Invalid secondary_start for vertical: {secondary_start}")
335
+ if is_horizontal and secondary_start not in ['up', 'down']:
336
+ raise ValueError(f"Invalid secondary_start for horizontal: {secondary_start}")
309
337
 
310
338
  for i, node_id in enumerate(nodes):
311
339
  # 1. Ana Eksen Koordinatını Hesapla
312
- if primary_direction == 'top-down': primary_coord, secondary_axis = i * -primary_spacing, 'x'
313
- elif primary_direction == 'bottom-up': primary_coord, secondary_axis = i * primary_spacing, 'x'
314
- elif primary_direction == 'left-to-right': primary_coord, secondary_axis = i * primary_spacing, 'y'
340
+ if primary_direction == 'top-down':
341
+ primary_coord, secondary_axis = i * -primary_spacing, 'x'
342
+ elif primary_direction == 'bottom-up':
343
+ primary_coord, secondary_axis = i * primary_spacing, 'x'
344
+ elif primary_direction == 'left-to-right':
345
+ primary_coord, secondary_axis = i * primary_spacing, 'y'
315
346
  else: # right-to-left
316
347
  primary_coord, secondary_axis = i * -primary_spacing, 'y'
317
348
 
@@ -345,19 +376,26 @@ def kececi_layout_v4_networkx(graph, primary_spacing=1.0, secondary_spacing=1.0,
345
376
  # NetworkX 2.x ve 3.x uyumluluğu için listeye çevirme
346
377
  nodes = sorted(list(graph.nodes()))
347
378
  num_nodes = len(nodes)
348
- if num_nodes == 0: return {}
379
+ if num_nodes == 0:
380
+ return {}
349
381
 
350
382
  is_vertical = primary_direction in ['top-down', 'bottom-up']
351
383
  is_horizontal = primary_direction in ['left-to-right', 'right-to-left']
352
- if not (is_vertical or is_horizontal): raise ValueError(f"Invalid primary_direction: {primary_direction}")
353
- if is_vertical and secondary_start not in ['right', 'left']: raise ValueError(f"Invalid secondary_start for vertical: {secondary_start}")
354
- if is_horizontal and secondary_start not in ['up', 'down']: raise ValueError(f"Invalid secondary_start for horizontal: {secondary_start}")
384
+ if not (is_vertical or is_horizontal):
385
+ raise ValueError(f"Invalid primary_direction: {primary_direction}")
386
+ if is_vertical and secondary_start not in ['right', 'left']:
387
+ raise ValueError(f"Invalid secondary_start for vertical: {secondary_start}")
388
+ if is_horizontal and secondary_start not in ['up', 'down']:
389
+ raise ValueError(f"Invalid secondary_start for horizontal: {secondary_start}")
355
390
 
356
391
  for i, node_id in enumerate(nodes):
357
392
  # 1. Ana Eksen Koordinatını Hesapla
358
- if primary_direction == 'top-down': primary_coord, secondary_axis = i * -primary_spacing, 'x'
359
- elif primary_direction == 'bottom-up': primary_coord, secondary_axis = i * primary_spacing, 'x'
360
- elif primary_direction == 'left-to-right': primary_coord, secondary_axis = i * primary_spacing, 'y'
393
+ if primary_direction == 'top-down':
394
+ primary_coord, secondary_axis = i * -primary_spacing, 'x'
395
+ elif primary_direction == 'bottom-up':
396
+ primary_coord, secondary_axis = i * primary_spacing, 'x'
397
+ elif primary_direction == 'left-to-right':
398
+ primary_coord, secondary_axis = i * primary_spacing, 'y'
361
399
  else: # right-to-left
362
400
  primary_coord, secondary_axis = i * -primary_spacing, 'y'
363
401
 
@@ -741,15 +779,20 @@ def kececi_layout_v4_gg(graph_set: gg.GraphSet,
741
779
  for i, node_id in enumerate(nodes):
742
780
  # ... (Koordinat hesaplama kısmı aynı kalır) ...
743
781
  if primary_direction == 'top-down':
744
- primary_coord = i * -primary_spacing; secondary_axis = 'x'
782
+ primary_coord = i * -primary_spacing;
783
+ secondary_axis = 'x'
745
784
  elif primary_direction == 'bottom-up':
746
- primary_coord = i * primary_spacing; secondary_axis = 'x'
785
+ primary_coord = i * primary_spacing;
786
+ secondary_axis = 'x'
747
787
  elif primary_direction == 'left-to-right':
748
- primary_coord = i * primary_spacing; secondary_axis = 'y'
788
+ primary_coord = i * primary_spacing;
789
+ secondary_axis = 'y'
749
790
  else: # right-to-left
750
- primary_coord = i * -primary_spacing; secondary_axis = 'y'
791
+ primary_coord = i * -primary_spacing;
792
+ secondary_axis = 'y'
751
793
 
752
- if i == 0: secondary_offset_multiplier = 0.0
794
+ if i == 0:
795
+ secondary_offset_multiplier = 0.0
753
796
  else:
754
797
  start_mult = 1.0 if secondary_start in ['right', 'up'] else -1.0
755
798
  magnitude = math.ceil(i / 2.0)
@@ -757,8 +800,10 @@ def kececi_layout_v4_gg(graph_set: gg.GraphSet,
757
800
  secondary_offset_multiplier = start_mult * magnitude * side
758
801
  secondary_coord = secondary_offset_multiplier * secondary_spacing
759
802
 
760
- if secondary_axis == 'x': x, y = secondary_coord, primary_coord
761
- else: x, y = primary_coord, secondary_coord
803
+ if secondary_axis == 'x':
804
+ x, y = secondary_coord, primary_coord
805
+ else:
806
+ x, y = primary_coord, secondary_coord
762
807
  pos[node_id] = (x, y)
763
808
 
764
809
  return pos
@@ -802,15 +847,20 @@ def kececi_layout_v4_graphillion(graph_set: gg.GraphSet,
802
847
  for i, node_id in enumerate(nodes):
803
848
  # ... (Koordinat hesaplama kısmı aynı kalır) ...
804
849
  if primary_direction == 'top-down':
805
- primary_coord = i * -primary_spacing; secondary_axis = 'x'
850
+ primary_coord = i * -primary_spacing;
851
+ secondary_axis = 'x'
806
852
  elif primary_direction == 'bottom-up':
807
- primary_coord = i * primary_spacing; secondary_axis = 'x'
853
+ primary_coord = i * primary_spacing;
854
+ secondary_axis = 'x'
808
855
  elif primary_direction == 'left-to-right':
809
- primary_coord = i * primary_spacing; secondary_axis = 'y'
856
+ primary_coord = i * primary_spacing;
857
+ secondary_axis = 'y'
810
858
  else: # right-to-left
811
- primary_coord = i * -primary_spacing; secondary_axis = 'y'
859
+ primary_coord = i * -primary_spacing;
860
+ secondary_axis = 'y'
812
861
 
813
- if i == 0: secondary_offset_multiplier = 0.0
862
+ if i == 0:
863
+ secondary_offset_multiplier = 0.0
814
864
  else:
815
865
  start_mult = 1.0 if secondary_start in ['right', 'up'] else -1.0
816
866
  magnitude = math.ceil(i / 2.0)
@@ -818,32 +868,44 @@ def kececi_layout_v4_graphillion(graph_set: gg.GraphSet,
818
868
  secondary_offset_multiplier = start_mult * magnitude * side
819
869
  secondary_coord = secondary_offset_multiplier * secondary_spacing
820
870
 
821
- if secondary_axis == 'x': x, y = secondary_coord, primary_coord
822
- else: x, y = primary_coord, secondary_coord
871
+ if secondary_axis == 'x':
872
+ x, y = secondary_coord, primary_coord
873
+ else:
874
+ x, y = primary_coord, secondary_coord
823
875
  pos[node_id] = (x, y)
824
876
 
825
877
  return pos
826
878
 
827
- def kececi_layout_v4_rx(graph: rx.PyGraph, primary_spacing=1.0, secondary_spacing=1.0,
879
+ def kececi_layout_v4_rx(graph:
880
+ rx.PyGraph, primary_spacing=1.0, secondary_spacing=1.0,
828
881
  primary_direction='top-down', secondary_start='right'):
829
882
  pos = {}
830
883
  nodes = sorted(graph.node_indices())
831
884
  num_nodes = len(nodes)
832
- if num_nodes == 0: return {}
885
+ if num_nodes == 0:
886
+ return {}
833
887
 
834
888
  is_vertical = primary_direction in ['top-down', 'bottom-up']
835
889
  is_horizontal = primary_direction in ['left-to-right', 'right-to-left']
836
- if not (is_vertical or is_horizontal): raise ValueError(f"Invalid primary_direction: {primary_direction}")
837
- if is_vertical and secondary_start not in ['right', 'left']: raise ValueError(f"Invalid secondary_start for vertical: {secondary_start}")
838
- if is_horizontal and secondary_start not in ['up', 'down']: raise ValueError(f"Invalid secondary_start for horizontal: {secondary_start}")
890
+ if not (is_vertical or is_horizontal):
891
+ raise ValueError(f"Invalid primary_direction: {primary_direction}")
892
+ if is_vertical and secondary_start not in ['right', 'left']:
893
+ raise ValueError(f"Invalid secondary_start for vertical: {secondary_start}")
894
+ if is_horizontal and secondary_start not in ['up', 'down']:
895
+ raise ValueError(f"Invalid secondary_start for horizontal: {secondary_start}")
839
896
 
840
897
  for i, node_index in enumerate(nodes):
841
- if primary_direction == 'top-down': primary_coord, secondary_axis = i * -primary_spacing, 'x'
842
- elif primary_direction == 'bottom-up': primary_coord, secondary_axis = i * primary_spacing, 'x'
843
- elif primary_direction == 'left-to-right': primary_coord, secondary_axis = i * primary_spacing, 'y'
844
- else: primary_coord, secondary_axis = i * -primary_spacing, 'y'
898
+ if primary_direction == 'top-down':
899
+ primary_coord, secondary_axis = i * -primary_spacing, 'x'
900
+ elif primary_direction == 'bottom-up':
901
+ primary_coord, secondary_axis = i * primary_spacing, 'x'
902
+ elif primary_direction == 'left-to-right':
903
+ primary_coord, secondary_axis = i * primary_spacing, 'y'
904
+ else:
905
+ primary_coord, secondary_axis = i * -primary_spacing, 'y'
845
906
 
846
- if i == 0: secondary_offset_multiplier = 0.0
907
+ if i == 0:
908
+ secondary_offset_multiplier = 0.0
847
909
  else:
848
910
  start_mult = 1.0 if secondary_start in ['right', 'up'] else -1.0
849
911
  magnitude = math.ceil(i / 2.0)
@@ -855,26 +917,36 @@ def kececi_layout_v4_rx(graph: rx.PyGraph, primary_spacing=1.0, secondary_spacin
855
917
  pos[node_index] = np.array([x, y])
856
918
  return pos
857
919
 
858
- def kececi_layout_v4_rustworkx(graph: rx.PyGraph, primary_spacing=1.0, secondary_spacing=1.0,
920
+ def kececi_layout_v4_rustworkx(graph:
921
+ rx.PyGraph, primary_spacing=1.0, secondary_spacing=1.0,
859
922
  primary_direction='top-down', secondary_start='right'):
860
923
  pos = {}
861
924
  nodes = sorted(graph.node_indices())
862
925
  num_nodes = len(nodes)
863
- if num_nodes == 0: return {}
926
+ if num_nodes == 0:
927
+ return {}
864
928
 
865
929
  is_vertical = primary_direction in ['top-down', 'bottom-up']
866
930
  is_horizontal = primary_direction in ['left-to-right', 'right-to-left']
867
- if not (is_vertical or is_horizontal): raise ValueError(f"Invalid primary_direction: {primary_direction}")
868
- if is_vertical and secondary_start not in ['right', 'left']: raise ValueError(f"Invalid secondary_start for vertical: {secondary_start}")
869
- if is_horizontal and secondary_start not in ['up', 'down']: raise ValueError(f"Invalid secondary_start for horizontal: {secondary_start}")
931
+ if not (is_vertical or is_horizontal):
932
+ raise ValueError(f"Invalid primary_direction: {primary_direction}")
933
+ if is_vertical and secondary_start not in ['right', 'left']:
934
+ raise ValueError(f"Invalid secondary_start for vertical: {secondary_start}")
935
+ if is_horizontal and secondary_start not in ['up', 'down']:
936
+ raise ValueError(f"Invalid secondary_start for horizontal: {secondary_start}")
870
937
 
871
938
  for i, node_index in enumerate(nodes):
872
- if primary_direction == 'top-down': primary_coord, secondary_axis = i * -primary_spacing, 'x'
873
- elif primary_direction == 'bottom-up': primary_coord, secondary_axis = i * primary_spacing, 'x'
874
- elif primary_direction == 'left-to-right': primary_coord, secondary_axis = i * primary_spacing, 'y'
875
- else: primary_coord, secondary_axis = i * -primary_spacing, 'y'
939
+ if primary_direction == 'top-down':
940
+ primary_coord, secondary_axis = i * -primary_spacing, 'x'
941
+ elif primary_direction == 'bottom-up':
942
+ primary_coord, secondary_axis = i * primary_spacing, 'x'
943
+ elif primary_direction == 'left-to-right':
944
+ primary_coord, secondary_axis = i * primary_spacing, 'y'
945
+ else:
946
+ primary_coord, secondary_axis = i * -primary_spacing, 'y'
876
947
 
877
- if i == 0: secondary_offset_multiplier = 0.0
948
+ if i == 0:
949
+ secondary_offset_multiplier = 0.0
878
950
  else:
879
951
  start_mult = 1.0 if secondary_start in ['right', 'up'] else -1.0
880
952
  magnitude = math.ceil(i / 2.0)
@@ -890,8 +962,10 @@ def kececi_layout_v4_rustworkx(graph: rx.PyGraph, primary_spacing=1.0, secondary
890
962
  # Rastgele Graf Oluşturma Fonksiyonu (Rustworkx ile - Düzeltilmiş subgraph)
891
963
  # =============================================================================
892
964
  def generate_random_rx_graph(min_nodes=5, max_nodes=15, edge_prob_min=0.15, edge_prob_max=0.4):
893
- if min_nodes < 2: min_nodes = 2
894
- if max_nodes < min_nodes: max_nodes = min_nodes
965
+ if min_nodes < 2:
966
+ min_nodes = 2
967
+ if max_nodes < min_nodes:
968
+ max_nodes = min_nodes
895
969
  while True:
896
970
  num_nodes_target = random.randint(min_nodes, max_nodes)
897
971
  edge_probability = random.uniform(edge_prob_min, edge_prob_max)
@@ -902,22 +976,29 @@ def generate_random_rx_graph(min_nodes=5, max_nodes=15, edge_prob_min=0.15, edge
902
976
  if random.random() < edge_probability:
903
977
  G_candidate.add_edge(node_indices[i], node_indices[j], None)
904
978
 
905
- if G_candidate.num_nodes() == 0: continue
906
- if num_nodes_target > 1 and G_candidate.num_edges() == 0: continue
979
+ if G_candidate.num_nodes() == 0:
980
+ continue
981
+ if num_nodes_target > 1 and G_candidate.num_edges() == 0:
982
+ continue
907
983
 
908
984
  if not rx.is_connected(G_candidate):
909
985
  components = rx.connected_components(G_candidate)
910
- if not components: continue
986
+ if not components:
987
+ continue
911
988
  largest_cc_nodes_indices = max(components, key=len, default=set())
912
- if len(largest_cc_nodes_indices) < 2 and num_nodes_target >=2 : continue
913
- if not largest_cc_nodes_indices: continue
989
+ if len(largest_cc_nodes_indices) < 2 and num_nodes_target >=2 :
990
+ continue
991
+ if not largest_cc_nodes_indices:
992
+ continue
914
993
  # Set'i listeye çevirerek subgraph oluştur
915
994
  G = G_candidate.subgraph(list(largest_cc_nodes_indices))
916
- if G.num_nodes() == 0: continue
995
+ if G.num_nodes() == 0:
996
+ continue
917
997
  else:
918
998
  G = G_candidate
919
999
 
920
- if G.num_nodes() >= 2: break
1000
+ if G.num_nodes() >= 2:
1001
+ break
921
1002
  print(f"Oluşturulan Rustworkx Graf: {G.num_nodes()} Düğüm, {G.num_edges()} Kenar (Başlangıç p={edge_probability:.3f})")
922
1003
  return G
923
1004
 
@@ -939,20 +1020,28 @@ def kececi_layout_v4_pure(nodes, primary_spacing=1.0, secondary_spacing=1.0,
939
1020
  sorted_nodes = list(nodes)
940
1021
 
941
1022
  num_nodes = len(sorted_nodes)
942
- if num_nodes == 0: return {}
1023
+ if num_nodes == 0:
1024
+ return {}
943
1025
  is_vertical = primary_direction in ['top-down', 'bottom-up']
944
1026
  is_horizontal = primary_direction in ['left-to-right', 'right-to-left']
945
- if not (is_vertical or is_horizontal): raise ValueError(f"Invalid primary_direction: {primary_direction}")
946
- if is_vertical and secondary_start not in ['right', 'left']: raise ValueError(f"Dikey yön için geçersiz secondary_start: {secondary_start}")
947
- if is_horizontal and secondary_start not in ['up', 'down']: raise ValueError(f"Yatay yön için geçersiz secondary_start: {secondary_start}")
1027
+ if not (is_vertical or is_horizontal):
1028
+ raise ValueError(f"Invalid primary_direction: {primary_direction}")
1029
+ if is_vertical and secondary_start not in ['right', 'left']:
1030
+ raise ValueError(f"Dikey yön için geçersiz secondary_start: {secondary_start}")
1031
+ if is_horizontal and secondary_start not in ['up', 'down']:
1032
+ raise ValueError(f"Yatay yön için geçersiz secondary_start: {secondary_start}")
948
1033
 
949
1034
  for i, node_id in enumerate(sorted_nodes):
950
1035
  primary_coord = 0.0
951
1036
  secondary_axis = ''
952
- if primary_direction == 'top-down': primary_coord, secondary_axis = i * -primary_spacing, 'x'
953
- elif primary_direction == 'bottom-up': primary_coord, secondary_axis = i * primary_spacing, 'x'
954
- elif primary_direction == 'left-to-right': primary_coord, secondary_axis = i * primary_spacing, 'y'
955
- else: primary_coord, secondary_axis = i * -primary_spacing, 'y'
1037
+ if primary_direction == 'top-down':
1038
+ primary_coord, secondary_axis = i * -primary_spacing, 'x'
1039
+ elif primary_direction == 'bottom-up':
1040
+ primary_coord, secondary_axis = i * primary_spacing, 'x'
1041
+ elif primary_direction == 'left-to-right':
1042
+ primary_coord, secondary_axis = i * primary_spacing, 'y'
1043
+ else:
1044
+ primary_coord, secondary_axis = i * -primary_spacing, 'y'
956
1045
 
957
1046
  secondary_offset_multiplier = 0.0
958
1047
  if i > 0:
@@ -971,27 +1060,37 @@ def kececi_layout_v4_pure(nodes, primary_spacing=1.0, secondary_spacing=1.0,
971
1060
  # =============================================================================
972
1061
  def generate_random_graph(min_nodes=0, max_nodes=200, edge_prob_min=0.15, edge_prob_max=0.4):
973
1062
 
974
- if min_nodes < 2: min_nodes = 2
975
- if max_nodes < min_nodes: max_nodes = min_nodes
1063
+ if min_nodes < 2:
1064
+ min_nodes = 2
1065
+ if max_nodes < min_nodes:
1066
+ max_nodes = min_nodes
976
1067
  while True:
977
1068
  num_nodes_target = random.randint(min_nodes, max_nodes)
978
1069
  edge_probability = random.uniform(edge_prob_min, edge_prob_max)
979
1070
  G_candidate = nx.gnp_random_graph(num_nodes_target, edge_probability, seed=None)
980
- if G_candidate.number_of_nodes() == 0: continue
1071
+ if G_candidate.number_of_nodes() == 0:
1072
+ continue
981
1073
  # Düzeltme: 0 kenarlı ama >1 düğümlü grafı da tekrar dene
982
- if num_nodes_target > 1 and G_candidate.number_of_edges() == 0 : continue
1074
+ if num_nodes_target > 1 and G_candidate.number_of_edges() == 0 :
1075
+ continue
983
1076
 
984
1077
  if not nx.is_connected(G_candidate):
985
1078
  # Düzeltme: default=set() kullanmak yerine önce kontrol et
986
1079
  connected_components = list(nx.connected_components(G_candidate))
987
- if not connected_components: continue # Bileşen yoksa tekrar dene
1080
+ if not connected_components:
1081
+ continue # Bileşen yoksa tekrar dene
988
1082
  largest_cc_nodes = max(connected_components, key=len)
989
- if len(largest_cc_nodes) < 2 and num_nodes_target >=2 : continue
990
- if not largest_cc_nodes: continue # Bu aslında gereksiz ama garanti olsun
1083
+ if len(largest_cc_nodes) < 2 and num_nodes_target >=2 :
1084
+ continue
1085
+ if not largest_cc_nodes:
1086
+ continue # Bu aslında gereksiz ama garanti olsun
991
1087
  G = G_candidate.subgraph(largest_cc_nodes).copy()
992
- if G.number_of_nodes() == 0: continue
993
- else: G = G_candidate
994
- if G.number_of_nodes() >= 2: break
1088
+ if G.number_of_nodes() == 0:
1089
+ continue
1090
+ else:
1091
+ G = G_candidate
1092
+ if G.number_of_nodes() >= 2:
1093
+ break
995
1094
  G = nx.convert_node_labels_to_integers(G, first_label=0)
996
1095
  print(f"Oluşturulan Graf: {G.number_of_nodes()} Düğüm, {G.number_of_edges()} Kenar (Başlangıç p={edge_probability:.3f})")
997
1096
  return G
@@ -999,24 +1098,36 @@ def generate_random_graph(min_nodes=0, max_nodes=200, edge_prob_min=0.15, edge_p
999
1098
  def generate_random_graph_ig(min_nodes=0, max_nodes=200, edge_prob_min=0.15, edge_prob_max=0.4):
1000
1099
  """igraph kullanarak rastgele bağlı bir graf oluşturur."""
1001
1100
 
1002
- if min_nodes < 2: min_nodes = 2
1003
- if max_nodes < min_nodes: max_nodes = min_nodes
1101
+ if min_nodes < 2:
1102
+ min_nodes = 2
1103
+ if max_nodes < min_nodes:
1104
+ max_nodes = min_nodes
1004
1105
  while True:
1005
1106
  num_nodes_target = random.randint(min_nodes, max_nodes)
1006
1107
  edge_probability = random.uniform(edge_prob_min, edge_prob_max)
1007
1108
  g_candidate = ig.Graph.Erdos_Renyi(n=num_nodes_target, p=edge_probability, directed=False)
1008
- if g_candidate.vcount() == 0: continue
1009
- if num_nodes_target > 1 and g_candidate.ecount() == 0 : continue
1109
+ if g_candidate.vcount() == 0:
1110
+ continue
1111
+ if num_nodes_target > 1 and g_candidate.ecount() == 0 :
1112
+ continue
1010
1113
  if not g_candidate.is_connected(mode='weak'):
1011
1114
  components = g_candidate.components(mode='weak')
1012
- if not components or len(components) == 0: continue
1115
+ if not components or len(components) == 0:
1116
+ continue
1013
1117
  largest_cc_subgraph = components.giant()
1014
- if largest_cc_subgraph.vcount() < 2 and num_nodes_target >=2 : continue
1118
+ if largest_cc_subgraph.vcount() < 2 and num_nodes_target >=2 :
1119
+ continue
1015
1120
  g = largest_cc_subgraph
1016
- if g.vcount() == 0: continue
1017
- else: g = g_candidate
1018
- if g.vcount() >= 2: break
1121
+ if g.vcount() == 0:
1122
+ continue
1123
+ else:
1124
+ g = g_candidate
1125
+ if g.vcount() >= 2:
1126
+ break
1019
1127
  print(f"Oluşturulan igraph Graf: {g.vcount()} Düğüm, {g.ecount()} Kenar (Başlangıç p={edge_probability:.3f})")
1020
1128
  g.vs["label"] = [str(i) for i in range(g.vcount())]
1021
1129
  g.vs["degree"] = g.degree()
1022
1130
  return g
1131
+
1132
+
1133
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kececilayout
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: 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.
5
5
  Home-page: https://github.com/WhiteSymmetry/kececilayout
6
6
  Author: Mehmet Keçeci
@@ -64,6 +64,8 @@ Dynamic: summary
64
64
  [![PyPI version](https://badge.fury.io/py/kececilayout.svg)](https://badge.fury.io/py/kececilayout)
65
65
  [![PyPI Downloads](https://static.pepy.tech/badge/kececilayout)](https://pepy.tech/projects/kececilayout)
66
66
  [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-2.1-4baaaa.svg)](CODE_OF_CONDUCT.md)
67
+ [![CI/CD](https://github.com/WhiteSymmetry/kececilayout/actions/workflows/ci-cd.yml/badge.svg)](https://github.com/WhiteSymmetry/kececilayout/actions/workflows/ci-cd.yml)
68
+ [![Linted with Ruff](https://img.shields.io/badge/Linted%20with-Ruff-green?logo=python&logoColor=white)](https://github.com/astral-sh/ruff)
67
69
 
68
70
  ---
69
71
 
@@ -762,6 +764,10 @@ If this library was useful to you in your research, please cite us. Following th
762
764
 
763
765
  ```
764
766
 
767
+ Keçeci, M. (2025). The Keçeci Layout: A Deterministic Visualisation Framework for the Structural Analysis of Ordered Systems in Chemistry and Environmental Science. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.16696713
768
+
769
+ Keçeci, M. (2025). The Keçeci Layout: A Deterministic, Order-Preserving Visualization Algorithm for Structured Systems. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.16526798
770
+
765
771
  Keçeci, M. (2025). Keçeci Deterministic Zigzag Layout. WorkflowHub. https://doi.org/10.48546/workflowhub.document.31.1
766
772
 
767
773
  Keçeci, M. (2025). Keçeci Zigzag Layout Algorithm. Authorea. https://doi.org/10.22541/au.175087581.16524538/v1
@@ -780,7 +786,7 @@ Keçeci, M. (2025, July 3). The Keçeci Layout: A Structural Approach for Interd
780
786
 
781
787
  Keçeci, M. (2025). Beyond Topology: Deterministic and Order-Preserving Graph Visualization with the Keçeci Layout. WorkflowHub. https://doi.org/10.48546/workflowhub.document.34.4
782
788
 
783
- Keçeci, M. (2025). A Graph-Theoretic Perspective on the Keçeci Layout: Structuring Cross-Disciplinary Inquiry. Preprints. https://doi.org/10.20944/preprints202507.0589
789
+ Keçeci, M. (2025). A Graph-Theoretic Perspective on the Keçeci Layout: Structuring Cross-Disciplinary Inquiry. Preprints. https://doi.org/10.20944/preprints202507.0589.v1
784
790
 
785
791
  Keçeci, M. (2025). Keçeci Layout. Open Science Articles (OSAs), Zenodo. https://doi.org/10.5281/zenodo.15314328
786
792
 
@@ -793,9 +799,16 @@ Keçeci, M. (2025, May 1). Kececilayout. Open Science Articles (OSAs), Zenodo. h
793
799
  ### Chicago
794
800
 
795
801
  ```
802
+
803
+ Keçeci, Mehmet. The Keçeci Layout: A Deterministic Visualisation Framework for the Structural Analysis of Ordered Systems in Chemistry and Environmental Science. Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.16696713
804
+
805
+ Keçeci, Mehmet. The Keçeci Layout: A Deterministic, Order-Preserving Visualization Algorithm for Structured Systems. Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.16526798
806
+
796
807
  Keçeci, Mehmet. kececilayout [Data set]. WorkflowHub, 2025. https://doi.org/10.48546/workflowhub.datafile.17.1
797
808
 
798
- Keçeci, Mehmet. "Kececilayout". Zenodo, 01 May 2025. https://doi.org/10.5281/zenodo.15313946.
809
+ Keçeci, Mehmet. "Kececilayout". Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.15313946.
799
810
 
800
- Keçeci, Mehmet. "Keçeci Layout", 01 May 2025. https://doi.org/10.5281/zenodo.15314329.
811
+ Keçeci, Mehmet. "Keçeci Layout". Open Science Articles (OSAs), Zenodo, 2025. https://doi.org/10.5281/zenodo.15314329.
801
812
  ```
813
+
814
+
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="kececilayout",
5
- version="0.2.4",
5
+ version="0.2.5",
6
6
  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.",
7
7
  long_description=open("README.md").read(),
8
8
  long_description_content_type="text/markdown",
@@ -20,7 +20,7 @@ setup(
20
20
  "networkit",
21
21
  "graphillion",
22
22
  "pycairo" ,
23
- "cairocffi",
23
+ "cairocffi"
24
24
  ],
25
25
  extras_require={
26
26
 
@@ -28,8 +28,9 @@ setup(
28
28
  classifiers=[
29
29
  "Programming Language :: Python :: 3",
30
30
  "License :: OSI Approved :: MIT License",
31
- "Operating System :: OS Independent",
31
+ "Operating System :: OS Independent"
32
32
  ],
33
33
  python_requires='>=3.9',
34
34
  license="MIT",
35
35
  )
36
+
@@ -1,37 +0,0 @@
1
- # __init__.py
2
- # Bu dosya paketin başlangıç noktası olarak çalışır.
3
- # Alt modülleri yükler, sürüm bilgileri tanımlar ve geriye dönük uyumluluk için uyarılar sağlar.
4
-
5
- from __future__ import annotations
6
- import importlib
7
- import warnings
8
- import os
9
- # if os.getenv("DEVELOPMENT") == "true":
10
- # importlib.reload(kececi_layout) # F821 undefined name 'kececi_layout'
11
-
12
- # Göreli modül içe aktarmaları
13
- # F401 hatasını önlemek için sadece kullanacağınız şeyleri dışa aktarın
14
- # Aksi halde linter'lar "imported but unused" uyarısı verir
15
- try:
16
- from .kececi_layout import * # gerekirse burada belirli fonksiyonları seçmeli yapmak daha güvenlidir
17
- from . import kececi_layout # Modülün kendisine doğrudan erişim isteniyorsa
18
- except ImportError as e:
19
- warnings.warn(f"Gerekli modül yüklenemedi: {e}", ImportWarning)
20
-
21
- # Eski bir fonksiyonun yer tutucusu - gelecekte kaldırılacak
22
- def eski_fonksiyon():
23
- """
24
- Kaldırılması planlanan eski bir fonksiyondur.
25
- Lütfen alternatif fonksiyonları kullanın.
26
- """
27
- warnings.warn(
28
- "eski_fonksiyon() artık kullanılmamaktadır ve gelecekte kaldırılacaktır. "
29
- "Lütfen yeni alternatif fonksiyonları kullanın. "
30
- "Keçeci Layout; Python 3.7-3.14 sürümlerinde sorunsuz çalışmalıdır.",
31
- category=DeprecationWarning,
32
- stacklevel=2
33
- )
34
-
35
-
36
- # Paket sürüm numarası
37
- __version__ = "0.2.2"
File without changes
File without changes
File without changes