Ik ben voor mijn vrouw een kleine tool in elkaar aan het draaien die haar in staat stelt om haar cyclus bij te houden en eventueel te temperaturen. Deze temperaturen zouden dan vervolgens tot een grafiekje verwerkt moeten worden. Dit werkt prima wanneer het aantal meetpunten heel laag is (bij 6 is er geen enkel probleem), maar wanneer ik een grotere range wil zien, zeg 10, dan krijg ik een foutmelding die niet van toepassing zou moeten zijn.
Wat doe ik?
Allereerst heb ik dus in de database een aantal data zitten met daarbij een temperatuur. Deze worden uit de db gehaald en vervolgens in de volgende code aan Jpgraph aangeboden:
De fout treedt op in de aanroep van de Get method van het Spline object. Deze dient voor zover ik kan zien om een voldoende hoog aantal punten te leveren zodat er vloeiende lijnen kunnen worden getrokken. Binnen deze method wordt de method Interpolate aangeroepen en in deze method wordt de fout gegenereerd (zo leert debuggen mij.) Ik heb alleen geen enkel idee wat deze method precies voor elkaar probeert te krijgen of waarom hij een foutmelding genereert die niet klopt.
Als ik debug en $min en $max laat zien krijg ik het volgende:
Element $aX[0.5625] wordt door PHP dus herleid naar element 0 (niet raar) en vervolgens concludeert hij dat er één of meer elementen gelijk aan elkaar zijn. Ik heb ook geprobeerd de foutmelding gewoon keihard uit te commenten, maar de grafiek die dan gegenereert wordt klopt vervolgens ook niet:

De input voor de x-as is de volgende array:
Input voor de y-as is de volgende array:
Zoals je ziet zijn alle waarden in de array met data voor de x-as uniek. Het is mij dus een raadsel waarom deze foutmelding optreedt of hoe ik hem zou moeten voorkomen. Is er iemand die me kan vertellen wat de functie Interpolate precies doet en waarom mijn input arrays deze foutmelding veroorzaken?
Om specifiek te zijn: hij zegt dat element [0] en element [0] gelijk zijn en hij dus de grafiek niet kan genereren. Heel typisch, dat die twee gelijk zijn. *kuch*Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.
Wat doe ik?
Allereerst heb ik dus in de database een aantal data zitten met daarbij een temperatuur. Deze worden uit de db gehaald en vervolgens in de volgende code aan Jpgraph aangeboden:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| try { $aResult = $oDB->query($sQuery, 'recordset'); } catch (CustomException $oException) { $oException->showError(9); } $aX = $aY = array(); foreach ($aResult as $aRecord) { $aX[] = strtotime($aRecord['date']); $aY[] = (float) $aRecord['temp']; } $oSpline = new Spline($aX, $aY); list($aNewX, $aNewY) = $oSpline->Get((count($aX) * 50)); $oGraph = new Graph((55 * count($aX)), 300); $oGraph->SetMargin(40, 20, 40, 30); $oGraph->title->Set('Temperatuurgrafiek test'); $oGraph->title->SetFont(FF_ARIAL, FS_NORMAL, 12); $oGraph->SetMarginColor('lightblue'); $oGraph->SetScale('datlin'); $oGraph->xgrid->Show(); $oGraph->xaxis->SetLabelFormatString('d-m', true); $oGraph->yaxis->SetLabelFormat('%1.1f'); $oGraph->img->SetImgFormat('png'); $oScatterplot = new ScatterPlot($aY, $aX); $oScatterplot->mark->SetFillColor('red@0.3'); $oScatterplot->mark->SetColor('red@0.5'); $oLineplot = new LinePlot($aNewY, $aNewX); $oLineplot->SetColor('navy'); $oGraph->Add($oLineplot); $oGraph->Add($oScatterplot); $sFilename = "./graphs/grafiek_".date('Ymd', time()).".png"; if (file_exists($sFilename)) { unlink($sFilename); } $oGraph->Stroke($sFilename); |
De fout treedt op in de aanroep van de Get method van het Spline object. Deze dient voor zover ik kan zien om een voldoende hoog aantal punten te leveren zodat er vloeiende lijnen kunnen worden getrokken. Binnen deze method wordt de method Interpolate aangeroepen en in deze method wordt de fout gegenereerd (zo leert debuggen mij.) Ik heb alleen geen enkel idee wat deze method precies voor elkaar probeert te krijgen of waarom hij een foutmelding genereert die niet klopt.
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
| // Return a single interpolated Y-value from an x value function Interpolate($xpoint) { $max = $this->n-1; $min = 0; // Binary search to find interval while( $max-$min > 1 ) { $k = ($max+$min) / 2; if( $this->xdata[$k] > $xpoint ) $max=$k; else $min=$k; } // Each interval is interpolated by a 3:degree polynom function $h = $this->xdata[$max]-$this->xdata[$min]; if( $h == 0 ) { JpGraphError::RaiseL(19002); //('Invalid input data for spline. Two or more consecutive input X-values are equal. Each input X-value must differ since from a mathematical point of view it must be a one-to-one mapping, i.e. each X-value must correspond to exactly one Y-value.'); } $a = ($this->xdata[$max]-$xpoint)/$h; $b = ($xpoint-$this->xdata[$min])/$h; return $a*$this->ydata[$min]+$b*$this->ydata[$max]+ (($a*$a*$a-$a)*$this->y2[$min]+($b*$b*$b-$b)*$this->y2[$max])*($h*$h)/6.0; } |
Als ik debug en $min en $max laat zien krijg ik het volgende:
PHP:
1
2
3
| int(0) float(0.5625) |
Element $aX[0.5625] wordt door PHP dus herleid naar element 0 (niet raar) en vervolgens concludeert hij dat er één of meer elementen gelijk aan elkaar zijn. Ik heb ook geprobeerd de foutmelding gewoon keihard uit te commenten, maar de grafiek die dan gegenereert wordt klopt vervolgens ook niet:

De input voor de x-as is de volgende array:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| array(10) { [0]=> int(1314835200) [1]=> int(1315008000) [2]=> int(1315094400) [3]=> int(1315353600) [4]=> int(1315526400) [5]=> int(1315612800) [6]=> int(1313798400) [7]=> int(1314057600) [8]=> int(1314316800) [9]=> int(1314403200) } |
Input voor de y-as is de volgende array:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| array(10) { [0]=> float(37.1) [1]=> float(36.9) [2]=> float(36.8) [3]=> float(37.2) [4]=> float(38.2) [5]=> float(37.5) [6]=> float(37.2) [7]=> float(37.4) [8]=> float(37.3) [9]=> float(37.2) } |
Zoals je ziet zijn alle waarden in de array met data voor de x-as uniek. Het is mij dus een raadsel waarom deze foutmelding optreedt of hoe ik hem zou moeten voorkomen. Is er iemand die me kan vertellen wat de functie Interpolate precies doet en waarom mijn input arrays deze foutmelding veroorzaken?