1<?php 2 3require_once(dirname(__FILE__).'/../../lib/plugins.php'); 4require_once(dirname(__FILE__).'/../../lib/project_file.php'); 5require_once(dirname(__FILE__).'/../file/plot_dependency.php'); 6require_once(dirname(__FILE__).'/../../pchart/pchart/pchart.php'); 7require_once(dirname(__FILE__).'/../../pchart/pchart/pdata.php'); 8 9class projects_plugin_plot extends MakeRule { 10 /** 11 * The name of the rule, a human readable string, a unique identifier 12 */ 13 public function name() { return "Plot"; } 14 15 /** 16 * whether this rule can make a given target 17 */ 18 public function can_handle($project, $file) { 19 if (!has_extension($file->name(), '.png')) return false; 20 $plot = $this->replace_extension($file->name(), '.png', '.plot'); 21 return $project->file($plot) != NULL; 22 } 23 24 /** 25 * returns a project file that can make $name 26 */ 27 public function handle($project, $file) { 28 $plot = $this->replace_extension($file->name(), '.png', '.plot'); 29 $source = new PlotDefinition(array('type' => SOURCE, 30 'name' => $plot)); 31 $source->add_content(file_get_contents($project->path() . $plot)); 32 $target = new PlotTarget($project, $file, $source); 33 return $target; 34 } 35 36} 37 38class PlotTarget extends ProjectGenerated { 39 private $plot = NULL; 40 public function __construct($project, $file, $source) { 41 $deps = $file->dependency(); 42 if (!in_array($source->name(), $deps)) $deps[] = $source->name(); 43 $this->deps = $deps; 44 $this->name = $file->name(); 45 $this->plot = $source; 46 } 47 48 public function makable() { return true; } 49 50 public function make($working_path) { 51 // This will import the file http://my.domain.com/myData.csv using each column as a serie 52 if (!$this->plot->valid()) { 53 $file = $this->plot->name(); 54 $error = $this->plot->error(); 55 $this->log($working_path, "Plot file $file is invalid: $error"); 56 return 1; 57 } 58 $data = new pData(); 59 $columns = array(); 60 $all_columns = array(); 61 62 $x_column = $this->plot->property('x_column') - 1; 63 if ($x_column === NULL) $x_column = 0; 64 $data_file = $this->plot->data_property('name'); 65 $deliminator = $this->plot->data_property('deliminator'); 66 $has_header = $this->plot->data_property('header') == 'yes'; 67 foreach ($this->plot->columns() as $column => $name) { 68 if ($column != $x_column + 1) $columns[] = $column - 1; 69 $all_columns[] = $column - 1; 70 } 71 $data->ImportFromCSV($working_path . $data_file, 72 $deliminator, $all_columns, $has_header); 73 foreach ($columns as $column) { 74 $name = $this->plot->column($column + 1); 75 $data->AddSerie('Serie' . $column); 76 $data->SetSerieName($name, "Serie" . $column); 77 } 78 $max_col = -1; 79 $max_val = NULL; 80 foreach ($data->GetData() as $record) { 81 foreach ($columns as $column) { 82 $point = $record['Serie' .$column]; 83 if ($max_val === NULL || $point > $max_val) { 84 $max_val = $point; 85 $max_col = $column; 86 } 87 } 88 } 89 $x_label = $this->plot->axis_property('x', 'label'); 90 if ($x_label) 91 $data->SetXAxisName($x_label); 92 else 93 $data->SetXAxisName($this->plot->column($x_column + 1)); 94 $x_unit = $this->plot->axis_property('x', 'unit'); 95 if ($x_unit) $data->SetXAxisUnit($x_unit); 96 $y_label = $this->plot->axis_property('y', 'label'); 97 reset($columns); 98 if ($y_label) 99 $data->SetYAxisName($y_label); 100 else 101 $data->SetYAxisName($this->plot->column(current($columns) + 1)); 102 $y_unit = $this->plot->axis_property('y', 'unit'); 103 if ($y_unit) $data->SetyAxisUnit($y_unit); 104 105 $width = $this->plot->property('width'); 106 if (!$width) $width = 640; 107 $height = $this->plot->property('height'); 108 if (!$height) $height = 480; 109 $plot = new pChart($width, $height); 110 $font_name = $this->plot->property('font-name'); 111 if (!$font_name) $font_name = 'tahoma.ttf'; 112 $font_name = 'lib/plugins/projects/pchart/fonts/' . $font_name; 113 $font_size = $this->plot->property('font_size'); 114 if (!$font_size) $font_size = 12; 115 $plot->setFontProperties($font_name, $font_size); 116 $h = $font_size + 10; 117 $left_margin = 0; 118 foreach ($data->GetData() as $record) { 119 $position = imageftbbox($font_size, 0, $font_name, 120 $record['Serie' . $max_col]); 121 $text_width = $position[2] - $position[0]; 122 if ($text_width > $left_margin) $left_margin = $text_width; 123 } 124 $left_margin += 2 * $h; 125 $plot->setGraphArea($left_margin, 2 * $h, $width - $h, $height - 2 * $h); 126 $background = $this->plot->property('background'); 127 if (!$background) 128 $background = array('R' => 255, 'G' => 255, 'B' => 255); 129 else $background = html_color_to_RGB($background); 130 $plot->drawGraphArea($background['R'], $background['G'], 131 $background['B']); 132 // pick the largest scale 133 $plot->drawXYScale($data->GetData(), $data->GetDataDescription(), 134 'Serie' . $max_col, 'Serie' . $x_column, 135 0, 0, 0, TRUE, 0, 0); 136 $line_no = 0; 137 $colors = array(); 138 foreach ($columns as $column) { 139 $name = $this->plot->column($column + 1); 140 $style = $this->plot->line_style($name, 'style'); 141 $line_color = $this->plot->line_style($name, 'color'); 142 if (!$line_color) 143 $colors[$name] = array('R' => 0, 'G' => 0, 'B' => 0); 144 else $colors[$name] = html_color_to_RGB($line_color); 145 $plot->setColorPalette($line_no, $colors[$name]['R'], 146 $colors[$name]['G'], $colors[$name]['B']); 147 if (!$style || $style == 'line' || $style == 'both') { 148 $line_width = $this->plot->line_style($name, 'width'); 149 if (!$line_width) $line_width = 1; 150 $dot_size = $this->plot->line_style($name, 'dot-size'); 151 if (!$dot_size) $dot_size = 0; 152 $plot->setLineStyle($line_width, $dot_size); 153 $plot->drawXYGraph($data->GetData(), 154 $data->GetDataDescription(), 155 'Serie' . $column, 'Serie' . $x_column, $line_no); 156 } 157 if ($style == 'point' || $style == 'both') { 158 $radius = $this->plot->line_style($name, 'radius'); 159 if (!$radius) $radius = 5; 160 $plot->drawXYPlotGraph($data->GetData(), 161 $data->GetDataDescription(), 162 'Serie' . $column, 'Serie' . $x_column, $line_no, 163 $radius, $radius - 2); 164 } 165 $line_no++; 166 } 167 168 $title = $this->plot->property('title'); 169 170 foreach ($columns as $column) 171 $data->removeSerie('Serie' . $column); 172 $in_legend = array(); 173 $description = $data->GetDataDescription(); 174 $description['Description'] = array(); 175 $palette_id = 0; 176 foreach ($columns as $column) { 177 $name = $this->plot->column($column + 1); 178 if (in_array($name, $in_legend)) continue; 179 $in_legend[] = $name; 180 $description['Description']['Serie' . $column] = $name; 181 $plot->setColorPalette($palette_id, $colors[$name]['R'], 182 $colors[$name]['G'], $colors[$name]['B']); 183 ++$palette_id; 184 } 185 $legend_box_size =$plot->getLegendBoxSize($description); 186 $legend_position = $this->plot->property('legend-position'); 187 if (!$legend_position) $legend_position = 'top-left'; 188 switch ($legend_position) { 189 case 'top-left': 190 $legend_left = 0; 191 $legend_top = 0; 192 break; 193 case 'top': 194 $legend_left = ($width - $h - $left_margin - $legend_box_size[0]) / 2; 195 $legend_top = 0; 196 break; 197 case 'top-right': 198 $legend_left = $width - $left_margin - $h - $legend_box_size[0]; 199 $legend_top = 0; 200 break; 201 case 'left': 202 $legend_left = 0; 203 $legend_top = ($height - 4 * $h - $legend_box_size[1]) / 2; 204 break; 205 case 'center': 206 $legend_left = ($width - $h - $left_margin - $legend_box_size[0]) / 2; 207 $legend_top = ($height - 4 * $h - $legend_box_size[1]) / 2; 208 break; 209 case 'right': 210 $legend_left = $width - $left_margin - $h - $legend_box_size[0]; 211 $legend_top = ($height - 4 * $h - $legend_box_size[1]) / 2; 212 break; 213 case 'bottom-left': 214 $legend_left = 0; 215 $legend_top = $height - 4 * $h - $legend_box_size[1]; 216 break; 217 case 'bottom': 218 $legend_left = ($width - $h - $left_margin - $legend_box_size[0]) / 2; 219 $legend_top = $height - 4 * $h - $legend_box_size[1]; 220 break; 221 case 'bottom-right': 222 $legend_left = $width - $left_margin - $h - $legend_box_size[0]; 223 $legend_top = $height - 4 * $h - $legend_box_size[1]; 224 break; 225 } 226 $plot->drawLegend($left_margin + $legend_left, 2 * $h + $legend_top, $description, 227 255, 255, 255, 100, 100, 100, 0, 0, 0, true); 228 $plot->drawTitle($h, 0, $title, 0, 0, 0, $width-$h, $h * 2, 100); 229 $plot->Render($this->path($working_path)); 230 231 $file_name =$this->plot->name(); 232 $plot_name =$this->name(); 233 $this->log($working_path, "Successfully plotted $file_name as $plot_name\ntitle: $title\n"); 234 return 0; 235 } 236} 237 238?>