Projet

Général

Profil

0001-dataviz-add-stacked-bar-percent-chart-type-52845.patch

Valentin Deniaud, 12 avril 2021 16:26

Télécharger (5,12 ko)

Voir les différences:

Subject: [PATCH] dataviz: add stacked bar percent chart type (#52845)

 .../migrations/0011_auto_20200813_1100.py     |  1 +
 combo/apps/dataviz/models.py                  | 20 ++++++++++++++++
 tests/test_dataviz.py                         | 24 +++++++++++++++++++
 3 files changed, 45 insertions(+)
combo/apps/dataviz/migrations/0011_auto_20200813_1100.py
45 45
                    ('bar', 'Bar'),
46 46
                    ('horizontal-bar', 'Horizontal Bar'),
47 47
                    ('stacked-bar', 'Stacked Bar'),
48
                    ('stacked-bar-percent', 'Stacked Bar (%)'),
48 49
                    ('line', 'Line'),
49 50
                    ('pie', 'Pie'),
50 51
                    ('dot', 'Dot'),
combo/apps/dataviz/models.py
190 190
            ('bar', _('Bar')),
191 191
            ('horizontal-bar', _('Horizontal Bar')),
192 192
            ('stacked-bar', _('Stacked Bar')),
193
            ('stacked-bar-percent', _('Stacked Bar (%)')),
193 194
            ('line', _('Line')),
194 195
            ('pie', _('Pie')),
195 196
            ('dot', _('Dot')),
......
306 307
            'bar': pygal.Bar,
307 308
            'horizontal-bar': pygal.HorizontalBar,
308 309
            'stacked-bar': pygal.StackedBar,
310
            'stacked-bar-percent': pygal.StackedBar,
309 311
            'line': pygal.Line,
310 312
            'pie': pygal.Pie,
311 313
            'dot': pygal.Dot,
......
337 339
                        if data
338 340
                    ]
339 341

  
342
            if self.chart_type == 'stacked-bar-percent':
343
                self.make_percent([serie['data'] for serie in data['series']])
344

  
340 345
            for serie in data['series']:
341 346
                chart.add(serie['label'], serie['data'])
342 347

  
......
485 490

  
486 491
    def add_data_to_chart(self, chart, data, y_labels):
487 492
        if self.chart_type != 'pie':
493
            series_data = []
488 494
            for i, serie_label in enumerate(y_labels):
489 495
                if chart.axis_count < 2:
490 496
                    values = data
491 497
                else:
492 498
                    values = [data[i][j] for j in range(len(chart.x_labels))]
499
                series_data.append(values)
493 500
                chart.add(serie_label, values)
501
            if self.chart_type == 'stacked-bar-percent':
502
                self.make_percent(series_data)
494 503
        else:
495 504
            # pie, create a serie by data, to get different colours
496 505
            values = data
......
529 538
        elif measure == 'percent':
530 539
            percent_formatter = lambda x: '{:.1f}%'.format(x)
531 540
            return percent_formatter
541

  
542
    def make_percent(self, series_data):
543
        for i, values in enumerate(zip(*series_data)):
544
            sum_values = sum([v for v in values if v is not None])
545
            if sum_values == 0:
546
                continue
547

  
548
            factor = 100 / sum_values
549
            for values in series_data:
550
                if values[i] is not None:
551
                    values[i] = round(values[i] * factor, 1)
tests/test_dataviz.py
441 441
        ([122, 114, 2, 33], {'title': u'bar'}),
442 442
    ]
443 443

  
444
    # stacked bar with percent
445
    cell.chart_type = 'stacked-bar-percent'
446
    cell.save()
447

  
448
    chart = cell.get_chart()
449
    assert chart.x_labels == ['web', 'mail', 'phone', 'email']
450
    assert chart.raw_series == [
451
        ([64.5, 54, 0, 61.6], {'title': u'foo'}),
452
        ([35.5, 46, 100, 38.4], {'title': u'bar'}),
453
    ]
454
    assert all(x + y == 100 for x, y in zip(chart.raw_series[0][0], chart.raw_series[1][0]))
455

  
444 456
    # single data point
445 457
    cell.chart_type = 'bar'
446 458
    cell.statistic = Statistic.objects.get(slug='fourth')
......
533 545
    assert chart.x_labels == ['2020-10', '2020-11', '2020-12']
534 546
    assert chart.raw_series == [([None, 16, 2], {'title': 'Serie 1'}), ([2, 1, None], {'title': 'Serie 2'})]
535 547

  
548
    # stacked bar with percent
549
    cell.chart_type = 'stacked-bar-percent'
550
    cell.save()
551

  
552
    chart = cell.get_chart()
553
    assert chart.x_labels == ['2020-10', '2020-11', '2020-12']
554
    assert chart.raw_series == [
555
        ([None, 94.1, 100], {'title': 'Serie 1'}),
556
        ([100, 5.9, None], {'title': 'Serie 2'}),
557
    ]
558
    assert all(x + y == 100 for x, y in zip(chart.raw_series[0][0], chart.raw_series[1][0]) if x and y)
559

  
536 560
    cell.statistic = Statistic.objects.get(slug='no-data')
537 561
    cell.save()
538 562

  
539
-