public function getData($days) { $columns = array(); $key_column = array('type' => 'date', 'title' => ct("Date")); $report_type = $this->report_type; $report_table = $this->report_table; $report_ref_table = $this->report_ref_table; $report_reference = $this->report_reference; $key_prefix = $this->key_prefix; $key = $this->key; $actual_value_key = $this->actual_value_key; $q = db()->prepare("SELECT * FROM performance_reports WHERE report_type=? ORDER BY id DESC LIMIT 30"); $q->execute(array($report_type)); $reports = $q->fetchAll(); if (!$reports) { return render_text($graph, "No report {$report_type} found."); } // construct an array of (date => ) $data = array(); $keys = array(); $last_updated = false; foreach ($reports as $report) { // get all queries $q = db()->prepare("SELECT * FROM {$report_table} AS r " . ($report_ref_table ? "JOIN {$report_ref_table} AS q ON r.{$report_reference}=q.id " : "") . "WHERE report_id=?"); $q->execute(array($report['id'])); $date = date('Y-m-d H:i:s', strtotime($report['created_at'])); $row = array(); while ($query = $q->fetch()) { if (!isset($keys[$query[$key]])) { $keys[$query[$key]] = count($keys); $columns[] = array('type' => 'number', 'title' => $query[$key]); } if ($actual_value_key === null) { if ($query[$key_prefix . '_count'] == 0) { // prevent division by 0 $row[$keys[$query[$key]]] = graph_number_format(0); } else { $row[$keys[$query[$key]]] = graph_number_format($query[$key_prefix . '_time'] / $query[$key_prefix . '_count']); } } else { $row[$keys[$query[$key]]] = graph_number_format($query[$actual_value_key]); } } $data[$date] = $row; $last_updated = max($last_updated, strtotime($report['created_at'])); } // fill in any missing rows, e.g. queries that may not have featured in certain reports foreach ($data as $date => $row) { foreach ($keys as $id) { if (!isset($row[$id])) { $data[$date][$id] = 0; } } } return array('key' => $key_column, 'columns' => $columns, 'data' => $data, 'last_updated' => $last_updated); }
} $offset_left = 0; $nsize = $FLIR['size_pts']; while (($REAL_HEIGHT_BOUNDS['height'] > $FLIR['maxheight'] || $bounds['width'] > $FLIR['maxwidth']) && $nsize > 2) { $nsize -= 0.5; $bounds = bounding_box($FLIR['text'], NULL, $nsize); $REAL_HEIGHT_BOUNDS = $FStyle['realFontHeight'] == 'true' ? bounding_box(HBOUNDS_TEXT, NULL, $nsize) : $bounds; } $FLIR['size_pts'] = $nsize; if (false === @($image = imagecreatetruecolor($bounds['width'], $REAL_HEIGHT_BOUNDS['height']))) { err('COULD_NOT_CREATE'); } gd_alpha(); imagefilledrectangle($image, $offset_left, 0, imagesx($image), imagesy($image), gd_bkg()); imagettftext($image, $FLIR['size_pts'], 0, $bounds['xOffset'], $REAL_HEIGHT_BOUNDS['yOffset'], gd_color(), $FLIR['font'], $FLIR['text']); render_text($bounds); break; case 'spacer': if (false === @($image = imagecreatetruecolor($SPACE_BOUNDS['width'] * $SPACES_COUNT, 1))) { err('COULD_NOT_CREATE'); } imagesavealpha($image, true); imagealphablending($image, false); imagefilledrectangle($image, 0, 0, imagesx($image), imagesy($image), gd_bkg()); break; } if ($FLIR['postscript']) { imagepsfreefont($FLIR['ps']['font']); } if (false !== $image) { switch ($FLIR['output']) {
function imagettftextbox($size_pts, $angle, $left, $top, $color, $font, $raw_text, $max_width, $align = 'left', $lineheight = 1.0) { global $FLIR; $raw_textlines = explode("\n", $raw_text); $formatted_lines = $formatted_widths = array(); $max_values = bounding_box(HBOUNDS_TEXT); $previous_bounds = array('width' => 0); $spaces = ' ' . str_repeat(' ', defined('SPACING_GAP') ? SPACING_GAP : 0); foreach ($raw_textlines as $text) { $bounds = bounding_box($text); if ($bounds['height'] > $max_lineheight) { $max_lineheight = $bounds['height']; } if ($bounds['belowBasepoint'] > $max_baseheight) { $max_baseheight = $bounds['belowBasepoint']; } if ($bounds['xOffset'] > $max_leftoffset) { $max_leftoffset = $bounds['xOffset']; } if ($bounds['yOffset'] > $max_rightoffset) { $max_rightoffset = $bounds['yOffset']; } if ($bounds['width'] < $max_width) { // text doesn't require wrapping $formatted_lines[] = $text; $formatted_widths[$text] = $bounds['width']; } else { // text requires wrapping $words = explode($spaces, trim($text)); $test_line = ''; for ($i = 0; $i < count($words); $i++) { // test words one-by-one to see if they put the width over $prepend = $i == 0 ? '' : $test_line . $spaces; // add space if not the first word $working_line = $prepend . $words[$i]; $bounds = bounding_box($working_line); if ($bounds['width'] > $max_width) { // if working line is too big previous line isn't, use that $formatted_lines[] = $test_line; $formatted_widths[$test_line] = $previous_bounds['width']; $test_line = $words[$i]; $bounds = bounding_box($test_line); } else { // keep adding $test_line = $working_line; } $previous_bounds = $bounds; } if ($test_line != '') { // if words are finished and there is something left in the buffer add it $bounds = bounding_box($test_line); $formatted_lines[] = $test_line; $formatted_widths[$test_line] = $bounds['width']; } } } $max_lineheight = $max_values['height'] * $lineheight; $image = imagecreatetruecolor($max_width, $max_lineheight * (count($formatted_lines) - 1) + $max_values['yOffset'] + $max_values['belowBasepoint']); gd_alpha($image); imagefilledrectangle($image, 0, 0, imagesx($image), imagesy($image), gd_bkg($image)); for ($i = 0; $i < count($formatted_lines); $i++) { if ($i == 0) { $offset_top = $max_values['yOffset']; } else { $offset_top = $max_lineheight * $i + $max_values['yOffset']; } switch (strtolower($align)) { default: case 'left': $offset_left = 0; break; case 'center': $offset_left = ($max_width - $formatted_widths[$formatted_lines[$i]]) / 2; break; case 'right': $offset_left = $max_width - $formatted_widths[$formatted_lines[$i]] - 1; break; } // imagettftext($image, $size_pts, $angle, $offset_left, $offset_top, gd_color($image), $font, $formatted_lines[$i]); $bounds = array('xOffset' => $offset_left, 'yOffset' => $offset_top); render_text($bounds, $formatted_lines[$i], $image, $bounds); } return $image; }
/** * @param $report_ref_table can be null * @param $report_reference can be null * @param $actual_value_key if null, use {$key_prefix}_time/{$key_prefix}_count; otherwise, use this key */ function render_metrics_graph($graph, $report_type, $report_table, $report_ref_table, $report_reference, $key_prefix, $key = null, $actual_value_key = null) { if ($key == null) { $key = $key_prefix; } if (!is_admin()) { return render_text(t("This graph is for administrators only.")); } $q = db()->prepare("SELECT * FROM performance_reports WHERE report_type=? ORDER BY id DESC LIMIT 30"); $q->execute(array($report_type)); $reports = $q->fetchAll(); if (!$reports) { return render_text($graph, "No report {$report_type} found."); } // construct an array of (date => ) $data = array(); $data[0] = array(t("Date")); $keys = array(); $graph['last_updated'] = 0; foreach ($reports as $report) { // get all queries $q = db()->prepare("SELECT * FROM {$report_table} AS r " . ($report_ref_table ? "JOIN {$report_ref_table} AS q ON r.{$report_reference}=q.id " : "") . "WHERE report_id=?"); $q->execute(array($report['id'])); $date = date('Y-m-d H:i:s', strtotime($report['created_at'])); $row = array('new Date(' . date('Y, n-1, j, H, i, s', strtotime($report['created_at'])) . ')'); while ($query = $q->fetch()) { if (!isset($keys[$query[$key]])) { $keys[$query[$key]] = count($keys) + 1; $data[0][] = array("title" => $query[$key]); } if ($actual_value_key === null) { $row[$keys[$query[$key]]] = graph_number_format($query[$key_prefix . '_time'] / $query[$key_prefix . '_count']); } else { $row[$keys[$query[$key]]] = graph_number_format($query[$actual_value_key]); } } $data[$date] = $row; $graph['last_updated'] = max($graph['last_updated'], strtotime($report['created_at'])); } // fill in any missing rows, e.g. queries that may not have featured in certain reports foreach ($data as $date => $row) { if ($date === 0) { continue; } foreach ($keys as $id) { if (!isset($row[$id])) { $data[$date][$id] = 0; } } } if (count($data) > 1) { render_linegraph_date($graph, array_values($data)); } else { render_text($graph, t("There is not yet any historical data for these statistics.")); } }