root/trunk/tests/bar.py

Revision 176, 13.9 kB (checked in by lgs, 3 years ago)

Fix in the computation of the bar width when there is just one data point and a custom range. Fixes #20

Line 
1# Copyright(c) 2007-2009 by Lorenzo Gil Sanchez <lorenzo.gil.sanchez@gmail.com>
2#
3# This file is part of PyCha.
4#
5# PyCha is free software: you can redistribute it and/or modify
6# it under the terms of the GNU Lesser General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# PyCha is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13# GNU Lesser General Public License for more details.
14#
15# You should have received a copy of the GNU Lesser General Public License
16# along with PyCha.  If not, see <http://www.gnu.org/licenses/>.
17
18import unittest
19
20import cairo
21
22import pycha.bar
23
24
25class RectTests(unittest.TestCase):
26
27    def test_rect(self):
28        r = pycha.bar.Rect(2, 3, 20, 40, 2.5, 3.4, 'test')
29        self.assertEqual(r.x, 2)
30        self.assertEqual(r.y, 3)
31        self.assertEqual(r.w, 20)
32        self.assertEqual(r.h, 40)
33        self.assertEqual(r.xval, 2.5)
34        self.assertEqual(r.yval, 3.4)
35        self.assertEqual(r.name, 'test')
36
37
38class BarTests(unittest.TestCase):
39
40    def test_init(self):
41        ch = pycha.bar.BarChart(None)
42        self.assertEqual(ch.bars, [])
43        self.assertEqual(ch.minxdelta, 0)
44
45    def test_updateChart(self):
46        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
47        # An evil dataset with just one point. See bug #9
48        dataset = (
49            ('dataset1', ([0, 0], )),
50        )
51        ch = pycha.bar.BarChart(surface)
52        ch.addDataset(dataset)
53        ch._updateXY()
54        ch._updateChart()
55
56        self.assertEqual(ch.xscale, 1.0)
57        self.assertEqual(ch.minxval, 0)
58        self.assertEqual(ch.minxdelta, 1.0)
59        self.assertAlmostEqual(ch.barWidthForSet, 0.75, 4)
60        self.assertAlmostEqual(ch.barMargin, 0.125, 4)
61
62    def test_customRangeWithOnePoint(self):
63        """Weird results with a custom range and just one point. See bug #20"""
64        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
65
66        dataset = (
67            ('dataset1', ([0, 1], )),
68        )
69        options = {
70            'axis': {
71                'x': {
72                    'range': (0.0, 4.0),
73                    },
74                },
75            }
76        ch = pycha.bar.BarChart(surface, options)
77        ch.addDataset(dataset)
78        ch._updateXY()
79        ch._updateChart()
80
81        self.assertEqual(ch.xscale, 0.2)
82        self.assertEqual(ch.minxval, 0)
83        self.assertEqual(ch.minxdelta, 1.0)
84        self.assertAlmostEqual(ch.barWidthForSet, 0.15, 2)
85        self.assertAlmostEqual(ch.barMargin, 0.025, 3)
86
87
88class VerticalBarTests(unittest.TestCase):
89
90    def test_updateChart(self):
91        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
92        dataset = (
93            ('dataset1', ([0, 3], [1, 4], [2, 2], [3, 5], [4, 3.5])),
94            ('dataset2', ([0, 2], [1, 3], [2, 1], [3, 5], [4, 2.5])),
95            )
96        ch = pycha.bar.VerticalBarChart(surface)
97        ch.addDataset(dataset)
98        ch._updateXY()
99        ch._updateChart()
100        self.assertEqual(ch.minxval, 0)
101        self.assertEqual(ch.maxxval, 4)
102        self.assertEqual(ch.xrange, 4)
103        self.assertAlmostEqual(ch.xscale, 0.20, 4)
104        self.assertEqual(ch.minyval, 0)
105        self.assertEqual(ch.maxyval, 5)
106        self.assertEqual(ch.yrange, 5)
107        self.assertAlmostEqual(ch.yscale, 0.20, 4)
108        self.assertEqual(ch.minxdelta, 1)
109        self.assertAlmostEqual(ch.barWidthForSet, 0.075, 4)
110        self.assertAlmostEqual(ch.barMargin, 0.025, 4)
111
112        R = pycha.bar.Rect
113        bars = (
114            R(0.025, 0.400, 0.075, 0.600, 0, 3, 'dataset1'),
115            R(0.225, 0.200, 0.075, 0.800, 1, 4, 'dataset1'),
116            R(0.425, 0.600, 0.075, 0.400, 2, 2, 'dataset1'),
117            R(0.625, 0.000, 0.075, 1.000, 3, 5, 'dataset1'),
118            R(0.825, 0.300, 0.075, 0.700, 4, 3.5, 'dataset1'),
119
120            R(0.100, 0.600, 0.075, 0.400, 0, 2, 'dataset2'),
121            R(0.300, 0.400, 0.075, 0.600, 1, 3, 'dataset2'),
122            R(0.500, 0.800, 0.075, 0.200, 2, 1, 'dataset2'),
123            R(0.700, 0.000, 0.075, 1.000, 3, 5, 'dataset2'),
124            R(0.900, 0.500, 0.075, 0.500, 4, 2.5, 'dataset2'),
125            )
126
127        for i, bar in enumerate(bars):
128            b1, b2 = ch.bars[i], bar
129            self.assertAlmostEqual(b1.x, b2.x, 4)
130            self.assertAlmostEqual(b1.y, b2.y, 4)
131            self.assertAlmostEqual(b1.w, b2.w, 4)
132            self.assertAlmostEqual(b1.h, b2.h, 4)
133            self.assertEqual(b1.xval, b2.xval)
134            self.assertEqual(b1.yval, b2.yval)
135            self.assertEqual(b1.name, b2.name)
136
137    def test_updateChartWithNegatives(self):
138        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
139        dataset = (
140            ('dataset1', ([0, -3], [1, -1], [2, 3], [3, 5])),
141            )
142        ch = pycha.bar.VerticalBarChart(surface)
143        ch.addDataset(dataset)
144        ch._updateXY()
145        ch._updateChart()
146        self.assertEqual(ch.minxval, 0)
147        self.assertEqual(ch.maxxval, 3)
148        self.assertEqual(ch.xrange, 3)
149        self.assertAlmostEqual(ch.xscale, 0.25, 4)
150        self.assertEqual(ch.minyval, -3)
151        self.assertEqual(ch.maxyval, 5)
152        self.assertEqual(ch.yrange, 8)
153        self.assertAlmostEqual(ch.yscale, 0.125, 4)
154        self.assertAlmostEqual(ch.area.origin, 0.375)
155        self.assertEqual(ch.minxdelta, 1)
156        self.assertAlmostEqual(ch.barWidthForSet, 0.1875, 4)
157        self.assertAlmostEqual(ch.barMargin, 0.03125, 4)
158
159        R = pycha.bar.Rect
160        bars = (
161            R(0.03125, 0.625, 0.1875, 0.375, 0, -3, 'dataset1'),
162            R(0.28125, 0.625, 0.1875, 0.125, 1, -1, 'dataset1'),
163            R(0.53125, 0.250, 0.1875, 0.375, 2, 3, 'dataset1'),
164            R(0.78125, 0.000, 0.1875, 0.625, 3, 5, 'dataset1'),
165            )
166
167        for i, bar in enumerate(bars):
168            b1, b2 = ch.bars[i], bar
169            self.assertAlmostEqual(b1.x, b2.x, 4)
170            self.assertAlmostEqual(b1.y, b2.y, 4)
171            self.assertAlmostEqual(b1.w, b2.w, 4)
172            self.assertAlmostEqual(b1.h, b2.h, 4)
173            self.assertEqual(b1.xval, b2.xval)
174            self.assertEqual(b1.yval, b2.yval)
175            self.assertEqual(b1.name, b2.name)
176
177    def test_updateTicks(self):
178        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
179        dataset = (
180            ('dataset1', ([0, 1], [1, 1], [2, 3])),
181            ('dataset2', ([0, 2], [1, 0], [3, 4])),
182            )
183        ch = pycha.bar.VerticalBarChart(surface)
184        ch.addDataset(dataset)
185        ch._updateXY()
186        ch._updateChart()
187        ch._updateTicks()
188        xticks = [(0.125, 0), (0.375, 1), (0.625, 2)]
189        for i in range(len(xticks)):
190            self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4)
191            self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4)
192
193        yticks = [
194            (1.0, 0.0), (0.9, 0.4), (0.8, 0.8), (0.7, 1.2), (0.6, 1.6),
195            (0.5, 2.0), (0.4, 2.4), (0.3, 2.8), (0.2, 3.2), (0.1, 3.6),
196            (0.0, 4.0),
197            ]
198        for i in range(len(yticks)):
199            self.assertAlmostEqual(ch.yticks[i][0], yticks[i][0], 4)
200            self.assertAlmostEqual(ch.yticks[i][1], yticks[i][1], 4)
201
202    def test_udpateTicksWithNegatives(self):
203        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
204        dataset = (
205            ('dataset1', ([0, -2], [1, 1], [2, 3])),
206            )
207        ch = pycha.bar.VerticalBarChart(surface)
208        ch.addDataset(dataset)
209        ch._updateXY()
210        ch._updateChart()
211        ch._updateTicks()
212        xticks = [(0.1667, 0), (0.5000, 1), (0.8333, 2)]
213        for i in range(len(xticks)):
214            self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4)
215            self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4)
216
217        yticks = [
218            (1.0, -2.0), (0.9, -1.5), (0.8, -1.0), (0.7, -0.5), (0.6, 0.0),
219            (0.5, 0.5), (0.4, 1.0), (0.3, 1.5), (0.2, 2.0), (0.1, 2.5),
220            (0.0, 3.0),
221            ]
222        for i in range(len(yticks)):
223            self.assertAlmostEqual(ch.yticks[i][0], yticks[i][0], 4)
224            self.assertAlmostEqual(ch.yticks[i][1], yticks[i][1], 4)
225
226    def test_shadowRectangle(self):
227        ch = pycha.bar.VerticalBarChart(None)
228        shadow = ch._getShadowRectangle(10, 20, 400, 300)
229        self.assertEqual(shadow, (8, 18, 404, 302))
230
231
232class HorizontalBarTests(unittest.TestCase):
233
234    def test_updateChart(self):
235        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
236        dataset = (
237            ('dataset1', ([0, 1], [1, 1], [2, 3])),
238            ('dataset2', ([0, 2], [1, 0], [3, 4])),
239            )
240        ch = pycha.bar.HorizontalBarChart(surface)
241        ch.addDataset(dataset)
242        ch._updateXY()
243        ch._updateChart()
244        self.assertEqual(ch.xrange, 3)
245        self.assertAlmostEqual(ch.xscale, 0.25, 4)
246        self.assertAlmostEqual(ch.yscale, 0.25, 4)
247        self.assertEqual(ch.minxdelta, 1)
248        self.assertAlmostEqual(ch.barWidthForSet, 0.09375, 4)
249        self.assertAlmostEqual(ch.barMargin, 0.03125, 4)
250
251        bars = (
252            pycha.bar.Rect(0, 0.03125, 0.25, 0.09375, 0, 1, 'dataset1'),
253            pycha.bar.Rect(0, 0.28125, 0.25, 0.09375, 1, 1, 'dataset1'),
254            pycha.bar.Rect(0, 0.53125, 0.75, 0.09375, 2, 3, 'dataset1'),
255
256            pycha.bar.Rect(0, 0.125, 0.5, 0.09375, 0, 2, 'dataset2'),
257            pycha.bar.Rect(0, 0.375, 0.0, 0.09375, 1, 0, 'dataset2'),
258            pycha.bar.Rect(0, 0.875, 1.0, 0.09375, 3, 4, 'dataset2'),
259            )
260
261        for i, bar in enumerate(bars):
262            b1, b2 = ch.bars[i], bar
263            self.assertAlmostEqual(b1.x, b2.x, 4)
264            self.assertAlmostEqual(b1.y, b2.y, 4)
265            self.assertAlmostEqual(b1.w, b2.w, 4)
266            self.assertAlmostEqual(b1.h, b2.h, 4)
267            self.assertEqual(b1.xval, b2.xval)
268            self.assertEqual(b1.yval, b2.yval)
269            self.assertEqual(b1.name, b2.name)
270
271    def test_updateChartWithNegatives(self):
272        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
273        dataset = (
274            ('dataset1', ([0, -3], [1, -1], [2, 3], [3, 5])),
275            )
276
277        ch = pycha.bar.HorizontalBarChart(surface)
278        ch.addDataset(dataset)
279        ch._updateXY()
280        ch._updateChart()
281        self.assertEqual(ch.minxval, 0)
282        self.assertEqual(ch.maxxval, 3)
283        self.assertEqual(ch.xrange, 3)
284        self.assertAlmostEqual(ch.xscale, 0.25, 4)
285        self.assertEqual(ch.minyval, -3)
286        self.assertEqual(ch.maxyval, 5)
287        self.assertEqual(ch.yrange, 8)
288        self.assertAlmostEqual(ch.yscale, 0.125, 4)
289        self.assertAlmostEqual(ch.area.origin, 0.375)
290        self.assertEqual(ch.minxdelta, 1)
291        self.assertAlmostEqual(ch.barWidthForSet, 0.1875, 4)
292        self.assertAlmostEqual(ch.barMargin, 0.03125, 4)
293
294        R = pycha.bar.Rect
295        bars = (
296            R(0.000, 0.03125, 0.375, 0.1875, 0, -3, 'dataset1'),
297            R(0.250, 0.28125, 0.125, 0.1875, 1, -1, 'dataset1'),
298            R(0.375, 0.53125, 0.375, 0.1875, 2, 3, 'dataset1'),
299            R(0.375, 0.78125, 0.625, 0.1875, 3, 5, 'dataset1'),
300            )
301
302        for i, bar in enumerate(bars):
303            b1, b2 = ch.bars[i], bar
304            self.assertAlmostEqual(b1.x, b2.x, 4)
305            self.assertAlmostEqual(b1.y, b2.y, 4)
306            self.assertAlmostEqual(b1.w, b2.w, 4)
307            self.assertAlmostEqual(b1.h, b2.h, 4)
308            self.assertEqual(b1.xval, b2.xval)
309            self.assertEqual(b1.yval, b2.yval)
310            self.assertEqual(b1.name, b2.name)
311
312    def test_updateTicks(self):
313        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
314        dataset = (
315            ('dataset1', ([0, 1], [1, 1], [2, 3])),
316            ('dataset2', ([0, 2], [1, 0], [3, 4])),
317            )
318        ch = pycha.bar.HorizontalBarChart(surface)
319        ch.addDataset(dataset)
320        ch._updateXY()
321        ch._updateChart()
322        ch._updateTicks()
323
324        xticks = [
325            (0.0, 0.0), (0.1, 0.4), (0.2, 0.8), (0.3, 1.2), (0.4, 1.6),
326            (0.5, 2.0), (0.6, 2.4), (0.7, 2.8), (0.8, 3.2), (0.9, 3.6),
327            (1.0, 4.0),
328            ]
329        for i in range(len(xticks)):
330            self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4)
331            self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4)
332
333        yticks = [(0.125, 0), (0.375, 1), (0.625, 2)]
334        for i in range(len(yticks)):
335            self.assertAlmostEqual(ch.yticks[i][0], yticks[i][0], 4)
336            self.assertAlmostEqual(ch.yticks[i][1], yticks[i][1], 4)
337
338    def test_udpateTicksWithNegatives(self):
339        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, 500, 500)
340        dataset = (
341            ('dataset1', ([0, -2], [1, 1], [2, 3])),
342            )
343        ch = pycha.bar.HorizontalBarChart(surface)
344        ch.addDataset(dataset)
345        ch._updateXY()
346        ch._updateChart()
347        ch._updateTicks()
348        xticks = [
349            (0.0, -2.0), (0.1, -1.5), (0.2, -1.0), (0.3, -0.5), (0.4, 0.0),
350            (0.5, 0.5), (0.6, 1.0), (0.7, 1.5), (0.8, 2.0), (0.9, 2.5),
351            (1.0, 3.0),
352            ]
353        for i in range(len(xticks)):
354            self.assertAlmostEqual(ch.xticks[i][0], xticks[i][0], 4)
355            self.assertAlmostEqual(ch.xticks[i][1], xticks[i][1], 4)
356
357        yticks = [(0.1667, 0), (0.5000, 1), (0.8333, 2)]
358        for i in range(len(yticks)):
359            self.assertAlmostEqual(ch.yticks[i][0], yticks[i][0], 4)
360            self.assertAlmostEqual(ch.yticks[i][1], yticks[i][1], 4)
361
362    def test_shadowRectangle(self):
363        ch = pycha.bar.HorizontalBarChart(None)
364        shadow = ch._getShadowRectangle(10, 20, 400, 300)
365        self.assertEqual(shadow, (10, 18, 402, 304))
366
367
368def test_suite():
369    return unittest.TestSuite((
370        unittest.makeSuite(RectTests),
371        unittest.makeSuite(BarTests),
372        unittest.makeSuite(VerticalBarTests),
373        unittest.makeSuite(HorizontalBarTests),
374    ))
375
376if __name__ == '__main__':
377    unittest.main(defaultTest='test_suite')
Note: See TracBrowser for help on using the browser.