Skip to content

Commit

Permalink
Merge pull request #21 from Ian-Foote/svg_wheel
Browse files Browse the repository at this point in the history
Generate svg wheel. Embed svg in index.html.
  • Loading branch information
meshy committed Nov 18, 2013
2 parents d0ba059 + eb84f15 commit a6cac72
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 8 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
results.json
wheel.svg
2 changes: 2 additions & 0 deletions generate.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from svg_wheel import generate_svg_wheel
from utils import (
annotate_wheels,
get_top_packages,
Expand All @@ -13,6 +14,7 @@ def main():
packages = remove_irrelevant_packages(get_top_packages(), TO_CHART)
annotate_wheels(packages)
save_to_file(packages, 'results.json')
generate_svg_wheel(packages, TO_CHART)


if __name__ == '__main__':
Expand Down
9 changes: 1 addition & 8 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
<html lang="en">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/0.2.0/Chart.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
Expand All @@ -11,13 +10,7 @@
console.log(response);
$("span.date").html(response['last_update']);

// Create doughnut
var data = response['data'];
var ctx = document.getElementById("wheel").getContext("2d");
new Chart(ctx).Doughnut(data, {
animation: false,
segmentShowStroke: false
});

// Populate table
var tbl_body = "";
Expand Down Expand Up @@ -51,7 +44,7 @@
<div class="row">
<div class="col-sm-6">
<h1>Python Wheels</h1>
<canvas class="center-block" id="wheel" width="360" height="360"></canvas>
<object data="wheel.svg" type="image/svg+xml" width="380" height="380" class="center-block"></object>
<h2>What are wheels?</h2>
<p><a href="https://pypi.python.org/pypi/wheel">Wheels</a> are <a href="http://www.python.org/dev/peps/pep-0427">the new standard</a> of python distribution and are intended to replace eggs. Among other advantages, they offer faster installation and allow secure digital signing. Support is offered in <code>pip &gt;= 1.4</code> and <code>setuptools &gt;= 0.8</code>.</p>
<h2>What is this list?</h2>
Expand Down
115 changes: 115 additions & 0 deletions svg_wheel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import math
import xml.etree.ElementTree as et


HEADERS = '''<?xml version=\"1.0\" standalone=\"no\"?>
<?xml-stylesheet href="wheel.css" type="text/css"?>
<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"
\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">
'''

PATH_TEMPLATE = '''
M {start_outer_x},{start_outer_y}
A{outer_radius},{outer_radius} 0 0 1 {end_outer_x},{end_outer_y}
L {start_inner_x},{start_inner_y}
A{inner_radius},{inner_radius} 0 0 0 {end_inner_x},{end_inner_y}
Z
'''

FRACTION_LINE = 80
OFFSET = 20
PADDING = 10
RADIUS = 180
CENTER = PADDING + RADIUS
TAU = 2*math.pi


def annular_sector_path(center_x, center_y, inner_radius, outer_radius, start, stop):
points = {
'inner_radius': inner_radius,
'outer_radius': outer_radius,
'start_outer_x': center_x + outer_radius*math.cos(start),
'start_outer_y': center_y + outer_radius*math.sin(start),
'end_outer_x': center_x + outer_radius*math.cos(stop),
'end_outer_y': center_y + outer_radius*math.sin(stop),
'start_inner_x': center_x + inner_radius*math.cos(stop),
'start_inner_y': center_y + inner_radius*math.sin(stop),
'end_inner_x': center_x + inner_radius*math.cos(start),
'end_inner_y': center_y + inner_radius*math.sin(start),
}

return PATH_TEMPLATE.format(**points)


def add_annular_sector(wheel, center, inner_radius, outer_radius, start, stop, style_class):
return et.SubElement(wheel, 'path',
d=annular_sector_path(
center_x=center[0], center_y=center[1],
inner_radius=inner_radius, outer_radius=outer_radius,
start=start, stop=stop,
),
attrib={'class': style_class},
)


def angles(index, total):
start = index * TAU / total
stop = (index + 1) * TAU / total

return (start - TAU/4, stop - TAU/4)


def add_fraction(wheel, packages, total):
text_attributes = {
'text-anchor': 'middle',
'dominant-baseline': 'central',
'font-size': str(2*OFFSET),
'font-family': '"Helvetica Neue",Helvetica,Arial,sans-serif',
'fill': '#333333',
}

# Packages with some sort of wheel
wheel_packages = sum(package['wheel'] for package in packages)

packages_with_wheels = et.SubElement(wheel, 'text',
x=str(CENTER), y=str(CENTER - OFFSET),
attrib=text_attributes,
)
packages_with_wheels.text='{}'.format(wheel_packages)

# Dividing line
et.SubElement(wheel, 'line',
x1=str(CENTER - FRACTION_LINE//2), y1=str(CENTER),
x2=str(CENTER + FRACTION_LINE//2), y2=str(CENTER),
attrib={'stroke': '#333333', 'stroke-width': '2'},
)

# Total packages
total_packages = et.SubElement(wheel, 'text',
x=str(CENTER), y=str(CENTER + OFFSET),
attrib=text_attributes,
)
total_packages.text='{}'.format(total)


def generate_svg_wheel(packages, total):
wheel = et.Element('svg', viewBox='0 0 {0} {0}'.format(2*CENTER), version='1.1', xmlns='http://www.w3.org/2000/svg')

for index, result in enumerate(packages):
start, stop = angles(index, total)
sector = add_annular_sector(
wheel,
center=(CENTER, CENTER),
inner_radius=RADIUS//2, outer_radius=RADIUS,
start=start, stop=stop,
style_class=result['css_class'],
)
title = et.SubElement(sector, 'title')
title.text = u'{} {}'.format(result['name'], result['icon'])

add_fraction(wheel, packages, total)

with open('wheel.svg', 'w') as svg:
svg.write(HEADERS)
svg.write(et.tostring(wheel))

17 changes: 17 additions & 0 deletions wheel.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
.success {
stroke: #4CAE4C;
stroke-width: 1;
fill: #5CB85C;
}

.danger {
stroke: #D43F3A;
stroke-width: 1;
fill: #D9534F;
}

.warning {
stroke: #F0AD4E;
stroke-width: 1;
fill: #F0AD4E;
}

0 comments on commit a6cac72

Please sign in to comment.