d3blocks 2.0.0__tar.gz → 2.2.0__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.
Files changed (154) hide show
  1. {d3blocks-2.0.0 → d3blocks-2.2.0}/MANIFEST.in +1 -0
  2. {d3blocks-2.0.0/d3blocks.egg-info → d3blocks-2.2.0}/PKG-INFO +6 -3
  3. {d3blocks-2.0.0 → d3blocks-2.2.0}/README.md +4 -1
  4. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/__init__.py +1 -1
  5. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/chord/Chord.py +19 -6
  6. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/chord/d3js/chord.css +4 -0
  7. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/chord/d3js/chord.html.j2 +29 -6
  8. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/circlepacking/Circlepacking.py +16 -8
  9. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/circlepacking/d3js/circlepacking.css +21 -4
  10. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/circlepacking/d3js/circlepacking.html.j2 +32 -4
  11. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/d3blocks.py +500 -116
  12. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/elasticgraph/d3js/elasticgraph.css +4 -0
  13. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/elasticgraph/d3js/elasticgraph.html.j2 +40 -12
  14. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/elasticgraph/elasticgraph.py +52 -14
  15. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/examples.py +168 -18
  16. d3blocks-2.2.0/d3blocks/flowgraph/Flowgraph.py +890 -0
  17. d3blocks-2.2.0/d3blocks/flowgraph/__init__.py +9 -0
  18. d3blocks-2.2.0/d3blocks/flowgraph/d3js/d3.flowgraph.js +1407 -0
  19. d3blocks-2.2.0/d3blocks/flowgraph/d3js/d3.v7.min.js +2 -0
  20. d3blocks-2.2.0/d3blocks/flowgraph/d3js/dagre.LICENSE +19 -0
  21. d3blocks-2.2.0/d3blocks/flowgraph/d3js/dagre.min.js +815 -0
  22. d3blocks-2.2.0/d3blocks/flowgraph/d3js/elk.LICENSE.md +264 -0
  23. d3blocks-2.2.0/d3blocks/flowgraph/d3js/elk.bundled.js +6545 -0
  24. d3blocks-2.2.0/d3blocks/flowgraph/d3js/flowgraph.css +372 -0
  25. d3blocks-2.2.0/d3blocks/flowgraph/d3js/flowgraph.html.j2 +130 -0
  26. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/heatmap/Heatmap.py +25 -13
  27. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/heatmap/d3js/heatmap.css +7 -2
  28. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/heatmap/d3js/heatmap.html.j2 +790 -774
  29. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/imageslider/Imageslider.py +7 -4
  30. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/imageslider/d3js/imageslider.css +5 -1
  31. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/imageslider/d3js/imageslider.html.j2 +6 -4
  32. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/maps/Maps.py +16 -5
  33. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/maps/d3js/maps.css +7 -3
  34. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/maps/d3js/maps.html.j2 +21 -6
  35. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/movingbubbles/Movingbubbles.py +18 -8
  36. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/movingbubbles/d3js/movingbubbles.css +19 -2
  37. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/movingbubbles/d3js/movingbubbles.html.j2 +33 -5
  38. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/radialgraph/Radialgraph.py +30 -12
  39. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/radialgraph/d3js/d3.radialgraph.js +128 -85
  40. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/radialgraph/d3js/radialgraph.css +18 -2
  41. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/radialgraph/d3js/radialgraph.html.j2 +38 -22
  42. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/sankey/Sankey.py +15 -3
  43. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/sankey/d3js/sankey.css +24 -4
  44. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/sankey/d3js/sankey.html.j2 +45 -12
  45. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/scatter/Scatter.py +33 -10
  46. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/scatter/d3js/scatter.css +37 -3
  47. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/scatter/d3js/scatter.html.j2 +33 -7
  48. d3blocks-2.2.0/d3blocks/skills_install.py +263 -0
  49. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tests/test_all_examples.py +1 -1
  50. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tests/test_d3blocks.py +0 -14
  51. d3blocks-2.2.0/d3blocks/tests/test_flowgraph.py +331 -0
  52. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/timeseries/Timeseries.py +31 -11
  53. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/timeseries/d3js/timeseries.css +39 -10
  54. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/timeseries/d3js/timeseries.html.j2 +92 -67
  55. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/timeseries/d3js/timeseries.js +9 -4
  56. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tree/Tree.py +17 -5
  57. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tree/d3js/tree.css +19 -2
  58. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tree/d3js/tree.html.j2 +28 -6
  59. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/treemap/Treemap.py +17 -5
  60. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/treemap/d3js/treemap.css +5 -0
  61. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/treemap/d3js/treemap.html.j2 +28 -7
  62. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/utils.py +51 -22
  63. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/violin/Violin.py +15 -6
  64. d3blocks-2.2.0/d3blocks/violin/d3js/__init__.py +0 -0
  65. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/violin/d3js/violin.css +4 -0
  66. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/violin/d3js/violin.html.j2 +29 -5
  67. {d3blocks-2.0.0 → d3blocks-2.2.0/d3blocks.egg-info}/PKG-INFO +6 -3
  68. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks.egg-info/SOURCES.txt +13 -1
  69. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks.egg-info/requires.txt +1 -1
  70. {d3blocks-2.0.0 → d3blocks-2.2.0}/pyproject.toml +1 -1
  71. d3blocks-2.0.0/d3blocks/skills.py +0 -129
  72. {d3blocks-2.0.0 → d3blocks-2.2.0}/LICENSE +0 -0
  73. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/chord/__init__.py +0 -0
  74. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/chord/d3js/__init__.py +0 -0
  75. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/chord/d3js/chord.js +0 -0
  76. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/circlepacking/__init__.py +0 -0
  77. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/circlepacking/d3js/__init__.py +0 -0
  78. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/circlepacking/d3js/d3.v6.min.js +0 -0
  79. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/circlepacking/d3js/lodash.min.js +0 -0
  80. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/elasticgraph/__init__.py +0 -0
  81. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/elasticgraph/d3js/.gitkeep +0 -0
  82. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/elasticgraph/d3js/__init__.py +0 -0
  83. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/elasticgraph/d3js/d3.v2.js +0 -0
  84. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/elasticgraph/d3js/elasticgraph.js +0 -0
  85. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/examples_docs.py +0 -0
  86. {d3blocks-2.0.0/d3blocks/heatmap → d3blocks-2.2.0/d3blocks/flowgraph/d3js}/__init__.py +0 -0
  87. {d3blocks-2.0.0/d3blocks/heatmap/d3js → d3blocks-2.2.0/d3blocks/heatmap}/__init__.py +0 -0
  88. {d3blocks-2.0.0/d3blocks/imageslider → d3blocks-2.2.0/d3blocks/heatmap/d3js}/__init__.py +0 -0
  89. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/heatmap/d3js/d3.scale.chromatic.v1.min.js +0 -0
  90. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/heatmap/d3js/d3.v4.js +0 -0
  91. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/heatmap/d3js/matrix.html.j2 +0 -0
  92. {d3blocks-2.0.0/d3blocks/imageslider/d3js → d3blocks-2.2.0/d3blocks/imageslider}/__init__.py +0 -0
  93. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/imageslider/d3js/.keep +0 -0
  94. {d3blocks-2.0.0/d3blocks/maps → d3blocks-2.2.0/d3blocks/imageslider/d3js}/__init__.py +0 -0
  95. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/imageslider/d3js/imageslider.js +0 -0
  96. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/imageslider/d3js/jquery-2.1.1.js +0 -0
  97. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/imageslider/d3js/modernizr.js +0 -0
  98. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/imageslider/d3js/reset.css +0 -0
  99. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/logo.txt +0 -0
  100. {d3blocks-2.0.0/d3blocks/maps/d3js → d3blocks-2.2.0/d3blocks/maps}/__init__.py +0 -0
  101. {d3blocks-2.0.0/d3blocks/matrix → d3blocks-2.2.0/d3blocks/maps/d3js}/__init__.py +0 -0
  102. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/maps/d3js/d3.v6.min.js +0 -0
  103. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/maps/d3js/geojson.zip +0 -0
  104. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/maps/d3js/world.geojson +0 -0
  105. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/matrix/Matrix.py +0 -0
  106. {d3blocks-2.0.0/d3blocks/matrix/d3js → d3blocks-2.2.0/d3blocks/matrix}/__init__.py +0 -0
  107. {d3blocks-2.0.0/d3blocks/movingbubbles → d3blocks-2.2.0/d3blocks/matrix/d3js}/__init__.py +0 -0
  108. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/matrix/d3js/d3.scale.chromatic.v1.min.js +0 -0
  109. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/matrix/d3js/d3.v4.js +0 -0
  110. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/matrix/d3js/matrix.html.j2 +0 -0
  111. {d3blocks-2.0.0/d3blocks/movingbubbles/d3js → d3blocks-2.2.0/d3blocks/movingbubbles}/__init__.py +0 -0
  112. {d3blocks-2.0.0/d3blocks/particles → d3blocks-2.2.0/d3blocks/movingbubbles/d3js}/__init__.py +0 -0
  113. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/movingbubbles/d3js/d3-3-5-5.min.js +0 -0
  114. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/particles/Particles.py +0 -0
  115. {d3blocks-2.0.0/d3blocks/particles/d3js → d3blocks-2.2.0/d3blocks/particles}/__init__.py +0 -0
  116. {d3blocks-2.0.0/d3blocks/sankey → d3blocks-2.2.0/d3blocks/particles/d3js}/__init__.py +0 -0
  117. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/particles/d3js/d3-scale-chromatic.v1.min.js +0 -0
  118. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/particles/d3js/d3.v4.min.js +0 -0
  119. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/particles/d3js/particles.html.j2 +0 -0
  120. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/radialgraph/__init__.py +0 -0
  121. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/radialgraph/d3js/__init__ .py +0 -0
  122. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/radialgraph/d3js/d3.v7.min.js +0 -0
  123. {d3blocks-2.0.0/d3blocks/sankey/d3js → d3blocks-2.2.0/d3blocks/sankey}/__init__.py +0 -0
  124. {d3blocks-2.0.0/d3blocks/scatter → d3blocks-2.2.0/d3blocks/sankey/d3js}/__init__.py +0 -0
  125. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/sankey/d3js/sankey.js +0 -0
  126. {d3blocks-2.0.0/d3blocks/scatter/d3js → d3blocks-2.2.0/d3blocks/scatter}/__init__.py +0 -0
  127. {d3blocks-2.0.0/d3blocks/tests → d3blocks-2.2.0/d3blocks/scatter/d3js}/__init__.py +0 -0
  128. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/scatter/d3js/associations.js +0 -0
  129. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/scatter/d3js/d3.v4.min.js +0 -0
  130. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/skills/d3blocks/SKILL.md +0 -0
  131. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/skills/d3blocks/references/scatter.md +0 -0
  132. {d3blocks-2.0.0/d3blocks/timeseries → d3blocks-2.2.0/d3blocks/tests}/__init__.py +0 -0
  133. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tests/test_chord_margins.py +0 -0
  134. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tests/test_medium_charts.py +0 -0
  135. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tests/test_movingbubbles_timedelta.py +0 -0
  136. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tests/test_radialgraph.py +0 -0
  137. {d3blocks-2.0.0/d3blocks/timeseries/d3js → d3blocks-2.2.0/d3blocks/timeseries}/__init__.py +0 -0
  138. {d3blocks-2.0.0/d3blocks/tree → d3blocks-2.2.0/d3blocks/timeseries/d3js}/__init__.py +0 -0
  139. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/timeseries/d3js/d3.v3.js +0 -0
  140. {d3blocks-2.0.0/d3blocks/tree/d3js → d3blocks-2.2.0/d3blocks/tree}/__init__.py +0 -0
  141. {d3blocks-2.0.0/d3blocks/treemap → d3blocks-2.2.0/d3blocks/tree/d3js}/__init__.py +0 -0
  142. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tree/d3js/collapsibleTree.js +0 -0
  143. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tree/d3js/d3.tree.js +0 -0
  144. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/tree/d3js/d3.v4.min.js +0 -0
  145. {d3blocks-2.0.0/d3blocks/treemap/d3js → d3blocks-2.2.0/d3blocks/treemap}/__init__.py +0 -0
  146. {d3blocks-2.0.0/d3blocks/violin → d3blocks-2.2.0/d3blocks/treemap/d3js}/__init__.py +0 -0
  147. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/treemap/d3js/d3.v4.min.js +0 -0
  148. {d3blocks-2.0.0/d3blocks/violin/d3js → d3blocks-2.2.0/d3blocks/violin}/__init__.py +0 -0
  149. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/violin/d3js/d3-scale-chromatic.v1.min.js +0 -0
  150. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks/violin/d3js/d3.v4.min.js +0 -0
  151. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks.egg-info/dependency_links.txt +0 -0
  152. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks.egg-info/entry_points.txt +0 -0
  153. {d3blocks-2.0.0 → d3blocks-2.2.0}/d3blocks.egg-info/top_level.txt +0 -0
  154. {d3blocks-2.0.0 → d3blocks-2.2.0}/setup.cfg +0 -0
@@ -14,5 +14,6 @@ include d3blocks/circlepacking/d3js/*
14
14
  include d3blocks/maps/d3js/*
15
15
  include d3blocks/elasticgraph/d3js/*
16
16
  include d3blocks/radialgraph/d3js/*
17
+ include d3blocks/flowgraph/d3js/*
17
18
  include d3blocks/*
18
19
  recursive-include d3blocks/skills *
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: d3blocks
3
- Version: 2.0.0
3
+ Version: 2.2.0
4
4
  Summary: Python package d3blocks.
5
5
  Author-email: Erdogan Taskesen <erdogant@gmail.com>
6
6
  License-Expression: GPL-3.0-or-later
@@ -20,7 +20,7 @@ License-File: LICENSE
20
20
  Requires-Dist: numpy
21
21
  Requires-Dist: colourmap>=1.1.10
22
22
  Requires-Dist: datazets>=0.1.7
23
- Requires-Dist: d3graph>=3.0.0
23
+ Requires-Dist: d3graph>=3.2.0
24
24
  Requires-Dist: ismember>=1.0.1
25
25
  Requires-Dist: pandas
26
26
  Requires-Dist: tqdm
@@ -42,7 +42,7 @@ Dynamic: license-file
42
42
  [![Medium](https://img.shields.io/badge/Medium-Blog-black)](https://d3blocks.github.io/d3blocks/pages/html/Documentation.html#medium-blog)
43
43
  ![GitHub Repo stars](https://img.shields.io/github/stars/d3blocks/d3blocks)
44
44
  ![GitHub repo size](https://img.shields.io/github/repo-size/d3blocks/d3blocks)
45
- [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://d3blocks.github.io/d3blocks/pages/html/Documentation.html#colab-notebook)
45
+ [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://github.com/d3blocks/d3blocks/blob/main/notebooks/d3blocks.ipynb)
46
46
  [![Donate](https://img.shields.io/badge/Support%20this%20project-grey.svg?logo=github%20sponsors)](https://d3blocks.github.io/d3blocks/pages/html/Documentation.html#)
47
47
 
48
48
  ###
@@ -117,6 +117,7 @@ The [documentation pages](https://d3blocks.github.io/d3blocks/) contains detaile
117
117
  | 14 | [Tree](https://d3blocks.github.io/d3blocks/pages/html/Tree.html) | ``` d3.tree() ``` | [D3Blocks](https://erdogant.medium.com) |
118
118
  | 15 | [Maps](https://d3blocks.github.io/d3blocks/pages/html/Maps.html) | ``` d3.maps() ``` | [D3Blocks](https://erdogant.medium.com) |
119
119
  | 16 | [Circlepacking](https://d3blocks.github.io/d3blocks/pages/html/Circlepacking.html) | ``` d3.circlepacking() ``` | [D3Blocks](https://erdogant.medium.com) |
120
+ | 17 | [Flowgraph](https://d3blocks.github.io/d3blocks/pages/html/Flowgraph.html) | ``` d3.flowgraph() ``` | [D3Blocks](https://erdogant.medium.com) |
120
121
 
121
122
  -------------------------------------------------------------------------
122
123
 
@@ -147,6 +148,8 @@ d3 = D3Blocks()
147
148
  When HTMLs are generated, it automatically include ethical ads as a small way to support development.
148
149
  This entire project with maintenance is done thoughtfully and only in my free time. Ads can be disabled via an input parameter, and you can also support the project with a coffee donation instead.
149
150
 
151
+ ### Star history
152
+ [![Star History Chart](https://star-history.dera.page/svg?repos=d3blocks/d3blocks)](https://star-history.dera.page/d3blocks/d3blocks)
150
153
 
151
154
  ### References
152
155
  * [bl.ocks](https://bl.ocks.org/)
@@ -11,7 +11,7 @@
11
11
  [![Medium](https://img.shields.io/badge/Medium-Blog-black)](https://d3blocks.github.io/d3blocks/pages/html/Documentation.html#medium-blog)
12
12
  ![GitHub Repo stars](https://img.shields.io/github/stars/d3blocks/d3blocks)
13
13
  ![GitHub repo size](https://img.shields.io/github/repo-size/d3blocks/d3blocks)
14
- [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://d3blocks.github.io/d3blocks/pages/html/Documentation.html#colab-notebook)
14
+ [![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://github.com/d3blocks/d3blocks/blob/main/notebooks/d3blocks.ipynb)
15
15
  [![Donate](https://img.shields.io/badge/Support%20this%20project-grey.svg?logo=github%20sponsors)](https://d3blocks.github.io/d3blocks/pages/html/Documentation.html#)
16
16
 
17
17
  ###
@@ -86,6 +86,7 @@ The [documentation pages](https://d3blocks.github.io/d3blocks/) contains detaile
86
86
  | 14 | [Tree](https://d3blocks.github.io/d3blocks/pages/html/Tree.html) | ``` d3.tree() ``` | [D3Blocks](https://erdogant.medium.com) |
87
87
  | 15 | [Maps](https://d3blocks.github.io/d3blocks/pages/html/Maps.html) | ``` d3.maps() ``` | [D3Blocks](https://erdogant.medium.com) |
88
88
  | 16 | [Circlepacking](https://d3blocks.github.io/d3blocks/pages/html/Circlepacking.html) | ``` d3.circlepacking() ``` | [D3Blocks](https://erdogant.medium.com) |
89
+ | 17 | [Flowgraph](https://d3blocks.github.io/d3blocks/pages/html/Flowgraph.html) | ``` d3.flowgraph() ``` | [D3Blocks](https://erdogant.medium.com) |
89
90
 
90
91
  -------------------------------------------------------------------------
91
92
 
@@ -116,6 +117,8 @@ d3 = D3Blocks()
116
117
  When HTMLs are generated, it automatically include ethical ads as a small way to support development.
117
118
  This entire project with maintenance is done thoughtfully and only in my free time. Ads can be disabled via an input parameter, and you can also support the project with a coffee donation instead.
118
119
 
120
+ ### Star history
121
+ [![Star History Chart](https://star-history.dera.page/svg?repos=d3blocks/d3blocks)](https://star-history.dera.page/d3blocks/d3blocks)
119
122
 
120
123
  ### References
121
124
  * [bl.ocks](https://bl.ocks.org/)
@@ -10,7 +10,7 @@ from d3blocks.utils import (
10
10
 
11
11
  __author__ = 'Erdogan Taskesen'
12
12
  __email__ = 'erdogant@gmail.com'
13
- __version__ = '2.0.0'
13
+ __version__ = '2.2.0'
14
14
 
15
15
  # Setup root logger
16
16
  import logging
@@ -12,9 +12,9 @@ import numpy as np
12
12
  from jinja2 import Environment, PackageLoader
13
13
 
14
14
  try:
15
- from .. utils import set_colors, pre_processing, convert_dataframe_dict, set_path, update_config, set_labels, create_unique_dataframe, write_html_file, include_save_to_svg_script, set_logo
15
+ from .. utils import set_colors, pre_processing, convert_dataframe_dict, set_path, update_config, set_labels, create_unique_dataframe, write_html_file, include_save_to_svg_script, set_logo, resolve_color_background
16
16
  except:
17
- from utils import set_colors, pre_processing, convert_dataframe_dict, set_path, update_config, set_labels, create_unique_dataframe, write_html_file, include_save_to_svg_script, set_logo
17
+ from utils import set_colors, pre_processing, convert_dataframe_dict, set_path, update_config, set_labels, create_unique_dataframe, write_html_file, include_save_to_svg_script, set_logo, resolve_color_background
18
18
 
19
19
  # %% Set configuration properties
20
20
  def set_config(config={}, **kwargs):
@@ -34,8 +34,12 @@ def set_config(config={}, **kwargs):
34
34
  config['save_button'] = kwargs.get('save_button', True)
35
35
  config['margin'] = kwargs.get('margin', 150) # Margin around the chord diagram
36
36
  config['text_offset'] = kwargs.get('text_offset', 5) # Additional offset for text labels
37
- config['show_controls'] = kwargs.get('show_controls', True) # Show the top bar and left control panels
38
- config['dark_mode'] = kwargs.get('dark_mode', True) # Start in dark theme
37
+ # [dark_hex, light_hex] for center / top panel / side panels per theme.
38
+ # None → defaults matching chord.css (--bg dark #222, light #fff).
39
+ config['color_background'] = kwargs.get('color_background', None)
40
+ config['dark_mode'] = kwargs.get('dark_mode', True)
41
+ config['show_side_panel'] = kwargs.get('show_side_panel', True)
42
+ config['show_top_panel'] = kwargs.get('show_top_panel', True)
39
43
  # return
40
44
  return config
41
45
 
@@ -285,8 +289,17 @@ def write_html(X, config, logger=None):
285
289
  else:
286
290
  ORDERING_MODE = 'none'
287
291
 
292
+ # Ensure new GUI keys have defaults (backwards compatible)
293
+ show_side_panel = config.get('show_side_panel', True)
294
+ show_top_panel = config.get('show_top_panel', True)
295
+ dark_mode = config.get('dark_mode', True)
296
+ bg_dark, bg_light = resolve_color_background(config.get('color_background', None))
297
+
288
298
  content = {
289
299
  'json_data': X,
300
+ 'COLOR_BACKGROUND_DARK': bg_dark,
301
+ 'COLOR_BACKGROUND_LIGHT': bg_light,
302
+ 'darkMode': 'true' if dark_mode else 'false',
290
303
  'TITLE': config['title'],
291
304
  'WIDTH': config['figsize'][0],
292
305
  'HEIGHT': config['figsize'][1],
@@ -300,8 +313,8 @@ def write_html(X, config, logger=None):
300
313
  'SAVE_TO_SVG_SCRIPT': save_script,
301
314
  'SAVE_BUTTON_START': show_save_button[0],
302
315
  'SAVE_BUTTON_STOP': show_save_button[1],
303
- 'showControls': 'true' if config.get('show_controls', True) else 'false',
304
- 'darkMode': 'true' if config.get('dark_mode', True) else 'false',
316
+ 'showSidePanel': 'true' if show_side_panel else 'false',
317
+ 'showTopPanel': 'true' if show_top_panel else 'false',
305
318
  'LOGO_BASE64': config['logo_base64'],
306
319
  }
307
320
 
@@ -187,6 +187,10 @@ html, body {
187
187
  transition: var(--transition);
188
188
  pointer-events: none;
189
189
  }
190
+ /* Light mode: no drop shadow so a white/light bar does not sit under a dark shadow. */
191
+ body.light .top-panel {
192
+ box-shadow: none;
193
+ }
190
194
  .top-panel .top-panel-left {
191
195
  pointer-events: none;
192
196
  justify-self: start;
@@ -14,10 +14,33 @@ Forked : Mike Bostock; https://observablehq.com/@d3/directed-chord-diagram
14
14
  <title>{{ TITLE }}</title>
15
15
  {{ SUPPORT }}
16
16
  <style>{% include "chord.css" %}</style>
17
+ <!-- Center + top panel + side panels: per-theme backgrounds.
18
+ Theme toggle (body.light) switches which color is used. -->
19
+ <style>
20
+ body {
21
+ background: {{ COLOR_BACKGROUND_DARK }};
22
+ }
23
+ body .top-panel {
24
+ background: {{ COLOR_BACKGROUND_DARK }};
25
+ }
26
+ body .stats-panel {
27
+ background: {{ COLOR_BACKGROUND_DARK }};
28
+ }
29
+ body.light {
30
+ background: {{ COLOR_BACKGROUND_LIGHT }};
31
+ }
32
+ body.light .top-panel {
33
+ background: {{ COLOR_BACKGROUND_LIGHT }};
34
+ }
35
+ body.light .stats-panel {
36
+ background: {{ COLOR_BACKGROUND_LIGHT }};
37
+ }
38
+ </style>
17
39
  </head>
18
40
  <body{% if darkMode == 'false' %} class="light"{% endif %}>
19
41
 
20
- <!-- Top panel always shown: logo left, ordering mode center, theme right -->
42
+ {% if showTopPanel == 'true' %}
43
+ <!-- Top panel: logo left, ordering mode center, theme right -->
21
44
  <div class="top-panel" role="toolbar" aria-label="Top controls">
22
45
  <div class="top-panel-left">
23
46
  <a href="https://d3blocks.github.io/d3blocks/" title="D3Blocks">
@@ -25,7 +48,7 @@ Forked : Mike Bostock; https://observablehq.com/@d3/directed-chord-diagram
25
48
  </a>
26
49
  </div>
27
50
  <div class="top-panel-center">
28
- {% if showControls == 'true' and ORDERING_MODE != 'custom' %}
51
+ {% if ORDERING_MODE != 'custom' %}
29
52
  <div class="mode-row top-mode">
30
53
  <label><input type="radio" name="ordering" value="ascending"{% if ORDERING_MODE == 'ascending' %} checked{% endif %}> Ascending</label>
31
54
  <label><input type="radio" name="ordering" value="descending"{% if ORDERING_MODE == 'descending' %} checked{% endif %}> Descending</label>
@@ -37,8 +60,9 @@ Forked : Mike Bostock; https://observablehq.com/@d3/directed-chord-diagram
37
60
  <button class="button-switch" id="themeBtn" type="button" title="{% if darkMode == 'false' %}Theme: Light{% else %}Theme: Dark{% endif %}">{% if darkMode == 'false' %}☀{% else %}🌙{% endif %}</button>
38
61
  </div>
39
62
  </div>
63
+ {% endif %}
40
64
 
41
- {% if showControls == 'true' %}
65
+ {% if showSidePanel == 'true' %}
42
66
  <!-- Side panel: Export / Save -->
43
67
  <div class="stats-panel collapsed" id="exportPanel">
44
68
  <div class="stats-panel-title" draggable="true" title="Drag to reorder panels">Export / Save<span class="stats-panel-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg></span></div>
@@ -212,15 +236,14 @@ Forked : Mike Bostock; https://observablehq.com/@d3/directed-chord-diagram
212
236
  }
213
237
 
214
238
  // Top bar clearance + side panels: position, collapse, reorder
215
- // Always clear the top panel — even when show_controls is false (no side panels).
239
+ // When top panel is absent, treat its height as 0 (do not return early).
216
240
  (function() {
217
241
  var PANEL_ORDER = ['exportPanel', 'appearancePanel', 'physicsPanel'];
218
242
 
219
243
  function positionSidePanels() {
220
244
  var bar = document.querySelector('.top-panel');
221
245
  var main = document.getElementById('chord-main');
222
- if (!bar) return;
223
- var bottom = bar.getBoundingClientRect().bottom;
246
+ var bottom = bar ? bar.getBoundingClientRect().bottom : 0;
224
247
  if (main) main.style.marginTop = (bottom + 12) + 'px';
225
248
  var y = bottom + 8;
226
249
  var bottomPad = 12;
@@ -9,9 +9,9 @@ License : GPL3
9
9
  from jinja2 import Environment, PackageLoader
10
10
 
11
11
  try:
12
- from .. utils import convert_dataframe_dict, set_path, pre_processing, update_config, set_labels, write_html_file, is_circular, include_save_to_svg_script, set_logo
12
+ from .. utils import convert_dataframe_dict, set_path, pre_processing, update_config, set_labels, write_html_file, is_circular, include_save_to_svg_script, set_logo, resolve_color_background
13
13
  except:
14
- from utils import convert_dataframe_dict, set_path, pre_processing, update_config, set_labels, write_html_file, is_circular, include_save_to_svg_script, set_logo
14
+ from utils import convert_dataframe_dict, set_path, pre_processing, update_config, set_labels, write_html_file, is_circular, include_save_to_svg_script, set_logo, resolve_color_background
15
15
 
16
16
 
17
17
  # %% Set configuration properties
@@ -34,8 +34,11 @@ def set_config(config={}, margin={}, font={}, border={}, **kwargs):
34
34
  config['border'] = {**{'color': '#FFFFFF', 'width': 1.5, 'fill': '#FFFFFF', "padding": 5}, **border}
35
35
  config['notebook'] = kwargs.get('notebook', False)
36
36
  config['save_button'] = kwargs.get('save_button', True)
37
- config['show_controls'] = kwargs.get('show_controls', True)
37
+ # UI conventions (aligned with scatter)
38
+ config['show_side_panel'] = kwargs.get('show_side_panel', True)
39
+ config['show_top_panel'] = kwargs.get('show_top_panel', True)
38
40
  config['dark_mode'] = kwargs.get('dark_mode', True)
41
+ config['color_background'] = kwargs.get('color_background', None)
39
42
  # return
40
43
  return config
41
44
 
@@ -184,9 +187,11 @@ def write_html(X, config, node_properties, logger=None):
184
187
  width = 'window.screen.width' if config['figsize'][0] is None else config['figsize'][0]
185
188
  height = 'window.screen.height' if config['figsize'][1] is None else config['figsize'][1]
186
189
 
187
- # Jinja expects lowercase 'true'/'false' JSON-style strings for template conditionals
188
- show_controls = 'true' if config.get('show_controls', True) else 'false'
189
- dark_mode = 'true' if config.get('dark_mode', True) else 'false'
190
+ # UI flags as lowercase 'true'/'false' for Jinja conditionals
191
+ show_side_panel = config.get('show_side_panel', True)
192
+ show_top_panel = config.get('show_top_panel', True)
193
+ dark_mode = config.get('dark_mode', True)
194
+ bg_dark, bg_light = resolve_color_background(config.get('color_background', None))
190
195
 
191
196
  content = {
192
197
  'json_data': X,
@@ -208,8 +213,11 @@ def write_html(X, config, node_properties, logger=None):
208
213
  'SAVE_TO_SVG_SCRIPT': save_script,
209
214
  'SAVE_BUTTON_START': show_save_button[0],
210
215
  'SAVE_BUTTON_STOP': show_save_button[1],
211
- 'showControls': show_controls,
212
- 'darkMode': dark_mode,
216
+ 'showSidePanel': 'true' if show_side_panel else 'false',
217
+ 'showTopPanel': 'true' if show_top_panel else 'false',
218
+ 'darkMode': 'true' if dark_mode else 'false',
219
+ 'COLOR_BACKGROUND_DARK': bg_dark,
220
+ 'COLOR_BACKGROUND_LIGHT': bg_light,
213
221
  'LOGO_BASE64': config['logo_base64'],
214
222
  }
215
223
 
@@ -54,7 +54,7 @@ html, body {
54
54
  overflow: hidden;
55
55
  }
56
56
  /* Leave room for the fixed top panel so the chart is not clipped under it */
57
- body.has-controls #circlepacking-container {
57
+ body.has-top-panel #circlepacking-container {
58
58
  top: 64px;
59
59
  }
60
60
  #circlepacking-container svg {
@@ -80,7 +80,7 @@ body.has-controls #circlepacking-container {
80
80
  transition: color 0.25s;
81
81
  }
82
82
 
83
- /* ==== Side panels (aligned with radialgraph) ==== */
83
+ /* ==== Side panels ==== */
84
84
  .stats-panel {
85
85
  position: fixed;
86
86
  display: flex;
@@ -220,6 +220,10 @@ body.has-controls #circlepacking-container {
220
220
  transition: var(--transition);
221
221
  pointer-events: none;
222
222
  }
223
+ /* Light mode: remove drop shadow so a light bar does not sit under a dark shadow */
224
+ body.light .top-panel {
225
+ box-shadow: none;
226
+ }
223
227
  .top-panel .top-panel-left {
224
228
  pointer-events: auto;
225
229
  display: flex;
@@ -260,8 +264,21 @@ body.has-controls #circlepacking-container {
260
264
  }
261
265
  .search-input::placeholder { color: var(--text-muted); }
262
266
  .search-input:focus { border-color: #5b9bd5; }
263
- .top-search { width: 360px; max-width: 50vw; }
264
- .top-search .search-input { width: 100%; }
267
+ /* Top-bar search: match button-switch padding/font-size; zero bottom margin */
268
+ .top-search {
269
+ width: 360px;
270
+ max-width: 50vw;
271
+ margin-bottom: 0;
272
+ display: flex;
273
+ align-items: center;
274
+ }
275
+ .top-search .search-input {
276
+ width: 100%;
277
+ padding: 6px 12px;
278
+ font-size: 1em;
279
+ line-height: normal;
280
+ box-sizing: border-box;
281
+ }
265
282
  .search-results {
266
283
  position: absolute;
267
284
  left: 0;
@@ -13,13 +13,35 @@ Forked : Mike Bostock; http://bl.ocks.org/mbostock/4063582
13
13
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
14
  <title>{{ TITLE }}</title>
15
15
  <style>{% include "circlepacking.css" %}</style>
16
+ <!-- Center + top panel + side panels: per-theme backgrounds.
17
+ Theme toggle (body.light) switches which color is used. -->
18
+ <style>
19
+ body {
20
+ background: {{ COLOR_BACKGROUND_DARK }};
21
+ }
22
+ body .top-panel {
23
+ background: {{ COLOR_BACKGROUND_DARK }};
24
+ }
25
+ body .stats-panel {
26
+ background: {{ COLOR_BACKGROUND_DARK }};
27
+ }
28
+ body.light {
29
+ background: {{ COLOR_BACKGROUND_LIGHT }};
30
+ }
31
+ body.light .top-panel {
32
+ background: {{ COLOR_BACKGROUND_LIGHT }};
33
+ }
34
+ body.light .stats-panel {
35
+ background: {{ COLOR_BACKGROUND_LIGHT }};
36
+ }
37
+ </style>
16
38
  <script>{% include "d3.v6.min.js" %}</script>
17
39
  <script>{% include "lodash.min.js" %}</script>
18
40
  {{ SUPPORT }}
19
41
  </head>
20
- <body class="{% if darkMode == 'false' %}light {% endif %}{% if showControls == 'true' %}has-controls{% endif %}">
42
+ <body class="{% if darkMode == 'false' %}light {% endif %}{% if showTopPanel == 'true' %}has-top-panel{% endif %}">
21
43
 
22
- {% if showControls == 'true' %}
44
+ {% if showTopPanel == 'true' %}
23
45
  <div class="top-panel" role="toolbar" aria-label="Top controls">
24
46
  <div class="top-panel-left">
25
47
  <a href="https://d3blocks.github.io/d3blocks/" title="D3Blocks" target="_blank" rel="noopener noreferrer">
@@ -37,9 +59,11 @@ Forked : Mike Bostock; http://bl.ocks.org/mbostock/4063582
37
59
  <button class="button-switch" id="themeBtn" type="button" title="{% if darkMode == 'false' %}Theme: Light{% else %}Theme: Dark{% endif %}">{% if darkMode == 'false' %}☀{% else %}🌙{% endif %}</button>
38
60
  </div>
39
61
  </div>
62
+ {% endif %}
40
63
 
64
+ {% if showSidePanel == 'true' %}
41
65
  <div class="stats-panel collapsed" id="exportPanel">
42
- <div class="stats-panel-title" draggable="true" title="Drag to reorder panels">Export<span class="stats-panel-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"></polyline></svg></span></div>
66
+ <div class="stats-panel-title" draggable="true" title="Drag to reorder panels">Export / Save<span class="stats-panel-toggle" aria-hidden="true"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="6 9 12 15 18 9"></polyline></svg></span></div>
43
67
  <div class="stats-panel-body">
44
68
  <button id="exportDataButton" class="button-switch">Export Data</button>
45
69
  {{ SAVE_BUTTON_START }}<button id="saveButton" class="button-switch">Save</button>{{ SAVE_BUTTON_STOP }}
@@ -96,7 +120,8 @@ Forked : Mike Bostock; http://bl.ocks.org/mbostock/4063582
96
120
  fonttype: "{{ fonttype }}",
97
121
  fontoutlinecolor: "{{ fontoutlinecolor }}",
98
122
  darkMode: {{ darkMode }},
99
- showControls: {{ showControls }}
123
+ showSidePanel: {{ showSidePanel }},
124
+ showTopPanel: {{ showTopPanel }}
100
125
  };
101
126
  </script>
102
127
  <script>
@@ -333,6 +358,7 @@ Forked : Mike Bostock; http://bl.ocks.org/mbostock/4063582
333
358
  rebuildChart();
334
359
 
335
360
  // —— Reset view ————————————————————————————————————————————————
361
+ // No-op when top panel / resetBtn is absent
336
362
  const resetBtn = document.getElementById("resetBtn");
337
363
  if (resetBtn) {
338
364
  resetBtn.addEventListener("click", function () {
@@ -341,6 +367,7 @@ Forked : Mike Bostock; http://bl.ocks.org/mbostock/4063582
341
367
  }
342
368
 
343
369
  // —— Theme toggle ——————————————————————————————————————————————
370
+ // No-op when top panel / themeBtn is absent
344
371
  const themeBtn = document.getElementById("themeBtn");
345
372
  if (themeBtn) {
346
373
  themeBtn.addEventListener("click", function () {
@@ -516,6 +543,7 @@ Forked : Mike Bostock; http://bl.ocks.org/mbostock/4063582
516
543
  }
517
544
 
518
545
  // —— Side panel positioning & collapse / reorder ————————————————
546
+ // When top bar is absent, treat its height as 0 (do not early-return)
519
547
  function positionSidePanels() {
520
548
  var panels = Array.from(document.querySelectorAll(".stats-panel"));
521
549
  var topPanel = document.querySelector(".top-panel");