1
1
#Copyright ReportLab Europe Ltd. 2000-2012
2
2
#see license.txt for license details
3
__version__=''' $Id: graph_charts.py 3959 2012-09-27 14:39:39Z robin $ '''
3
__version__=''' $Id$ '''
4
4
from tools.docco.rl_doc_utils import *
5
5
from reportlab.graphics.shapes import *
20
20
disc("Here are some of the design goals: ")
22
22
disc("<i>Make simple top-level use really simple </i>")
23
disc("""<para lindent=+36>It should be possible to create a simple chart with minimum lines of
23
disc("""<para lindent="+36">It should be possible to create a simple chart with minimum lines of
24
24
code, yet have it 'do the right things' with sensible automatic
25
25
settings. The pie chart snippets above do this. If a real chart has
26
26
many subcomponents, you still should not need to interact with them
27
unless you want to customize what they do.""")
27
unless you want to customize what they do.</para>""")
29
29
disc("<i>Allow precise positioning </i>")
30
disc("""<para lindent=+36>An absolute requirement in publishing and graphic design is to control
30
disc("""<para lindent="+36">An absolute requirement in publishing and graphic design is to control
31
31
the placing and style of every element. We will try to have properties
32
32
that specify things in fixed sizes and proportions of the drawing,
33
33
rather than having automatic resizing. Thus, the 'inner plot
34
34
rectangle' will not magically change when you make the font size of
35
35
the y labels bigger, even if this means your labels can spill out of
36
36
the left edge of the chart rectangle. It is your job to preview the
37
chart and choose sizes and spaces which will work.""")
37
chart and choose sizes and spaces which will work.</para>""")
39
disc("""<para lindent=+36>Some things do need to be automatic. For example, if you want to fit N
39
disc("""<para lindent="+36">Some things do need to be automatic. For example, if you want to fit N
40
40
bars into a 200 point space and don't know N in advance, we specify
41
41
bar separation as a percentage of the width of a bar rather than a
42
42
point size, and let the chart work it out. This is still deterministic
43
and controllable.</para>""")
45
45
disc("<i>Control child elements individually or as a group</i>")
46
disc("""<para lindent=+36>We use smart collection classes that let you customize a group of
46
disc("""<para lindent="+36">We use smart collection classes that let you customize a group of
47
47
things, or just one of them. For example you can do this in our
48
experimental pie chart:""")
48
experimental pie chart:</para>""")
51
51
d = Drawing(400,200)
66
disc("""<para lindent=+36>pc.slices[3] actually lazily creates a little object which holds
66
disc("""<para lindent="+36">pc.slices[3] actually lazily creates a little object which holds
67
67
information about the slice in question; this will be used to format a
68
fourth slice at draw-time if there is one.""")
68
fourth slice at draw-time if there is one.</para>""")
70
70
disc("<i>Only expose things you should change </i>")
71
disc("""<para lindent=+36>It would be wrong from a statistical viewpoint to let you directly
71
disc("""<para lindent="+36">It would be wrong from a statistical viewpoint to let you directly
72
72
adjust the angle of one of the pie wedges in the above example, since
73
73
that is determined by the data. So not everything will be exposed
74
74
through the public properties. There may be 'back doors' to let you
75
75
violate this when you really need to, or methods to provide advanced
76
functionality, but in general properties will be orthogonal.""")
76
functionality, but in general properties will be orthogonal.</para>""")
78
78
disc("<i>Composition and component based </i>")
79
disc("""<para lindent=+36>Charts are built out of reusable child widgets. A Legend is an
79
disc("""<para lindent="+36">Charts are built out of reusable child widgets. A Legend is an
80
80
easy-to-grasp example. If you need a specialized type of legend (e.g.
81
81
circular colour swatches), you should subclass the standard Legend
82
widget. Then you could either do something like...""")
82
widget. Then you could either do something like...</para>""")
85
85
c = MyChartWithLegend()
88
88
c.data = [10,20,30] # and then configure as usual...
91
disc("""<para lindent=+36>...or create/modify your own chart or drawing class which creates one
91
disc("""<para lindent="+36">...or create/modify your own chart or drawing class which creates one
92
92
of these by default. This is also very relevant for time series
93
charts, where there can be many styles of x axis.""")
93
charts, where there can be many styles of x axis.</para>""")
95
disc("""<para lindent=+36>Top level chart classes will create a number of such components, and
95
disc("""<para lindent="+36">Top level chart classes will create a number of such components, and
96
96
then either call methods or set private properties to tell them their
97
97
height and position - all the stuff which should be done for you and
98
98
which you cannot customise. We are working on modelling what the
99
99
components should be and will publish their APIs here as a consensus
102
102
disc("<i>Multiples </i>")
103
disc("""<para lindent=+36>A corollary of the component approach is that you can create diagrams
103
disc("""<para lindent="+36">A corollary of the component approach is that you can create diagrams
104
104
with multiple charts, or custom data graphics. Our favourite example
105
105
of what we are aiming for is the weather report in our gallery
106
106
contributed by a user; we'd like to make it easy to create such
107
107
drawings, hook the building blocks up to their legends, and feed that
108
data in a consistent way.""")
109
disc("""<para lindent=+36>(If you want to see the image, it is available on our website at
110
<font color=blue>http://www.reportlab.com/demos/provencio.pdf</font>)""")
108
data in a consistent way.</para>""")
109
disc("""<para lindent="+36">(If you want to see the image, it is available on our website
110
<font color="blue"><a href="https://www.reportlab.com/media/imadj/data/RLIMG_e5e5cb85cc0a555f5433528ac38c5884.PDF">here</a></font>)</para>""")
113
113
##heading3("Key Concepts and Components")
902
902
lc.joinedLines = 1
903
catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
903
catNames = 'Jan Feb Mar Apr May Jun Jul Aug'.split(' ')
904
904
lc.categoryAxis.categoryNames = catNames
905
905
lc.categoryAxis.labels.boxAnchor = 'n'
906
906
lc.valueAxis.valueMin = 0
929
929
lc.joinedLines = 1
930
catNames = string.split('Jan Feb Mar Apr May Jun Jul Aug', ' ')
930
catNames = 'Jan Feb Mar Apr May Jun Jul Aug'.split(' ')
931
931
lc.categoryAxis.categoryNames = catNames
932
932
lc.categoryAxis.labels.boxAnchor = 'n'
933
933
lc.valueAxis.valueMin = 0