public function __construct(&$result_file)
 {
     $columns = array();
     $hw = array();
     $sw = array();
     foreach ($result_file->get_systems() as $system) {
         $columns[] = $system->get_identifier();
         $hw[] = $system->get_hardware();
         $sw[] = $system->get_software();
     }
     $rows = array();
     $table_data = array();
     pts_result_file_analyzer::system_components_to_table($table_data, $columns, $rows, $hw);
     pts_result_file_analyzer::system_components_to_table($table_data, $columns, $rows, $sw);
     pts_result_file_analyzer::compact_result_table_data($table_data, $columns, true);
     // TODO: see if this true value works fine but if rendering starts messing up, disable it
     if (defined('OPENBENCHMARKING_IDS')) {
         foreach ($columns as &$column) {
             $column = new pts_graph_ir_value($column);
             $column->set_attribute('href', 'http://openbenchmarking.org/system/' . OPENBENCHMARKING_IDS . '/' . $column);
         }
     }
     parent::__construct($rows, $columns, $table_data, $result_file);
     $this->i['identifier_size'] *= 0.8;
     $this->column_heading_vertical = false;
     $this->graph_title = $result_file->get_title();
     if (!defined('PHOROMATIC_EXPORT_VIEWER')) {
         pts_render::report_system_notes_to_table($result_file, $this);
     }
 }
 public function render_graph_start()
 {
     // Needs to be at least 86px wide for the PTS logo
     $this->i['left_start'] = ceil(max(86, $this->text_string_width($this->longest_row_identifier, $this->i['identifier_size']) * 1.1 + 12));
     if ($this->column_heading_vertical) {
         $top_identifier_height = round($this->text_string_width($this->longest_column_identifier, $this->i['identifier_size']) * 1.1) + 12;
         $table_identifier_width = $this->text_string_height($this->longest_column_identifier, $this->i['identifier_size']);
     } else {
         $top_identifier_height = $this->text_string_height($this->longest_column_identifier, $this->i['identifier_size']) + 8;
         $table_identifier_width = round($this->text_string_width($this->longest_column_identifier, $this->i['identifier_size']) * 1.1) + 8;
     }
     // Needs to be at least 46px tall for the PTS logo
     $top_identifier_height = max($top_identifier_height, 48);
     if (defined('PHOROMATIC_TRACKER') || $this->is_multi_way) {
         $extra_heading_height = round($this->text_string_height($this->longest_column_identifier, self::$c['size']['headers']) * 1.25);
         $top_identifier_height += 6 + $extra_heading_height;
     }
     $this->i['top_heading_height'] = 8;
     if ($this->graph_title != null) {
         $this->i['top_heading_height'] += round(self::$c['size']['headers'] + count($this->graph_sub_titles) * (self::$c['size']['sub_headers'] + 4));
     }
     $table_max_value_width = ceil($this->text_string_width($this->i['graph_max_value'], $this->i['identifier_size']) * 1.02) + 2;
     $table_item_width = max($table_max_value_width, $table_identifier_width) + 2;
     $table_width = max($table_item_width * count($this->columns), floor($this->text_string_width($this->graph_title, 12) / $table_item_width) * $table_item_width);
     //$table_width = $table_item_width * count($this->columns);
     $table_line_height = round($this->text_string_height($this->i['graph_max_value'], $this->i['identifier_size']) + 8);
     $table_line_height_half = round($table_line_height / 2);
     $table_height = $table_line_height * count($this->rows);
     $table_proper_height = $this->i['top_heading_height'] + $table_height + $top_identifier_height;
     $this->i['graph_width'] = $table_width + $this->i['left_start'];
     $this->i['graph_height'] = round($table_proper_height + $table_line_height);
     if (!empty($this->i['notes'])) {
         $this->i['graph_height'] += $this->note_display_height();
     }
     // Do the actual work
     $this->render_graph_pre_init();
     $this->render_graph_init();
     $this->svg_dom->add_element('rect', array('x' => 1, 'y' => 1, 'width' => $this->i['graph_width'] - 1, 'height' => $this->i['graph_height'] - 1, 'fill' => self::$c['color']['background'], 'stroke' => self::$c['color']['border'], 'stroke-width' => 1));
     // Start drawing
     if ($this->i['left_start'] >= 170 && $top_identifier_height >= 90) {
         $this->svg_dom->add_element('image', array('http_link' => 'http://www.phoronix-test-suite.com/', 'xlink:href' => 'https://openbenchmarking.org/static/images/pts-160x83.png', 'x' => round($this->i['left_start'] / 2 - 80), 'y' => round($top_identifier_height / 2 - 41.5 + $this->i['top_heading_height']), 'width' => 160, 'height' => 83));
     } else {
         $this->svg_dom->add_element('image', array('http_link' => 'http://www.phoronix-test-suite.com/', 'xlink:href' => 'https://openbenchmarking.org/static/images/pts-80x42.png', 'x' => round($this->i['left_start'] / 2 - 40), 'y' => round($top_identifier_height / 2 - 21 + $this->i['top_heading_height']), 'width' => 80, 'height' => 42));
     }
     // Draw the vertical table lines
     $v = round(($top_identifier_height + $table_height) / 2 + $this->i['top_heading_height']);
     $table_columns_end = $this->i['left_start'] + $table_item_width * count($this->columns);
     $this->svg_dom->draw_svg_line($this->i['left_start'], $v, $table_columns_end, $v, self::$c['color']['body'], $table_height + $top_identifier_height, array('stroke-dasharray' => $table_item_width . ',' . $table_item_width));
     if ($table_columns_end < $this->i['graph_width']) {
         $this->svg_dom->add_element('rect', array('x' => $table_columns_end, 'y' => $this->i['top_heading_height'], 'width' => $this->i['graph_width'] - $table_columns_end, 'height' => $table_height + $top_identifier_height, 'fill' => self::$c['color']['body_light']));
     }
     // Background horizontal
     $this->svg_dom->draw_svg_line(round($table_columns_end / 2), $top_identifier_height + $this->i['top_heading_height'], round($table_columns_end / 2), $table_proper_height, self::$c['color']['body_light'], $table_columns_end, array('stroke-dasharray' => $table_line_height . ',' . $table_line_height));
     // Draw the borders
     $this->svg_dom->draw_svg_line($this->i['left_start'], $v, $table_columns_end + ($table_columns_end < $this->i['graph_width'] ? $table_item_width : 0), $v, self::$c['color']['border'], $table_height + $top_identifier_height, array('stroke-dasharray' => '1,' . ($table_item_width - 1)));
     // Heading
     if ($this->graph_title != null) {
         $this->svg_dom->add_element('rect', array('x' => 1, 'y' => 1, 'width' => $this->i['graph_width'] - 2, 'height' => $this->i['top_heading_height'], 'fill' => self::$c['color']['main_headers']));
         $this->svg_dom->add_text_element($this->graph_title, array('x' => 5, 'y' => self::$c['size']['headers'] + 2, 'font-size' => self::$c['size']['headers'], 'fill' => self::$c['color']['background'], 'text-anchor' => 'start'));
         foreach ($this->graph_sub_titles as $i => $sub_title) {
             $vertical_offset = 16 + self::$c['size']['headers'] + $i * self::$c['size']['sub_headers'];
             $this->svg_dom->add_text_element($sub_title, array('x' => 5, 'y' => $vertical_offset, 'font-size' => self::$c['size']['sub_headers'], 'fill' => self::$c['color']['background'], 'text-anchor' => 'start'));
         }
         $this->svg_dom->draw_svg_line(1, $this->i['top_heading_height'], $this->i['graph_width'] - 1, $this->i['top_heading_height'], self::$c['color']['border'], 1);
     }
     // Write the rows
     $row = 1;
     $g = $this->svg_dom->make_g(array('font-size' => $this->i['identifier_size'], 'font-weight' => 'bold', 'text-anchor' => 'end', 'fill' => self::$c['color']['text']));
     foreach ($this->rows as $i => $row_string) {
         if ($row_string instanceof pts_graph_ir_value == false) {
             $row_string = new pts_graph_ir_value($row_string);
         }
         $v = round($top_identifier_height + $this->i['top_heading_height'] + $row * $table_line_height - 4);
         $r = array('x' => $this->i['left_start'] - 2, 'y' => $v, 'fill' => self::$c['color']['text'], 'xlink:href' => $row_string->get_attribute('href'));
         if ($row_string->get_attribute('alert')) {
             $r['fill'] = self::$c['color']['alert'];
         }
         $this->svg_dom->add_text_element($row_string, $r, $g);
         $row++;
     }
     // Write the identifiers
     if (defined('PHOROMATIC_TRACKER') || $this->is_multi_way) {
         $last_identifier = null;
         $last_changed_col = 0;
         $show_keys = array_keys($this->table_data);
         array_push($show_keys, 'Temp: Temp');
         $g1 = $this->svg_dom->make_g(array());
         $g2 = $this->svg_dom->make_g(array('font-size' => self::$c['size']['axis_headers'], 'fill' => self::$c['color']['background'], 'font-weight' => 'bold', 'text-anchor' => 'middle'));
         foreach ($show_keys as $current_col => $system_identifier) {
             $identifier = pts_strings::colon_explode($system_identifier);
             if (isset($identifier[0]) && $identifier[0] != $last_identifier) {
                 if ($current_col == $last_changed_col) {
                     $last_identifier = $identifier[0];
                     continue;
                 }
                 $paint_color = $this->get_paint_color($identifier[0]);
                 if ($this->i['top_heading_height'] > 0) {
                     $extra_heading_height = $this->i['top_heading_height'];
                 }
                 $x = $this->i['left_start'] + 1 + $last_changed_col * $table_item_width;
                 $x_end = $this->i['left_start'] + $last_changed_col * $table_item_width + $table_item_width * ($current_col - $last_changed_col);
                 $this->svg_dom->add_element('rect', array('x' => $x, 'y' => 0, 'width' => $table_item_width * ($current_col - $last_changed_col) - 2, 'height' => $extra_heading_height, 'fill' => $paint_color), $g1);
                 if ($identifier[0] != 'Temp') {
                     $this->svg_dom->draw_svg_line($this->i['left_start'] + $current_col * $table_item_width + 1, 1, $this->i['left_start'] + $current_col * $table_item_width + 1, $table_proper_height, $paint_color, 1);
                 }
                 //$x = $this->i['left_start'] + ($last_changed_col * $table_item_width) + ($this->i['left_start'] + ($current_col * $table_item_width) - $this->i['left_start'] + ($last_changed_col * $table_item_width));
                 $this->svg_dom->add_text_element($last_identifier, array('x' => round($x + ($x_end - $x) / 2), 'y' => self::$c['size']['axis_headers'] + 4), $g2);
                 $last_identifier = $identifier[0];
                 $last_changed_col = $current_col;
             }
         }
     }
     $table_identifier_offset = $table_item_width / 2 + $table_identifier_width / 2 - 1;
     $g_opts = array('font-size' => $this->i['identifier_size'], 'fill' => self::$c['color']['text'], 'font-weight' => 'bold');
     if ($this->column_heading_vertical) {
         $g_opts['text-anchor'] = 'end';
     } else {
         $g_opts['text-anchor'] = 'middle';
         $g_opts['dominant-baseline'] = 'text-before-edge';
     }
     $g = $this->svg_dom->make_g($g_opts);
     foreach ($this->columns as $i => $col_string) {
         if ($this->column_heading_vertical) {
             $x = $this->i['left_start'] + $i * $table_item_width + $table_identifier_offset;
             $y = $this->i['top_heading_height'] + $top_identifier_height - 4;
             $this->svg_dom->add_text_element($col_string, array('x' => $x, 'y' => $y, 'transform' => 'rotate(90 ' . $x . ' ' . $y . ')'), $g);
         } else {
             $x = $this->i['left_start'] + $i * $table_item_width + $table_item_width / 2;
             $y = $this->i['top_heading_height'] + $top_identifier_height / 2;
             $this->svg_dom->add_text_element($col_string, array('x' => $x, 'y' => $y), $g);
         }
     }
     // Write the columns
     $g_background = $this->svg_dom->make_g(array());
     $g = $this->svg_dom->make_g(array('text-anchor' => 'middle', 'font-size' => $this->i['identifier_size']));
     foreach ($this->table_data as $index => &$table_values) {
         if (!is_array($table_values)) {
             // TODO: determine why sometimes $table_values is empty or not an array
             continue;
         }
         if ($this->is_multi_way && ($c = strpos($index, ':')) !== false) {
             $index = substr($index, $c + 1);
         }
         $col = array_search(strval($index), $this->columns);
         if ($col === false) {
             continue;
         } else {
             // unset this since it shouldn't be needed anymore and will then wipe out it from where multiple results have same name
             unset($this->columns[$col]);
         }
         foreach ($table_values as $i => &$result_table_value) {
             $row = $i - 1;
             // if using $row, the alignment may be off sometimes
             $hover = array();
             $text_color = self::$c['color']['text'];
             $bold = false;
             if ($result_table_value == null) {
                 continue;
             }
             if ($result_table_value instanceof pts_graph_ir_value) {
                 if (($t = $result_table_value->get_attribute('std_percent')) > 0) {
                     array_push($hover, 'STD Dev: ' . $t . '%');
                 }
                 if (($t = $result_table_value->get_attribute('std_error')) != 0) {
                     array_push($hover, ' STD Error: ' . $t);
                 }
                 if (defined('PHOROMATIC_TRACKER') && ($t = $result_table_value->get_attribute('delta')) != 0) {
                     $bold = true;
                     $text_color = $t < 0 ? self::$c['color']['alert'] : self::$c['color']['headers'];
                     array_push($hover, ' Change: ' . pts_math::set_precision(100 * $t, 2) . '%');
                 } else {
                     if ($result_table_value->get_attribute('highlight') == true) {
                         $text_color = self::$c['color']['highlight'];
                     } else {
                         if ($result_table_value->get_attribute('alert') == true) {
                             $text_color = self::$c['color']['alert'];
                         }
                     }
                 }
                 $value = $result_table_value->get_value();
                 $spans_col = $result_table_value->get_attribute('spans_col');
             } else {
                 $value = $result_table_value;
                 $spans_col = 1;
             }
             $left_bounds = $this->i['left_start'] + $col * $table_item_width;
             $right_bounds = $this->i['left_start'] + ($col + max(1, $spans_col)) * $table_item_width;
             if ($spans_col > 1) {
                 if ($col == 1) {
                     $background_paint = $i % 2 == 1 ? self::$c['color']['background'] : self::$c['color']['body'];
                 } else {
                     $background_paint = $i % 2 == 0 ? self::$c['color']['body_light'] : self::$c['color']['body'];
                 }
                 $y = round($this->i['top_heading_height'] + $top_identifier_height + ($row + 1) * $table_line_height);
                 $this->svg_dom->add_element('rect', array('x' => $left_bounds, 'y' => $y + 1, 'width' => $right_bounds - $left_bounds, 'height' => $table_line_height, 'fill' => $background_paint), $g_background);
             }
             $x = $left_bounds + ($right_bounds - $left_bounds) / 2;
             $this->svg_dom->add_text_element($result_table_value, array('x' => $x, 'y' => round($this->i['top_heading_height'] + $top_identifier_height + ($row + 2) * $table_line_height - 3), 'fill' => $text_color, 'xlink:title' => implode('; ', $hover), 'xlink:href' => $result_table_value->get_attribute('href')), $g);
             //$row++;
         }
     }
     //$this->svg_dom->draw_svg_line(($table_columns_end / 2), ($top_identifier_height + $this->i['top_heading_height']), round($table_columns_end / 2), $this->i['graph_height'], self::$c['color']['border'], $table_columns_end, array('stroke-dasharray' => '1,' . ($table_line_height - 1)));
     $this->svg_dom->draw_svg_line(round($table_columns_end / 2), $top_identifier_height + $this->i['top_heading_height'], round($table_columns_end / 2), $table_proper_height, self::$c['color']['body_light'], $table_columns_end, array('stroke-dasharray' => 1 . ',' . ($table_line_height - 1)));
     // Bottom part
     $this->svg_dom->add_element('rect', array('x' => 0, 'y' => $table_proper_height, 'width' => $this->i['graph_width'], 'height' => $this->i['graph_height'] - $table_proper_height, 'fill' => self::$c['color']['headers']));
     $this->svg_dom->add_text_element(self::$c['text']['watermark'], array('x' => $this->i['graph_width'] - 2, 'y' => $this->i['graph_height'] - 3, 'font-size' => $this->i['identifier_size'], 'fill' => self::$c['color']['body_text'], 'text-anchor' => 'end', 'xlink:show' => 'new', 'xlink:href' => self::$c['text']['watermark_url']));
     if (isset($this->d['link_alternate_view']) && $this->d['link_alternate_view']) {
         $this->svg_dom->add_text_element(0, array('x' => 6, 'y' => $this->i['graph_height'] - 3, 'font-size' => 7, 'fill' => self::$c['color']['background'], 'text-anchor' => 'start', 'xlink:show' => 'new', 'xlink:href' => $this->d['link_alternate_view'], 'show' => 'replace', 'font-weight' => 'bold'));
     }
     if (!empty($this->i['notes'])) {
         $estimated_height = 0;
         $previous_section = null;
         $g = $this->svg_dom->make_g(array('fill' => self::$c['color']['background'], 'text-anchor' => 'start'));
         foreach ($this->i['notes'] as $i => $note_r) {
             if ($note_r['section'] != null && $note_r['section'] !== $previous_section) {
                 $estimated_height += 2;
                 $this->svg_dom->add_textarea_element($note_r['section'] . ' Details', array('x' => 6, 'y' => $table_proper_height + $table_line_height + $estimated_height, 'xlink:title' => $note_r['hover-title'], 'style' => 'font-weight: bold', 'fill' => self::$c['color']['background'], 'font-size' => self::$c['size']['key'] - 1), $estimated_height, $g);
                 $estimated_height += 2;
                 $previous_section = $note_r['section'];
             }
             $this->svg_dom->add_textarea_element('- ' . $note_r['note'], array('x' => 6, 'y' => $table_proper_height + $table_line_height + $estimated_height, 'xlink:title' => $note_r['hover-title'], 'fill' => self::$c['color']['background'], 'font-size' => self::$c['size']['key'] - 1), $estimated_height, $g);
         }
     }
     $this->rendered_rows = $row;
 }
 public static function system_value_to_ir_value($value, $index)
 {
     // TODO XXX: Move this logic off to OpenBenchmarking.org script
     /*
     !in_array($index, array('Memory', 'System Memory', 'Desktop', 'Screen Resolution', 'System Layer')) &&
     	$search_break_characters = array('@', '(', '/', '+', '[', '<', '*', '"');
     	for($i = 0, $x = strlen($value); $i < $x; $i++)
     	{
     		if(in_array($value[$i], $search_break_characters))
     		{
     			$value = substr($value, 0, $i);
     			break;
     		}
     	}
     */
     $ir = new pts_graph_ir_value($value);
     if ($value != 'Unknown' && $value != null) {
         $ir->set_attribute('href', 'http://openbenchmarking.org/s/' . $value);
     }
     return $ir;
 }