Skip to content

Loading…

changes made to front page graph for mobeta fixes bug 771116 #788

Merged
merged 1 commit into from

2 participants

@ghost

adrian r?

@lonnen
Mozilla member

no major errors in the vm. r+ so we can get it in on c-s-d

@lonnen lonnen merged commit 8a03a19 into mozilla:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
View
3 webapp-php/application/config/routes.php-dist
@@ -12,6 +12,9 @@ $config['_default'] =
$config['products/([0-9a-zA-Z.]+)'] =
'products/index/$1';
+$config['/products/json_data'] =
+ 'products/json_data';
+
$config['products/([0-9a-zA-Z.]+)/versions/(.*)'] =
'products/index/$1/$2';
View
39 webapp-php/application/controllers/products.php
@@ -97,11 +97,13 @@ private function _determineDuration()
/**
* Determine the starting date used in a web service call.
*
+ * @param string the selected or duration in the format 3, 7 or 14
* @return string Y-M-D
*/
- private function _determineDateStart()
+ private function _determineDateStart($selected_duration=null)
{
- return date('Y-m-d', mktime(0, 0, 0, date("m"), date("d")-($this->duration+1), date("Y")));
+ ($selected_duration ? $selected_duration : $this->duration);
+ return date('Y-m-d', mktime(0, 0, 0, date("m"), date("d")-($selected_duration+1), date("Y")));
}
/**
@@ -445,6 +447,39 @@ private function _versionSelected($product, $version)
}
/**
+ * Handles front-end Ajax calls and returns a JSON encoded object with the data for the
+ * frontpage graph.
+ *
+ * @access public
+ * @return object JSON encoded object
+ */
+ public function json_data()
+ {
+ $graph_params = array('product' => '', 'version' => '', 'date_range_type' => 'report', 'duration' => '7');
+ $params = $this->getRequestParameters($graph_params);
+
+ $date_start = $this->_determineDateStart($params['duration']);
+ $date_end = $this->_determineDateEnd();
+ $date_range_type = $params['date_range_type'];
+ $i = 0;
+
+ if (empty($params['version'])) {
+ foreach($this->featured_versions as $featured_version) {
+ $daily_versions[] = $featured_version->version;
+ $i++;
+ }
+ $versions = implode("+", $daily_versions);
+ } else {
+ $versions = $params['version'];
+ }
+
+ $results = $this->daily_model->getCrashesByADU($params['product'], $versions, $date_start, $date_end, $date_range_type);
+ $graph_data = $results;
+
+ echo json_encode($graph_data); exit; // We can halt processing here.
+ }
+
+ /**
* Display the dashboard for a product or a product/version combination.
*
* We're running all products and versions through this method in order to verify that they exist.
View
102 webapp-php/application/models/daily.php
@@ -487,6 +487,108 @@ private function formatADUDetailsByReportTypeURL ($product, $versions, $report_t
return $this->formatURL("/adu/byday/details/p/", $product, $versions, $rt, $operating_systems, $start_date, $end_date);
}
+ /**
+ * Build data object for front page graph.
+ *
+ * @access private
+ * @param string The start date for this product YYYY-MM-DD
+ * @param string The end date for this product YYYY-MM-DD
+ * @param object The individual items from which we extract the ratios for the graph
+ * @return array The compiled data for the front page graph
+ */
+ private function _buidDataObjectForGraph($date_start=null, $date_end=null, $response_items=null)
+ {
+ $count = count(get_object_vars($response_items));
+ $counter = 1;
+
+ $data = array(
+ 'startDate' => $date_start,
+ 'endDate' => $date_end,
+ 'count' => $count,
+ );
+
+ foreach ($response_items as $version => $version_data) {
+ if ($counter <= $count) {
+ $key_ratio = 'ratio' . $counter;
+ $key_item = 'item' . $counter;
+ $data[$key_item] = $version;
+
+ $data[$key_ratio] = array();
+ $version_data_array = array();
+
+ foreach ($version_data as $item) {
+ array_push($version_data_array, $item);
+ }
+
+ usort($version_data_array, function ($a, $b) {
+ return ($a->date < $b->date) ? -1 : 1;
+ });
+
+ foreach ($version_data_array as $details) {
+ array_push($data[$key_ratio], array(strtotime($details->date) * 1000, $details->crash_hadu));
+ }
+ }
+ $counter++;
+ }
+ return $data;
+ }
+
+ /**
+ * Build the service URI from the paramters passed and returns the URI with
+ * all values rawurlencoded.
+ *
+ * @param array url parameters to append and encode
+ * @param string the main api entry point ex. crashes
+ * @return string service URI with all values encoded
+ */
+ public function buildURI($params, $apiEntry)
+ {
+ $separator = "/";
+ $host = Kohana::config('webserviceclient.socorro_hostname');
+ $apiData = array(
+ $host,
+ $apiEntry
+ );
+
+ foreach ($params as $key => $value) {
+ $apiData[] = $key;
+ $apiData[] = (is_array($value) ? $this->encodeArray($value) : rawurlencode($value));
+ }
+
+ $apiData[] = ''; // Trick to have the closing '/'
+
+ return implode($separator, $apiData);
+ }
+
+ /**
+ * Fetch records for active daily users.
+ *
+ * @access public
+ * @param string The product name (e.g. 'Camino', 'Firefox', 'Seamonkey, 'Thunderbird')
+ * @param string The versions for this product
+ * @param string The start date for this product YYYY-MM-DD
+ * @param string The end date for this product YYYY-MM-DD
+ * @param string The date range for which to fetch record. Should be either 'build' or 'report'
+ * @return array The compiled data for the front page graph
+ */
+ public function getCrashesByADU($product=null, $versions=null, $start_date=null, $end_date=null, $date_range_type=null)
+ {
+ $params['product'] = $product;
+ $params['versions'] = $versions;
+ $params['from_date'] = $start_date;
+ $params['to_date'] = $end_date;
+ $params['date_range_type'] = $date_range_type;
+
+ $url = $this->buildURI($params, "/crashes/daily");
+ $lifetime = Kohana::config('webserviceclient.topcrash_vers_rank_cache_minutes', 60) * 60; // number of seconds
+ $response = $this->service->get($url, 'json', $lifetime);
+
+ if (isset($response) && !empty($response)) {
+ return $this->_buidDataObjectForGraph($start_date, $end_date, $response->hits);
+ }
+ return false;
+ }
+
/**
* Fetch records for active daily users / installs.
*
View
16 webapp-php/application/views/common/dashboard_product.php
@@ -9,24 +9,26 @@
<?php out::H($version); ?>
<?php } ?>
Crash Data</h2>
- <ul class="options">
+ <ul id="duration" class="options">
<li><a href="<?php out::H($url_base); ?>?duration=3" <?php if ($duration == 3) echo ' class="selected"'; ?>>3 days</a></li>
<li><a href="<?php out::H($url_base); ?>?duration=7" <?php if ($duration == 7) echo ' class="selected"'; ?>>7 days</a></li>
<li><a href="<?php out::H($url_base); ?>?duration=14" <?php if ($duration == 14) echo ' class="selected"'; ?>>14 days</a></li>
</ul>
+
+ <ul id="date-range-type" class="options">
+ <li>Date Range:</li>
+ <li><a href="<?php out::H($url_base); ?>?date_range_type=report" class="selected">By Crash Date</a></li>
+ <li><a href="<?php out::H($url_base); ?>?date_range_type=build">By Build Date</a></li>
+ </ul>
</div>
-<div class="panel">
+<div id="homepage-graph" class="panel">
<div class="title">
<h2>Crashes per 100 Active Daily Users</h2>
</div>
<div class="body">
- <?php if (!empty($graph_data)) { ?>
- <div id="adu-chart"></div>
- <?php } else { ?>
- <p>No Active Daily User crash data is available for this report.</p>
- <?php } ?>
+ <div id="adu-chart"></div>
</div>
</div>
View
13 webapp-php/application/views/products/product.php
@@ -17,11 +17,6 @@
<?php
-echo '<script>var data = ' . json_encode($graph_data) . '</script>';
-echo html::script(array(
- 'js/flot-0.7/jquery.flot.pack.js',
- 'js/socorro/daily.js',
- ));
View::factory('common/dashboard_product', array(
'duration' => $duration,
@@ -32,4 +27,12 @@
'version' => $version,
))->render(TRUE);
+echo '<script>var data = ' . json_encode($graph_data) . '</script>';
+echo html::script(array(
+ 'js/flot-0.7/jquery.flot.pack.js',
+ 'js/socorro/utils.js',
+ 'js/socorro/dashboard_graph.js',
+ 'js/socorro/daily.js',
+ ));
+
?>
View
13 webapp-php/application/views/products/product_version.php
@@ -22,11 +22,6 @@
echo html::stylesheet(array(
'css/daily.css',
), array('screen', 'screen'));
-echo '<script>var data = ' . json_encode($graph_data) . '</script>';
-echo html::script(array(
- 'js/flot-0.7/jquery.flot.pack.js',
- 'js/socorro/daily.js',
- ));
View::factory('common/dashboard_product', array(
'duration' => $duration,
@@ -37,4 +32,12 @@
'version' => $version,
))->render(TRUE);
+echo '<script>var data = ' . json_encode($graph_data) . '</script>';
+echo html::script(array(
+ 'js/flot-0.7/jquery.flot.pack.js',
+ 'js/socorro/utils.js',
+ 'js/socorro/dashboard_graph.js',
+ 'js/socorro/daily.js',
+ ));
+
?>
View
3 webapp-php/css/screen.css
@@ -756,6 +756,9 @@ div.admin ul li:before {
top: 45%;
left: 45%;
}
+#homepage-graph {
+ position: relative;
+}
/* simplebox css */
#simplebox {
display:none;
View
18 webapp-php/js/socorro/daily.js
@@ -9,18 +9,18 @@ $(function() {
xaxis: {
mode: 'time',
timeformat: "%b %d",
- minTickSize: [1, "day"],
+ minTickSize: [1, "day"]
},
yaxis: {
- min: 0,
+ min: 0
},
series: {
lines: { show: true },
points: {
show: true,
- radius: 1,
+ radius: 1
},
- shadowSize: 0,
+ shadowSize: 0
},
colors: colours,
grid: {
@@ -52,16 +52,6 @@ $(function() {
}
return false;
}).trigger('click');
- } else {
- var chartData = [
- { data: data.ratio1 },
- { data: data.ratio2 },
- { data: data.ratio3 },
- { data: data.ratio4 }
- ];
- if(aduChartContainer.length > 0) {
- $.plot(aduChartContainer, chartData, chartOpts);
- }
}
$("#click_by_version").bind("click", function() {
View
173 webapp-php/js/socorro/dashboard_graph.js
@@ -0,0 +1,173 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*global $:true, socorro:true */
+$(function() {
+ "use strict";
+ var chartContainer = $("#adu-chart"),
+ product = "",
+ version = "",
+ baseURL = "/products/json_data?",
+ ajaxURL = "",
+ hashString = "",
+ currentHref = "",
+ dateRangeType = "",
+ dateRangeVal = "",
+ dateRangeTypeValPattern = /(?!=)[a-zA-Z]{1,6}(?=:|$)/i,
+ durationPattern = /\d{1,2}(?=:|$)/,
+ durationValPattern = /(?!=)\d{1,6}(?=:|$)/,
+ colours = ['#058DC7', '#ED561B', '#50B432', '#990099'],
+ chartOpts = {
+ xaxis: {
+ mode: 'time',
+ timeformat: "%b %d",
+ minTickSize: [1, "day"]
+ },
+ yaxis: {
+ min: 0
+ },
+ series: {
+ lines: { show: true },
+ points: {
+ show: true,
+ radius: 1
+ },
+ shadowSize: 0
+ },
+ colors: colours,
+ grid: {
+ color: '#606060',
+ backgroundColor: '#ffffff',
+ borderColor: '#c0c0c0',
+ borderWidth: 0
+ },
+ legend: {}
+ };
+
+ var setSelected = function(item, container) {
+ $(container).find('a').removeClass("selected");
+ item.addClass("selected");
+ },
+ setSelectedByHash = function() {
+ hashString = $.trim(window.location.hash);
+ if(hashString.length) {
+ if(dateRangeTypeValPattern.exec(hashString) !== null) {
+ $("#date-range-type a").each(function() {
+ if($(this).attr("href").indexOf(dateRangeTypeValPattern.exec(hashString)) > -1) {
+ setSelected($(this), "#date-range-type");
+ }
+ });
+ }
+
+ if(durationValPattern.exec(hashString) !== null) {
+ $("#duration a").each(function() {
+ if($(this).attr("href").indexOf(durationValPattern.exec(hashString)) > -1) {
+ setSelected($(this), "#duration");
+ }
+ });
+ }
+ }
+ },
+ manageHistory = function(key, value) {
+ var newHashString = key + "=" + value,
+ currentKeyValue = "";
+
+ hashString = $.trim(window.location.hash);
+
+ if(hashString.indexOf(key) === -1) {
+ window.location.hash += hashString.length ? ":" + newHashString : newHashString;
+ } else {
+ if(key === "date_range_type") {
+ currentKeyValue = dateRangeTypeValPattern.exec(hashString);
+ if(currentKeyValue !== value) {
+ newHashString = hashString.replace(currentKeyValue, value);
+ }
+ } else {
+ currentKeyValue = durationValPattern.exec(hashString);
+ if(currentKeyValue !== value) {
+ newHashString = hashString.replace(currentKeyValue, value);
+ }
+ }
+ window.location.hash = newHashString;
+ }
+ },
+ buildAjaxURL = function() {
+
+ var isDateRangeSet = hashString.indexOf("date_range_type"),
+ isDurationSet = hashString.indexOf("duration");
+
+ product = $("#products_select").val(),
+ version = $("#product_version_select").val(),
+ ajaxURL = baseURL,
+ hashString = window.location.hash,
+ dateRangeVal = dateRangeTypeValPattern.exec(hashString);
+
+ if(product.length) {
+ ajaxURL += "product=" + product;
+ }
+
+ if(version.length && version !== "Current Versions") {
+ ajaxURL += "&version=" + version;
+ }
+
+ if(isDateRangeSet !== -1) {
+ ajaxURL += "&date_range_type=" + dateRangeVal;
+ }
+
+ if(isDurationSet !== -1) {
+ ajaxURL += "&duration=" + durationPattern.exec(hashString)[0];
+ }
+
+ return ajaxURL;
+ },
+ drawGraph = function(ajaxURL) {
+ socorro.ui.setLoader("#homepage-graph");
+ $.getJSON(ajaxURL, function(data) {
+
+ $(".loading").remove();
+
+ if(data.count > 0) {
+ var chartData = [
+ { data: data.ratio1 },
+ { data: data.ratio2 },
+ { data: data.ratio3 },
+ { data: data.ratio4 }
+ ];
+ $.plot(chartContainer, chartData, chartOpts);
+ } else {
+ chartContainer.empty().append("No Active Daily User crash data is available for this report.");
+ }
+ }).fail(function(jqXHR, textStatus, errorThrown) {
+ $(".loading").remove();
+ chartContainer.empty().append("There was an error processing the request: Status: " + textStatus + " Error: " + errorThrown);
+ });
+ },
+ handleClickEvent = function(anchor, container, key) {
+ currentHref = anchor.attr("href");
+
+ //set the clicked item to selected
+ setSelected(anchor, container);
+
+ dateRangeType = currentHref.substring(currentHref.indexOf('=') + 1);
+ manageHistory(key, dateRangeType);
+ drawGraph(buildAjaxURL());
+ },
+ init = function() {
+ setSelectedByHash();
+ drawGraph(buildAjaxURL());
+ };
+
+ $("#date-range-type a").click(function(event) {
+ event.preventDefault();
+ handleClickEvent($(this), "#date-range-type", "date_range_type");
+ });
+
+ $("#duration a").click(function(event) {
+ event.preventDefault();
+ handleClickEvent($(this), "#duration", "duration");
+ });
+
+ // initialize and draw graph on DOM ready
+ init();
+});
Something went wrong with that request. Please try again.