ChartOutput::endCharts()   A
last analyzed

Complexity

Conditions 5
Paths 3

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 11.4436

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 3
nop 1
dl 0
loc 18
ccs 4
cts 11
cp 0.3636
crap 11.4436
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
namespace CMEN\GoogleChartsBundle\Output\Javascript;
4
5
use CMEN\GoogleChartsBundle\Exception\GoogleChartsException;
6
use CMEN\GoogleChartsBundle\GoogleCharts\Chart;
7
use CMEN\GoogleChartsBundle\GoogleCharts\Charts\Diff\DiffChart;
8
use CMEN\GoogleChartsBundle\Output\AbstractChartOutput;
9
use CMEN\GoogleChartsBundle\Output\DataOutputInterface;
10
use CMEN\GoogleChartsBundle\Output\EventsOutputInterface;
11
use CMEN\GoogleChartsBundle\Output\OptionsOutputInterface;
12
13
/**
14
 * @author Christophe Meneses
15
 */
16
class ChartOutput extends AbstractChartOutput
17
{
18 14
    public function __construct(
19
        string $version,
20
        string $language,
21
        private readonly OptionsOutputInterface $optionsOutput,
22
        private readonly DataOutputInterface $dataOutput,
23
        private readonly EventsOutputInterface $eventsOutput,
24
    ) {
25 14
        parent::__construct($version, $language);
26
    }
27
28 5
    public function startChart(Chart $chart): string
29
    {
30 5
        if (null === $chart->getElementID()) {
31 1
            throw new GoogleChartsException('Container is not defined.');
32
        }
33
34 4
        $js = 'var '.$chart->getName().' = new google.'.$chart->getLibrary().'.'.$chart->getType().
35 4
            '(document.getElementById("'.$chart->getElementID().'"));';
36
37 4
        if (!$chart instanceof DiffChart) {
38 4
            $js .= $this->dataOutput->draw($chart->getData(), $chart->getDataName());
39
        } else {
40
            $js .= $this->dataOutput->draw($chart->getOldChart()->getData(), 'old_'.$chart->getDataName()).
41
                $this->dataOutput->draw($chart->getNewChart()->getData(), 'new_'.$chart->getDataName()).
42
                'var '.$chart->getDataName().' = '.$chart->getName().
43
                '.computeDiff(old_'.$chart->getDataName().',
44
                 new_'.$chart->getDataName().');';
45
        }
46
47 4
        $js .= $this->optionsOutput->draw($chart->getOptions(), $chart->getOptionsName());
48
49 4
        return $js;
50
    }
51
52 4
    public function endChart(Chart $chart): string
53
    {
54 4
        if ('visualization' == $chart->getLibrary()) {
55 4
            $options = $chart->getOptionsName();
56
        } else {
57
            /* Options conversion for material charts */
58
            $options = 'google.'.$chart->getLibrary().'.'.$chart->getType().
59
                '.convertOptions('.$chart->getOptionsName().')';
60
        }
61
62 4
        return $this->eventsOutput->draw($chart->getEvents(), $chart->getName()).$chart->getName().
63 4
            '.draw('.$chart->getDataName().', '.$options.');';
64
    }
65
66 10
    public function startCharts($charts, $elementsID = null): string
67
    {
68 10
        if ($charts instanceof Chart) {
69 5
            $charts = [$charts];
70
71 5
            if ($elementsID) {
72 1
                if (!is_string($elementsID)) {
73 1
                    throw new GoogleChartsException('A string is expected for HTML element ID.');
74
                }
75
76 4
                $elementsID = [$elementsID];
77
            }
78 5
        } elseif (is_array($charts) && !empty($charts)) {
79 4
            $this->checkChartsTypes($charts);
80
81 3
            if (null !== $elementsID) {
82 3
                if (!is_array($elementsID)) {
83 1
                    throw new GoogleChartsException('An array of string is expected for HTML elements IDs.');
84
                }
85
86 2
                $this->checkElementsId($charts, $elementsID);
87
            }
88
        } else {
89 1
            throw new GoogleChartsException('An instance of Chart or an array of Chart is expected.');
90
        }
91
92 4
        $packages = [];
93 4
        $drawChartName = '';
94 4
        $nbCharts = count($charts);
95 4
        for ($i = 0; $i < $nbCharts; ++$i) {
96 4
            if ($elementsID) {
97
                $charts[$i]->setElementID($elementsID[$i]);
98
            }
99
100 4
            if (!in_array($charts[$i]->getPackage(), $packages)) {
101 4
                $packages[] = $charts[$i]->getPackage();
102
            }
103 4
            $drawChartName .= $charts[$i]->getElementID();
104
        }
105
106 4
        $js = $this->loadLibraries($packages);
107
108 4
        $js .= $this->startCallback('drawChart'.ucfirst(md5($drawChartName)));
109
110 4
        foreach ($charts as $chart) {
111 4
            $js .= $this->startChart($chart);
112
        }
113
114 4
        return $js;
115
    }
116
117 4
    public function endCharts($charts): string
118
    {
119 4
        if ($charts instanceof Chart) {
120 4
            $js = $this->endChart($charts).$this->endCallback();
121
        } elseif (is_array($charts) && !empty($charts)) {
122
            $this->checkChartsTypes($charts);
123
124
            $js = '';
125
            foreach ($charts as $chart) {
126
                $js .= $this->endChart($chart);
127
            }
128
129
            $js .= $this->endCallback();
130
        } else {
131
            throw new GoogleChartsException('An instance of Chart or an array of Chart is expected.');
132
        }
133
134 4
        return $js;
135
    }
136
137 4
    public function fullCharts($charts, $elementsID = null): string
138
    {
139 4
        return $this->startCharts($charts, $elementsID).$this->endCharts($charts);
140
    }
141
142 5
    public function loadLibraries(array $packages): string
143
    {
144 5
        array_walk($packages, function (&$item): void {
145 5
            $item = "'".$item."'";
146 5
        });
147
148 5
        ($this->language) ? $language = ", language: '".$this->language."'" : $language = '';
149
150 5
        $load = "'".$this->version."', {packages:[".implode(',', $packages).']'.$language.'}';
151
152 5
        return "google.charts.load($load);";
153
    }
154
155 5
    public function startCallback(string $name): string
156
    {
157 5
        return "google.charts.setOnLoadCallback($name); function $name() {";
158
    }
159
160 5
    public function endCallback(): string
161
    {
162 5
        return '}';
163
    }
164
}
165