Skip to content

Commit

Permalink
Make donut_slice_gap option work on 3D donut graph types.
Browse files Browse the repository at this point in the history
  • Loading branch information
goat1000 committed Dec 9, 2021
1 parent b61f1af commit 71b08c4
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 29 deletions.
7 changes: 5 additions & 2 deletions Donut3DGraph.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@ class Donut3DGraph extends Pie3DGraph {

public function __construct($w, $h, array $settings, array $fixed_settings = [])
{
// slice gap is no use on a 3D graph
$fs = [ 'donut_slice_gap' => 0, ];
$fs = [];
// enable flat sides when drawing a gap
if(isset($settings['donut_slice_gap']) && $settings['donut_slice_gap'] > 0)
$fs['draw_flat_sides'] = true;

$fs = array_merge($fs, $fixed_settings);
parent::__construct($w, $h, $settings, $fs);
}
Expand Down
20 changes: 14 additions & 6 deletions DonutGraphTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,10 @@
trait DonutGraphTrait {

/**
* Override the parent to draw doughnut slice
* Returns the outer and inner angle adjustments for the slice gap
*/
protected function getSlice($item, $angle_start, $angle_end, $radius_x,
$radius_y, &$attr, $single_slice, $colour_index)
public function getSliceGap($angle, $ratio)
{
$ratio = min(0.99, max(0.01, $this->getOption('inner_radius')));
$angle = $angle_end - $angle_start;

$gap_angle = $this->getOption('donut_slice_gap');
$outer_a = $inner_a = 0;
if($gap_angle > 0) {
Expand All @@ -41,7 +37,19 @@ protected function getSlice($item, $angle_start, $angle_end, $radius_x,
$inner_a = $outer_a / $ratio;
}
}
return [$outer_a, $inner_a];
}

/**
* Override the parent to draw doughnut slice
*/
protected function getSlice($item, $angle_start, $angle_end, $radius_x,
$radius_y, &$attr, $single_slice, $colour_index)
{
$ratio = min(0.99, max(0.01, $this->getOption('inner_radius')));
$angle = $angle_end - $angle_start;

list($outer_a, $inner_a) = $this->getSliceGap($angle, $ratio);
$x_start = $y_start = $x_end = $y_end = 0;
$angle_start += $this->s_angle;
$angle_end += $this->s_angle;
Expand Down
43 changes: 26 additions & 17 deletions DonutSliceEdge.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
class DonutSliceEdge extends PieSliceEdge {

protected $ratio = 1.0;
protected $outer_a = 0;
protected $inner_a = 0;

/**
* $slice is the slice details array
Expand All @@ -42,6 +44,10 @@ public function __construct(&$graph, $type, $slice, $s_angle)
$start_angle = $slice['angle_start'] + $s_angle;
$end_angle = $slice['angle_end'] + $s_angle;
$ratio = min(0.99, max(0.01, $graph->getOption('inner_radius')));
list($outer_a, $inner_a) = $graph->getSliceGap($end_angle - $start_angle, $ratio);
$this->outer_a = $outer_a;
$this->inner_a = $inner_a;

if(isset($slice['single_slice']) && $slice['single_slice'] &&
!is_numeric($graph->end_angle)) {

Expand Down Expand Up @@ -82,6 +88,8 @@ public function __construct(&$graph, $type, $slice, $s_angle)
// flat edge at a2
$this->a1 = $this->a2;
$this->ratio = $ratio;
$this->outer_a = -$outer_a;
$this->inner_a = -$inner_a;
break;
case 2:
// bottom edge
Expand Down Expand Up @@ -123,9 +131,11 @@ public function __construct(&$graph, $type, $slice, $s_angle)
break;
}

$ac = ($this->a1 + $this->a2) / 2;
$this->x = PieSliceEdge::SCALE * cos($ac);
$this->y = PieSliceEdge::SCALE * sin($ac);
// ignore tiny curves as floating point artifacts
if($type > 1 && abs($this->a1 - $this->a2) < 0.0001)
return;

$this->setupSort();
$this->type = $type;
}

Expand Down Expand Up @@ -184,31 +194,30 @@ public function getInnerRatio()
*/
protected function getFlatPath($angle, $x_centre, $y_centre, $depth)
{
$rx = $this->slice['radius_x'] * cos($angle);
$ry = $this->slice['radius_y'] * sin($angle);
$x1 = $x_centre + $rx;
$y1 = $y_centre + $ry;
$x2 = $x_centre + ($rx * $this->ratio);
$y2 = $y_centre + ($ry * $this->ratio);
$rx1 = $this->slice['radius_x'] * cos($angle + $this->outer_a);
$ry1 = $this->slice['radius_y'] * sin($angle + $this->outer_a);
$rx2 = $this->slice['radius_x'] * $this->ratio * cos($angle + $this->inner_a);
$ry2 = $this->slice['radius_y'] * $this->ratio * sin($angle + $this->inner_a);
$x1 = $x_centre + $rx1;
$y1 = $y_centre + $ry1;
$x2 = $x_centre + $rx2;
$y2 = $y_centre + $ry2;
return new PathData('M', $x2, $y2, 'v', $depth, 'L', $x1, $y1 + $depth,
'v', -$depth, 'z');
return new PathData('M', $x_centre, $y_centre, 'v', $depth, 'L', $x1, $y1,
'v', -$depth, 'z');
}

/**
* Returns the path for the curved edge
*/
protected function getCurvedPath($x_centre, $y_centre, $depth)
{
$d1 = rad2deg($this->a1);
$d2 = rad2deg($this->a2);
$a = $this->ratio < 1.0 ? $this->inner_a : $this->outer_a;
$rx = $this->slice['radius_x'] * $this->ratio;
$ry = $this->slice['radius_y'] * $this->ratio;
$x1 = $x_centre + $rx * cos($this->a1);
$y1 = $y_centre + $ry * sin($this->a1);
$x2 = $x_centre + $rx * cos($this->a2);
$y2 = $y_centre + $ry * sin($this->a2);
$x1 = $x_centre + $rx * cos($this->a1 + $a);
$y1 = $y_centre + $ry * sin($this->a1 + $a);
$x2 = $x_centre + $rx * cos($this->a2 - $a);
$y2 = $y_centre + $ry * sin($this->a2 - $a);
$y2d = $y2 + $depth;

$outer = 0; // edge is never > PI
Expand Down
17 changes: 13 additions & 4 deletions PieSliceEdge.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
class PieSliceEdge {

const SCALE = 2000.0;
public $x;
public $y;
public $slice;

Expand Down Expand Up @@ -98,12 +97,22 @@ public function __construct(&$graph, $type, $slice, $s_angle)
break;
}

$ac = ($this->a1 + $this->a2) / 2;
$this->x = PieSliceEdge::SCALE * cos($ac);
$this->y = PieSliceEdge::SCALE * sin($ac);
$this->setupSort();
$this->type = $type;
}

/**
* Fills in $this->y, for sorting slices by layer depth
*/
protected function setupSort()
{
if($this->a1 < M_PI_2 && $this->a2 > M_PI_2)
$ac = M_PI_2;
else
$ac = ($this->a1 + $this->a2) / 2;
$this->y = PieSliceEdge::SCALE * sin($ac);
}

/**
* Returns the number of edge types this class supports
*/
Expand Down

0 comments on commit 71b08c4

Please sign in to comment.