jenkins-bot has submitted this change and it was merged.

Change subject: Updated nuclides charts to display using SVG; includes some 
refactoring into common components
......................................................................


Updated nuclides charts to display using SVG; includes some refactoring into 
common components

Change-Id: I35f83888f486ed66c1b6ca264966992755147fc6
---
M app.py
M nuclides.py
M static/nuclides.css
A static/nuclides.js
M templates/nuclide_decays.html
M templates/nuclides.html
A templates/nuclides_common.html
7 files changed, 283 insertions(+), 164 deletions(-)

Approvals:
  ArthurPSmith: Looks good to me, but someone else must approve
  Ricordisamoa: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/app.py b/app.py
index 6b9d1eb..dddd4cc 100644
--- a/app.py
+++ b/app.py
@@ -69,20 +69,28 @@
 
 @app.route('/nuclides')
 def nuclides():
-    """Render the chart of the nuclides."""
+    """Render the chart of the nuclides by half-life."""
     nuclides, table, incomplete = app.nuclide_provider.get_table()
     app.nuclide_provider.decorate_by_halflife(nuclides)
-    return render_template('nuclides.html', table=table,
-                           incomplete=incomplete, **fake_globals)
+    return render_nuclides(nuclides, 'nuclides.html', incomplete)
 
 
 @app.route('/nuclide_decays')
 def nuclide_decays():
-    """Render the chart of the nuclides."""
+    """Render the chart of the nuclides by decay mode."""
     nuclides, table, incomplete = app.nuclide_provider.get_table()
     app.nuclide_provider.decorate_by_decay_mode(nuclides)
-    return render_template('nuclide_decays.html', table=table,
-                           incomplete=incomplete, **fake_globals)
+    return render_nuclides(nuclides, 'nuclide_decays.html', incomplete)
+
+
+def render_nuclides(nuclides, template_file, incomplete):
+    magic_numbers = app.nuclide_provider.get_magic_numbers()
+    max_neutrons = max(map(lambda nuclide: nuclide.neutron_number, nuclides))
+    max_protons = max(map(lambda nuclide: nuclide.atomic_number, nuclides))
+    return render_template(template_file, nuclide_list=nuclides,
+                           magic_numbers=magic_numbers, 
max_neutrons=max_neutrons,
+                           max_protons=max_protons, incomplete=incomplete,
+                           **fake_globals)
 
 
 @app.route('/license')
diff --git a/nuclides.py b/nuclides.py
index 7ec44f7..d094b0c 100644
--- a/nuclides.py
+++ b/nuclides.py
@@ -97,11 +97,11 @@
             '179856': 'alpha-decay',
             '898923': 'neutron-emission',
             '902157': 'proton-emission',
-            '9253686': '2-proton-emission',
-            '21457313': '3-proton-emission',
-            '21456752': '2-neutron-emission',
-            '21457084': '3-neutron-emission',
-            '21457201': '4-neutron emission',
+            '9253686': 'two-proton-emission',
+            '21457313': 'three-proton-emission',
+            '21456752': 'two-neutron-emission',
+            '21457084': 'three-neutron-emission',
+            '21457201': 'four-neutron emission',
             '21457421': 'double-alpha-decay',
             '146682': 'spontaneous-fission'
         }
@@ -205,6 +205,21 @@
         for item_id, nuclide in nuclides.items():
             yield nuclide
 
+    def get_magic_numbers(self):
+        magic_query = "PREFIX wdt: <http://www.wikidata.org/prop/direct/> \
+PREFIX wd: <http://www.wikidata.org/entity/> \
+SELECT ?magic_number WHERE {{ \
+    ?number wdt:P{0} wd:Q{1} ; \
+            wdt:P{2} ?magic_number . \
+}} ORDER by ?magic_number".format(Nuclide.instance_pid, Nuclide.magic_qid,
+                                  Nuclide.numeric_pid)
+        query_result = self.get_sparql(magic_query)
+        magic_numbers = []
+        for magic_result in query_result:
+            magic_number = magic_result['magic_number']['value']
+            magic_numbers.append(int(magic_number))
+        return magic_numbers
+
 
 class WdqNuclideProvider(WdqBase, NuclideProvider):
     """Load nuclides from Wikidata Query."""
@@ -306,6 +321,8 @@
     isotope_qid = 25276  # top-level class under which all isotopes to be found
     stable_qid = 878130  # id for stable isotope
     isomer_qid = 846110  # metastable isomers all instances of this
+    magic_qid = 11606  # magic number of nucleons for stability
+    numeric_pid = 1181
 
     def __init__(self, **kwargs):
         self.decay_modes = []
diff --git a/static/nuclides.css b/static/nuclides.css
index ccd36f2..13a30b3 100644
--- a/static/nuclides.css
+++ b/static/nuclides.css
@@ -16,7 +16,7 @@
  * You should have received a copy of the GNU General Public License
  * along with the Wikidata periodic table.  If not, see 
<http://www.gnu.org/licenses/>.
  */
-table#nuclides{
+table#nuclides {
        border-spacing: 0;
 }
 table#nuclides td {
@@ -34,7 +34,7 @@
        background: none;
 }
 
-td.nuclide{
+td.nuclide {
        background: #e8e8e8;
 }
 
@@ -122,15 +122,15 @@
        background: #00f;
 }
 
-td.nuclide.2-neutron-emission{
+td.nuclide.two-neutron-emission {
        background: #04c;
 }
 
-td.nuclide.3-neutron-emission {
+td.nuclide.three-neutron-emission {
        background: #088;
 }
 
-td.nuclide.4-neutron-emission {
+td.nuclide.four-neutron-emission {
        background: #0c4;
 }
 
@@ -150,11 +150,11 @@
        background: #cf6;
 }
 
-td.nuclide.2-proton-emission {
+td.nuclide.two-proton-emission {
        background: #ff0;
 }
 
-td.nuclide.3-proton-emission {
+td.nuclide.three-proton-emission {
        background: #f93;
 }
 
@@ -169,3 +169,150 @@
 td.nuclide.spontaneous-fission {
        background: #f00;
 }
+
+rect.nuclide {
+       fill: #e8e8e8;
+       cursor: pointer;
+}
+
+rect.nuclide.stable {
+       fill: #000;
+}
+
+rect.nuclide.hl1e9 {
+       fill: #008;
+}
+
+rect.nuclide.hl1e6 {
+       fill: #00c;
+}
+
+rect.nuclide.hl1e3 {
+       fill: #00f;
+}
+
+rect.nuclide.hl1e2 {
+       fill: #04c;
+}
+
+rect.nuclide.hl1e1 {
+       fill: #088;
+}
+
+rect.nuclide.hl1e0 {
+       fill: #0c4;
+}
+
+rect.nuclide.hl1e-1 {
+       fill: #0f0;
+}
+
+rect.nuclide.hl1e-2 {
+       fill: #4c4;
+}
+
+rect.nuclide.hl1e-3 {
+       fill: #8f8;
+}
+
+rect.nuclide.hl1e-6 {
+       fill: #cf6;
+}
+
+rect.nuclide.hl1e-9 {
+       fill: #ff0;
+}
+
+rect.nuclide.hl1e-12 {
+       fill: #f93;
+}
+
+rect.nuclide.hl1e-15 {
+       fill: #c60;
+}
+
+rect.nuclide.hl1e-18 {
+       fill: #f60;
+}
+
+rect.nuclide.hl1e-21 {
+       fill: #f00;
+}
+
+table#nuclides rect.x_axis {
+       font-size: 5px;
+       transform: rotate(90.0deg);
+}
+table#nuclides rect.y_axis {
+       font-size: 5px;
+}
+
+rect.nuclide.beta-minus {
+       fill: #0ac;
+}
+
+rect.nuclide.double-beta {
+       fill: #00c;
+}
+
+rect.nuclide.neutron-emission {
+       fill: #00f;
+}
+
+rect.nuclide.two-neutron-emission {
+       fill: #04c;
+}
+
+rect.nuclide.three-neutron-emission {
+       fill: #088;
+}
+
+rect.nuclide.four-neutron-emission {
+       fill: #0c4;
+}
+
+rect.nuclide.positron-emission {
+       fill: #0f0;
+}
+
+rect.nuclide.electron-capture {
+       fill: #4c4;
+}
+
+rect.nuclide.double-electron-capture {
+       fill: #8f8;
+}
+
+rect.nuclide.proton-emission {
+       fill: #cf6;
+}
+
+rect.nuclide.two-proton-emission {
+       fill: #ff0;
+}
+
+rect.nuclide.three-proton-emission {
+       fill: #f93;
+}
+
+rect.nuclide.alpha-decay {
+       fill: #c60;
+}
+
+rect.nuclide.double-alpha-decay {
+       fill: #f60;
+}
+
+rect.nuclide.spontaneous-fission {
+       fill: #f00;
+}
+
+svg#nuclides line {
+       stroke: #000000;
+       stroke-width: 0.1;
+       stroke-dasharray: 2 1;
+}
+
+svg#nuclides text {
+       font-size: 4px;
+}
diff --git a/static/nuclides.js b/static/nuclides.js
new file mode 100644
index 0000000..f2bbb3a
--- /dev/null
+++ b/static/nuclides.js
@@ -0,0 +1,8 @@
+window.addEventListener( 'load', function () {
+       $( '#nuclides' ).panzoom( {
+               $zoomIn: $( '#nuclides-zoom-in' ),
+               $zoomOut: $( '#nuclides-zoom-out' ),
+               $zoomRange: $( '#nuclides-zoom-range' ),
+               $reset: $( '#nuclides-reset' )
+       } );
+} );
diff --git a/templates/nuclide_decays.html b/templates/nuclide_decays.html
index a41fc48..62e697c 100644
--- a/templates/nuclide_decays.html
+++ b/templates/nuclide_decays.html
@@ -1,74 +1,6 @@
-{% extends "base.html" %}
-{%- macro wd_url(nuclide) -%}
-       //www.wikidata.org/wiki/{{ nuclide.item_id }}
-{%- endmacro -%}
-{%- macro format_cell(cell) -%}
-       {%- if isinstance(cell, NoneCell) -%}
-               <td class="empty"></td>
-       {%- elif isinstance(cell, NuclideCell) -%}
-               <td title="{{ cell.label }}" class="nuclide {% for class in 
cell.classes %} {{ class }}{% endfor %}"> <a href="{{ wd_url(cell) 
}}">&nbsp;</a> </td>
-       {%- else -%}
-               <td></td>
-       {%- endif -%}
-{%- endmacro -%}
-{% block head -%}
-<link rel="stylesheet" type="text/css" href="{{ url_for('static', 
filename='nuclides.css') }}">
-{% endblock %}
-{% block title %}
-Wikidata chart of the nuclides - Wikimedia Tool Labs
-{% endblock %}
-{% block content %}
-<h1>Wikidata chart of the nuclides</h1>
-<h2> by decay mode (stable nuclides are black)</h2>
-{% if incomplete %}
-       <h2>Incomplete</h2>
-       <table>
-               <thead>
-                       <tr>
-                               <th>nuclide</th>
-                               <th>atomic number</th>
-                               <th>neutron number</th>
-                       </tr>
-               </thead>
-               <tbody>
-               {%- for nuclide in incomplete -%}
-                       <tr>
-                               <td><a href="{{ wd_url(nuclide) }}">{{ 
nuclide.label }} ({{ nuclide.item_id }})</a></td>
-                               <td>{{ nuclide.atomic_number or '?' }}</td>
-                               <td>{{ nuclide.neutron_number or '?' }}</td>
-                       </tr>
-               {%- endfor -%}
-               </tbody>
-       </ul>
-{% endif %}
-<table id="nuclides">
-       <tr><td>Proton number</td></tr>
-       {%- for anum in sorted(table.keys(),reverse=True) -%}
-               <tr>
-                       <td class="y_axis">
-                               {%- if anum % 5 == 0 -%}
-                                       {{ anum }}
-                               {%- endif %}
-                       </td>
-                       {%- for nnum in sorted(table[anum].keys()) -%}
-                               {{ format_cell(table[anum][nnum]) }}
-                       {%- endfor -%}
-               </tr>
-       {%- endfor -%}
-       <tr>
-               <td> </td>
-               {%- for nnum in sorted(table[0].keys()) -%}
-                       <td class="x_axis">
-                               {%- if nnum % 5 == 0 -%}
-                                       {{ nnum }}
-                               {%- endif %}
-                       </td>
-               {%- endfor -%}
-       </tr>
-       <tr><td colspan="100" align="center">Neutron number</td></tr>
-</table>
-
-<hr>
+{% extends "nuclides_common.html" %}
+{% block chart_label %}decay mode{% endblock %}
+{% block legend %}
 <b>Decay types:</b>
 <table>
   <tr><td class="nuclide beta-minus" style="width: 20px; height: 
20px;"></td><td> beta-minus decay</td></tr>
@@ -79,9 +11,9 @@
   <tr><td class="nuclide alpha-decay" style="width: 20px; height: 
20px;"></td><td> alpha decay</td></tr>
   <tr><td class="nuclide spontaneous-fission" style="width: 5px; height: 
5px;"></td><td> spontaneous fission</td></tr>
 </table>
+{% endblock %}
 
-<hr>
-
+{% block links %}
 <a href="{{ url_for('nuclides') }}">Nuclides by half-life</a> /
 <a href="{{ url_for('index') }}">Periodic Table</a>
 {% endblock %}
diff --git a/templates/nuclides.html b/templates/nuclides.html
index 73ba0fb..a67ec9c 100644
--- a/templates/nuclides.html
+++ b/templates/nuclides.html
@@ -1,77 +1,8 @@
-{% extends "base.html" %}
-{%- macro wd_url(nuclide) -%}
-       //www.wikidata.org/wiki/{{ nuclide.item_id }}
-{%- endmacro -%}
-{%- macro format_cell(cell) -%}
-       {%- if isinstance(cell, NoneCell) -%}
-               <td class="empty"></td>
-       {%- elif isinstance(cell, NuclideCell) -%}
-               <td title="{{ cell.label }}" class="nuclide {% for class in 
cell.classes %} {{ class }}{% endfor %}"> <a href="{{ wd_url(cell) 
}}">&nbsp;</a> </td>
-       {%- else -%}
-               <td></td>
-       {%- endif -%}
-{%- endmacro -%}
-{% block head -%}
-<link rel="stylesheet" type="text/css" href="{{ url_for('static', 
filename='nuclides.css') }}">
-{% endblock %}
-{% block title %}
-Wikidata chart of the nuclides - Wikimedia Tool Labs
-{% endblock %}
-{% block content %}
-<h1>Wikidata chart of the nuclides</h1>
-<h2> By half-life (stable nuclides are black)</h2>
-{% if incomplete %}
-       <h2>Incomplete</h2>
-       <table>
-               <thead>
-                       <tr>
-                               <th>nuclide</th>
-                               <th>atomic number</th>
-                               <th>neutron number</th>
-                       </tr>
-               </thead>
-               <tbody>
-               {%- for nuclide in incomplete -%}
-                       <tr>
-                               <td><a href="{{ wd_url(nuclide) }}">{{ 
nuclide.label }} ({{ nuclide.item_id }})</a></td>
-                               <td>{{ nuclide.atomic_number or '?' }}</td>
-                               <td>{{ nuclide.neutron_number or '?' }}</td>
-                       </tr>
-               {%- endfor -%}
-               </tbody>
-       </ul>
-{% endif %}
-<table id="nuclides">
-       <tr><td>Proton number</td></tr>
-       {%- for anum in sorted(table.keys(),reverse=True) -%}
-               <tr>
-                       <td class="y_axis">
-                               {%- if anum % 5 == 0 -%}
-                                       {{ anum }}
-                               {%- endif %}
-                       </td>
-                       {%- for nnum in sorted(table[anum].keys()) -%}
-                               {{ format_cell(table[anum][nnum]) }}
-                       {%- endfor -%}
-               </tr>
-       {%- endfor -%}
-       <tr>
-               <td> </td>
-               {%- for nnum in sorted(table[0].keys()) -%}
-                       <td class="x_axis">
-                               {%- if nnum % 5 == 0 -%}
-                                       {{ nnum }}
-                               {%- endif %}
-                       </td>
-               {%- endfor -%}
-       </tr>
-       <tr><td colspan="100" align="center">Neutron number</td></tr>
-</table>
-
-<hr>
+{% extends "nuclides_common.html" %}
+{% block chart_label %}half life{% endblock %}
+{% block legend %}
 <b>Half-life ranges:</b>
 <table>
-
   <tr><td class="nuclide hl1e9" style="width: 20px; height: 20px;"></td><td> 
&gt; 10<sup>9</sup>s</td></tr>
   <tr><td class="nuclide hl1e6" style="width: 20px; height: 20px;"></td><td> 
10<sup>6</sup> - 10<sup>9</sup>s</td></tr>
   <tr><td class="nuclide hl1e3" style="width: 20px; height: 20px;"></td><td> 
10<sup>3</sup> - 10<sup>6</sup></td></tr>
@@ -88,8 +19,9 @@
   <tr><td class="nuclide hl1e-18" style="width: 20px; height: 20px;"></td><td> 
10<sup>-18</sup> - 10<sup>-15</sup> s</td></tr>
   <tr><td class="nuclide hl1e-21" style="width: 20px; height: 20px;"></td><td> 
&lt; 10<sup>-18</sup> s</td></tr>
 </table>
+{% endblock %}
 
-<hr>
+{% block links %}
 <a href="{{ url_for('nuclide_decays') }}">Nuclides by dominant decay mode</a> /
 <a href="{{ url_for('index') }}">Periodic Table</a>
 {% endblock %}
diff --git a/templates/nuclides_common.html b/templates/nuclides_common.html
new file mode 100644
index 0000000..f1353ab
--- /dev/null
+++ b/templates/nuclides_common.html
@@ -0,0 +1,75 @@
+{% extends "base.html" %}
+{%- macro wd_url(nuclide) -%}
+       //www.wikidata.org/wiki/{{ nuclide.item_id }}
+{%- endmacro -%}
+{%- macro format_cell(nuclide) -%}
+       {%- if isinstance(nuclide, NuclideCell) -%}
+            <a xlink:href="{{ wd_url(nuclide) }}"><rect x="{{ 
nuclide.neutron_number }}" y="-{{ nuclide.atomic_number }}" width="1" 
height="1" class="nuclide {% for class in nuclide.classes %} {{ class }}{% 
endfor %}"><title>{{ nuclide.label }}</title></rect></a>
+       {%- endif -%}
+{%- endmacro -%}
+{% block head -%}
+<link rel="stylesheet" type="text/css" href="{{ url_for('static', 
filename='nuclides.css') }}">
+<script 
src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
+<script 
src="//tools-static.wmflabs.org/cdnjs/ajax/libs/jquery.panzoom/2.0.5/jquery.panzoom.min.js"></script>
+<script src="{{ url_for('static', filename='nuclides.js') }}"></script>
+{% endblock %}
+{% block title %}
+Wikidata chart of the nuclides - Wikimedia Tool Labs
+{% endblock %}
+{% block content %}
+<h1>Wikidata chart of the nuclides</h1>
+<h2>By {% block chart_label %}{% endblock %} (stable nuclides are black)</h2>
+{% if incomplete %}
+       <h2>Incomplete</h2>
+       <table>
+               <thead>
+                       <tr>
+                               <th>nuclide</th>
+                               <th>atomic number</th>
+                               <th>neutron number</th>
+                       </tr>
+               </thead>
+               <tbody>
+               {%- for nuclide in incomplete -%}
+                       <tr>
+                               <td><a href="{{ wd_url(nuclide) }}">{{ 
nuclide.label }} ({{ nuclide.item_id }})</a></td>
+                               <td>{{ nuclide.atomic_number or '?' }}</td>
+                               <td>{{ nuclide.neutron_number or '?' }}</td>
+                       </tr>
+               {%- endfor -%}
+               </tbody>
+       </ul>
+{% endif %}
+
+<section class="buttons">
+  <button id="nuclides-zoom-in">Zoom In</button>
+  <button id="nuclides-zoom-out">Zoom Out</button>
+  <input type="range" id="nuclides-zoom-range" min="0.2" max="2" step="0.05"/>
+  <button id="nuclides-reset">Reset</button>
+</section>
+<table>
+<tr><td>
+    <svg height="600px" width="700px" viewBox="-10 -{{ max_protons + 10 }} {{ 
max_neutrons + 20 }} {{ max_protons + 20 }}" preserveAspectRatio="xMinYMin 
meet" id="nuclides">
+       {%- for magic_number in magic_numbers -%}
+           {%- if magic_number < max_neutrons -%}
+                <line x1="{{ magic_number + 0.5 }}" y1="-{{ max_protons }}" 
x2="{{ magic_number + 0.5 }}" y2="0" />
+                <text transform="translate({{ magic_number }}, -{{ 
2*magic_number**0.8 + 10 }})rotate(-90)">{{ magic_number }} neutrons</text>
+            {%- endif -%}
+           {%- if magic_number < max_protons -%}
+                <line x1="0" y1="-{{ magic_number - 0.5 }}" x2="{{ 
max_neutrons }}" y2="-{{ magic_number - 0.5 }}" />
+                <text x="{{ magic_number *1.5 + 25 }}" y="-{{ magic_number 
}}">{{ magic_number }} protons</text>
+            {%- endif -%}
+        {%- endfor -%}
+       {%- for nuclide in nuclide_list -%}
+               {{ format_cell(nuclide) }}
+       {%- endfor -%}
+   </svg>
+</td><td>
+{% block legend %}{% endblock %}
+</td></tr></table>
+
+<hr>
+
+{% block links %}{% endblock %}
+
+{% endblock %}

-- 
To view, visit https://gerrit.wikimedia.org/r/275521
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I35f83888f486ed66c1b6ca264966992755147fc6
Gerrit-PatchSet: 5
Gerrit-Project: labs/tools/ptable
Gerrit-Branch: master
Gerrit-Owner: ArthurPSmith <[email protected]>
Gerrit-Reviewer: ArthurPSmith <[email protected]>
Gerrit-Reviewer: Ricordisamoa <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to