title: Updating spline class on a graph so that the highest peak is the marker position - JPGraph
body: <p>I have created a graph using Jpgraph (<a href="http://www.jpgraph.com" rel="nofollow noreferrer">http://www.jpgraph.com</a>). </p>
  
  <p>Jpgraph has a spline class which smooths out the lines on the line graph. However it does not work as I expected. As you can see, the highest peak of the line goes above the actual markings (the red squares). Friday 10pm is 2.0 however it appears to be higher than that around 6am friday.</p>
  
  <p><a href="https://i.stack.imgur.com/w76AJ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/w76AJ.png" alt="enter image description here"></a></p>
  
  <p>A poorly laptop touchpad drawn example of what I would have expected is below :)
  <a href="https://i.stack.imgur.com/jybxi.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/jybxi.png" alt="enter image description here"></a></p>
  
  <p>I have managed to track down the class to jpgraph_regstat.php. Any idea how to make the center of the peak the actual markings?</p>
  
  <pre><code>//------------------------------------------------------------------------
  // CLASS Spline
  // Create a new data array from an existing data array but with more points.
  // The new points are interpolated using a cubic spline algorithm
  //------------------------------------------------------------------------
  class Spline {
      // 3:rd degree polynom approximation
  
      private $xdata,$ydata;   // Data vectors
      private $y2;   // 2:nd derivate of ydata
      private $n=0;
  
      function __construct($xdata,$ydata) {
          $this-&gt;y2 = array();
          $this-&gt;xdata = $xdata;
          $this-&gt;ydata = $ydata;
  
          $n = count($ydata);
          $this-&gt;n = $n;
          if( $this-&gt;n !== count($xdata) ) {
              JpGraphError::RaiseL(19001);
              //('Spline: Number of X and Y coordinates must be the same');
          }
  
          // Natural spline 2:derivate == 0 at endpoints
          $this-&gt;y2[0]    = 0.0;
          $this-&gt;y2[$n-1] = 0.0;
          $delta[0] = 0.0;
  
          // Calculate 2:nd derivate
          for($i=1; $i &lt; $n-1; ++$i) {
              $d = ($xdata[$i+1]-$xdata[$i-1]);
              if( $d == 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.');
              }
              $s = ($xdata[$i]-$xdata[$i-1])/$d;
              $p = $s*$this-&gt;y2[$i-1]+2.0;
              $this-&gt;y2[$i] = ($s-1.0)/$p;
              $delta[$i] = ($ydata[$i+1]-$ydata[$i])/($xdata[$i+1]-$xdata[$i]) -
              ($ydata[$i]-$ydata[$i-1])/($xdata[$i]-$xdata[$i-1]);
              $delta[$i] = (6.0*$delta[$i]/($xdata[$i+1]-$xdata[$i-1])-$s*$delta[$i-1])/$p;
          }
  
          // Backward substitution
          for( $j=$n-2; $j &gt;= 0; --$j ) {
              $this-&gt;y2[$j] = $this-&gt;y2[$j]*$this-&gt;y2[$j+1] + $delta[$j];
          }
      }
  
      // Return the two new data vectors
      function Get($num=50) {
          $n = $this-&gt;n ;
          $step = ($this-&gt;xdata[$n-1]-$this-&gt;xdata[0]) / ($num-1);
          $xnew=array();
          $ynew=array();
          $xnew[0] = $this-&gt;xdata[0];
          $ynew[0] = $this-&gt;ydata[0];
          for( $j=1; $j &lt; $num; ++$j ) {
              $xnew[$j] = $xnew[0]+$j*$step;
              $ynew[$j] = $this-&gt;Interpolate($xnew[$j]);
          }
          return array($xnew,$ynew);
      }
  
      // Return a single interpolated Y-value from an x value
      function Interpolate($xpoint) {
  
          $max = $this-&gt;n-1;
          $min = 0;
  
          // Binary search to find interval
          while( $max-$min &gt; 1 ) {
              $k = ($max+$min) / 2;
              if( $this-&gt;xdata[$k] &gt; $xpoint )
              $max=$k;
              else
              $min=$k;
          }
  
          // Each interval is interpolated by a 3:degree polynom function
          $h = $this-&gt;xdata[$max]-$this-&gt;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-&gt;xdata[$max]-$xpoint)/$h;
          $b = ($xpoint-$this-&gt;xdata[$min])/$h;
          return $a*$this-&gt;ydata[$min]+$b*$this-&gt;ydata[$max]+
          (($a*$a*$a-$a)*$this-&gt;y2[$min]+($b*$b*$b-$b)*$this-&gt;y2[$max])*($h*$h)/6.0;
      }
  }
  </code></pre>
  
  <p>Code example using spline can be found here (<a href="http://jpgraph.net/download/manuals/chunkhtml/example_src/splineex1.html" rel="nofollow noreferrer">http://jpgraph.net/download/manuals/chunkhtml/example_src/splineex1.html</a>)</p>