1<?php 2 3namespace CpChart\Chart; 4 5use CpChart\Data; 6use CpChart\Image; 7 8/** 9 * Split - class to draw spline splitted charts 10 * 11 * Version : 2.1.4 12 * Made by : Jean-Damien POGOLOTTI 13 * Last Update : 19/01/2014 14 * 15 * This file can be distributed under the license you can find at : 16 * 17 * http://www.pchart.net/license 18 * 19 * You can find the whole class documentation on the pChart web site. 20 */ 21class Split 22{ 23 /** 24 * @var Image 25 */ 26 public $pChartObject; 27 28 /** 29 * Create the encoded string 30 * @param Image $Object 31 * @param Data $Values 32 * @param array $Format 33 */ 34 public function drawSplitPath(Image $Object, Data $Values, array $Format = []) 35 { 36 $this->pChartObject = $Object; 37 38 $Spacing = isset($Format["Spacing"]) ? $Format["Spacing"] : 20; 39 $TextPadding = isset($Format["TextPadding"]) ? $Format["TextPadding"] : 2; 40 $TextPos = isset($Format["TextPos"]) ? $Format["TextPos"] : TEXT_POS_TOP; 41 $Surrounding = isset($Format["Surrounding"]) ? $Format["Surrounding"] : null; 42 $Force = isset($Format["Force"]) ? $Format["Force"] : 70; 43 $Segments = isset($Format["Segments"]) ? $Format["Segments"] : 15; 44 $X1 = $Object->GraphAreaX1; 45 $Y1 = $Object->GraphAreaY1; 46 $X2 = $Object->GraphAreaX2; 47 $Y2 = $Object->GraphAreaY2; 48 49 /* Data Processing */ 50 $Data = $Values->getData(); 51 $Palette = $Values->getPalette(); 52 53 $LabelSerie = $Data["Abscissa"]; 54 $DataSerie = []; 55 56 foreach ($Data["Series"] as $SerieName => $Value) { 57 if ($SerieName != $LabelSerie && empty($DataSerie)) { 58 $DataSerie = $SerieName; 59 } 60 } 61 62 $DataSerieSum = array_sum($Data["Series"][$DataSerie]["Data"]); 63 $DataSerieCount = count($Data["Series"][$DataSerie]["Data"]); 64 65 /* Scale Processing */ 66 if ($TextPos == TEXT_POS_RIGHT) { 67 $YScale = (($Y2 - $Y1) - (($DataSerieCount + 1) * $Spacing)) / $DataSerieSum; 68 } else { 69 $YScale = (($Y2 - $Y1) - ($DataSerieCount * $Spacing)) / $DataSerieSum; 70 } 71 $LeftHeight = $DataSerieSum * $YScale; 72 73 /* Re-compute graph width depending of the text mode choosen */ 74 if ($TextPos == TEXT_POS_RIGHT) { 75 $MaxWidth = 0; 76 foreach ($Data["Series"][$LabelSerie]["Data"] as $Key => $Label) { 77 $Boundardies = $Object->getTextBox(0, 0, $Object->FontName, $Object->FontSize, 0, $Label); 78 if ($Boundardies[1]["X"] > $MaxWidth) { 79 $MaxWidth = $Boundardies[1]["X"] + $TextPadding * 2; 80 } 81 } 82 $X2 = $X2 - $MaxWidth; 83 } 84 85 /* Drawing */ 86 $LeftY = ((($Y2 - $Y1) / 2) + $Y1) - ($LeftHeight / 2); 87 $RightY = $Y1; 88 89 foreach ($Data["Series"][$DataSerie]["Data"] as $Key => $Value) { 90 if (isset($Data["Series"][$LabelSerie]["Data"][$Key])) { 91 $Label = $Data["Series"][$LabelSerie]["Data"][$Key]; 92 } else { 93 $Label = "-"; 94 } 95 $LeftY1 = $LeftY; 96 $LeftY2 = $LeftY + $Value * $YScale; 97 98 $RightY1 = $RightY + $Spacing; 99 $RightY2 = $RightY + $Spacing + $Value * $YScale; 100 101 $Settings = [ 102 "R" => $Palette[$Key]["R"], 103 "G" => $Palette[$Key]["G"], 104 "B" => $Palette[$Key]["B"], 105 "Alpha" => $Palette[$Key]["Alpha"], 106 "NoDraw" => true, 107 "Segments" => $Segments, 108 "Surrounding" => $Surrounding 109 ]; 110 111 112 $Angle = $Object->getAngle($X2, $RightY1, $X1, $LeftY1); 113 $VectorX1 = cos(deg2rad($Angle + 90)) * $Force + ($X2 - $X1) / 2 + $X1; 114 $VectorY1 = sin(deg2rad($Angle + 90)) * $Force + ($RightY1 - $LeftY1) / 2 + $LeftY1; 115 $VectorX2 = cos(deg2rad($Angle - 90)) * $Force + ($X2 - $X1) / 2 + $X1; 116 $VectorY2 = sin(deg2rad($Angle - 90)) * $Force + ($RightY1 - $LeftY1) / 2 + $LeftY1; 117 118 $Points = $Object->drawBezier( 119 $X1, 120 $LeftY1, 121 $X2, 122 $RightY1, 123 $VectorX1, 124 $VectorY1, 125 $VectorX2, 126 $VectorY2, 127 $Settings 128 ); 129 130 $PolyGon = []; 131 foreach ($Points as $Key => $Pos) { 132 $PolyGon[] = $Pos["X"]; 133 $PolyGon[] = $Pos["Y"]; 134 } 135 136 $Angle = $Object->getAngle($X2, $RightY2, $X1, $LeftY2); 137 $VectorX1 = cos(deg2rad($Angle + 90)) * $Force + ($X2 - $X1) / 2 + $X1; 138 $VectorY1 = sin(deg2rad($Angle + 90)) * $Force + ($RightY2 - $LeftY2) / 2 + $LeftY2; 139 $VectorX2 = cos(deg2rad($Angle - 90)) * $Force + ($X2 - $X1) / 2 + $X1; 140 $VectorY2 = sin(deg2rad($Angle - 90)) * $Force + ($RightY2 - $LeftY2) / 2 + $LeftY2; 141 142 $Points = $Object->drawBezier( 143 $X1, 144 $LeftY2, 145 $X2, 146 $RightY2, 147 $VectorX1, 148 $VectorY1, 149 $VectorX2, 150 $VectorY2, 151 $Settings 152 ); 153 $Points = array_reverse($Points); 154 foreach ($Points as $Key => $Pos) { 155 $PolyGon[] = $Pos["X"]; 156 $PolyGon[] = $Pos["Y"]; 157 } 158 159 $Object->drawPolygon($PolyGon, $Settings); 160 161 if ($TextPos == TEXT_POS_RIGHT) { 162 $Object->drawText( 163 $X2 + $TextPadding, 164 ($RightY2 - $RightY1) / 2 + $RightY1, 165 $Label, 166 ["Align" => TEXT_ALIGN_MIDDLELEFT] 167 ); 168 } else { 169 $Object->drawText( 170 $X2, 171 $RightY1 - $TextPadding, 172 $Label, 173 ["Align" => TEXT_ALIGN_BOTTOMRIGHT] 174 ); 175 } 176 $LeftY = $LeftY2; 177 $RightY = $RightY2; 178 } 179 } 180} 181