Passed
Pull Request — master (#51)
by Christophe
03:10
created

ChartOutput::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

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