|
1 | 1 | import os
|
2 | 2 | import bottle
|
| 3 | +import random |
| 4 | +from bokeh.models import (HoverTool, FactorRange, Plot, LinearAxis, Grid, |
| 5 | + Range1d) |
| 6 | +from bokeh.models.glyphs import VBar |
| 7 | +from bokeh.plotting import figure |
| 8 | +from bokeh.charts import Bar |
| 9 | +from bokeh.embed import components |
| 10 | +from bokeh.models.sources import ColumnDataSource |
3 | 11 | from bottle import route, run, template
|
4 | 12 |
|
5 | 13 |
|
|
9 | 17 | <html>
|
10 | 18 | <head>
|
11 | 19 | <title>Bar charts with Bottle and Bokeh</title>
|
| 20 | + <link href="http://cdn.pydata.org/bokeh/release/bokeh-0.12.6.min.css" rel="stylesheet"> |
| 21 | + <link href="http://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.6.min.css" rel="stylesheet"> |
12 | 22 | </head>
|
13 | 23 | <body>
|
14 | 24 | <h1>Bugs found over the past {{ bars_count }} days</h1>
|
| 25 | + {{ !the_div }} |
| 26 | + <script src="http://cdn.pydata.org/bokeh/release/bokeh-0.12.6.min.js"></script> |
| 27 | + <script src="http://cdn.pydata.org/bokeh/release/bokeh-widgets-0.12.6.min.js"></script> |
| 28 | + {{ !the_script }} |
15 | 29 | </body>
|
16 | 30 | </html>
|
17 | 31 | """
|
18 | 32 |
|
19 | 33 |
|
20 | 34 | @route('/<num_bars:int>/')
|
21 | 35 | def chart(num_bars):
|
22 |
| - """Returns a simple template stating the number of bars that should |
23 |
| - be generated when the rest of the function is complete. |
24 |
| - """ |
| 36 | + """Creates a bar chart with the desired number of bars in a chart.""" |
25 | 37 | if num_bars <= 0:
|
26 | 38 | num_bars = 1
|
27 |
| - return template(TEMPLATE_STRING, bars_count=num_bars) |
| 39 | + data = {"days": [], "bugs": [], "costs": []} |
| 40 | + for i in range(1, num_bars + 1): |
| 41 | + data['days'].append(i) |
| 42 | + data['bugs'].append(random.randint(1,100)) |
| 43 | + data['costs'].append(random.uniform(1.00, 1000.00)) |
| 44 | + |
| 45 | + hover = create_hover_tool() |
| 46 | + plot = create_bar_chart(data, "Bugs found per day", "days", |
| 47 | + "bugs", hover) |
| 48 | + script, div = components(plot) |
| 49 | + return template(TEMPLATE_STRING, bars_count=num_bars, |
| 50 | + the_div=div, the_script=script) |
| 51 | + |
| 52 | + |
| 53 | +def create_hover_tool(): |
| 54 | + # we'll code this function in a moment |
| 55 | + return None |
| 56 | + |
| 57 | + |
| 58 | +def create_bar_chart(data, title, x_name, y_name, hover_tool=None, |
| 59 | + width=1200, height=300): |
| 60 | + """Creates a bar chart plot with the exact styling for the centcom |
| 61 | + dashboard. Pass in data as a dictionary, desired plot title, |
| 62 | + name of x axis, y axis and the hover tool HTML. |
| 63 | + """ |
| 64 | + source = ColumnDataSource(data) |
| 65 | + xdr = FactorRange(factors=data[x_name]) |
| 66 | + ydr = Range1d(start=0,end=max(data[y_name])*1.5) |
| 67 | + |
| 68 | + tools = [] |
| 69 | + if hover_tool: |
| 70 | + tools = [hover_tool,] |
| 71 | + |
| 72 | + plot = figure(title=title, x_range=xdr, y_range=ydr, plot_width=width, |
| 73 | + plot_height=height, h_symmetry=False, v_symmetry=False, |
| 74 | + min_border=10, toolbar_location="above", tools=tools, |
| 75 | + responsive=True, outline_line_color="#666666") |
| 76 | + |
| 77 | + glyph = VBar(x=x_name, top=y_name, bottom=0, width=.8, |
| 78 | + fill_color="#6599ed") |
| 79 | + plot.add_glyph(source, glyph) |
| 80 | + |
| 81 | + xaxis = LinearAxis() |
| 82 | + yaxis = LinearAxis() |
| 83 | + |
| 84 | + plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker)) |
| 85 | + plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker)) |
| 86 | + plot.toolbar.logo = None |
| 87 | + plot.min_border_top = 0 |
| 88 | + plot.xgrid.grid_line_color = None |
| 89 | + plot.ygrid.grid_line_color = "#999999" |
| 90 | + plot.yaxis.axis_label = "Bugs found" |
| 91 | + plot.ygrid.grid_line_alpha = 0.1 |
| 92 | + plot.xaxis.axis_label = "Days after app deployment" |
| 93 | + plot.xaxis.major_label_orientation = 1 |
| 94 | + return plot |
28 | 95 |
|
29 | 96 |
|
30 | 97 | if __name__ == '__main__':
|
|
0 commit comments