Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenaka Moorthi <benaka.moorthi@gmail.com>2013-09-01 19:26:59 +0400
committerBenaka Moorthi <benaka.moorthi@gmail.com>2013-09-01 19:26:59 +0400
commit42623a05f26bd153d65299ecfda0ee62c9d9d042 (patch)
treed052718e826c9591abd24d54b902fd9616bd1eee /plugins/CoreVisualizations
parent356d47698e409ce2b55a5e713c1b27b6f08a16ea (diff)
Refs #4041, refactored jqplot.js file by removing JQPlot class and creating JqplotGraph datatable class, and did more refactoring to jqplot data generating mechanism.
Notes: - Removed jqplot specific code from datatable_manager.js and moved to new JqplotGraph class. - Moved tooltip percentage calculating code to client.
Diffstat (limited to 'plugins/CoreVisualizations')
-rw-r--r--plugins/CoreVisualizations/JqplotDataGenerator.php13
-rw-r--r--plugins/CoreVisualizations/JqplotDataGenerator/Chart.php120
-rw-r--r--plugins/CoreVisualizations/Visualizations/JqplotGraph.php7
-rw-r--r--plugins/CoreVisualizations/javascripts/jqplot.js1178
-rw-r--r--plugins/CoreVisualizations/javascripts/seriesPicker.js2
-rw-r--r--plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig7
6 files changed, 677 insertions, 650 deletions
diff --git a/plugins/CoreVisualizations/JqplotDataGenerator.php b/plugins/CoreVisualizations/JqplotDataGenerator.php
index 488d1c94b5..1311fb0790 100644
--- a/plugins/CoreVisualizations/JqplotDataGenerator.php
+++ b/plugins/CoreVisualizations/JqplotDataGenerator.php
@@ -92,8 +92,6 @@ class JqplotDataGenerator
$this->initChartObjectData($dataTable, $visualization);
}
- $visualization->customizeChartProperties();
-
return $visualization->render();
}
@@ -125,12 +123,6 @@ class JqplotDataGenerator
$visualization->setAxisXLabels($xLabels);
$visualization->setAxisYValues($columnNameToValue);
$visualization->setAxisYLabels($columnNameToTranslation);
- $visualization->setAxisYUnit($this->properties['y_axis_unit']);
-
- // show_all_ticks is not real query param, it is set by GenerateGraphHTML.
- if ($this->properties['visualization_properties']->show_all_ticks) {
- $visualization->showAllTicks();
- }
$units = $this->getUnitsForColumnsToDisplay();
$visualization->setAxisYUnits($units);
@@ -141,10 +133,7 @@ class JqplotDataGenerator
// derive units from column names
$units = $this->deriveUnitsFromRequestedColumnNames();
if (!empty($this->properties['y_axis_unit'])) {
- // force unit to the value set via $this->setAxisYUnit()
- foreach ($units as &$unit) {
- $unit = $this->properties['y_axis_unit'];
- }
+ $units = array_fill(0, count($units), $this->properties['y_axis_unit']);
}
// the bar charts contain the labels a first series
diff --git a/plugins/CoreVisualizations/JqplotDataGenerator/Chart.php b/plugins/CoreVisualizations/JqplotDataGenerator/Chart.php
index d095294568..128935c884 100644
--- a/plugins/CoreVisualizations/JqplotDataGenerator/Chart.php
+++ b/plugins/CoreVisualizations/JqplotDataGenerator/Chart.php
@@ -23,23 +23,28 @@ class Chart
protected $series = array();
protected $data = array();
protected $axes = array();
- protected $tooltip = array();
-
- // other attributes (not directly used for jqplot)
- protected $yUnit = '';
// temporary
public $dataTable;
public $properties;
- /**
- * Whether to show every x-axis tick or only every other one.
- */
- protected $showAllTicks = false;
-
- public function setAxisXLabels(&$xLabels)
+ public function setAxisXLabels($xLabels)
{
- $this->axes['xaxis']['ticks'] = & $xLabels;
+ $xSteps = $this->properties['visualization_properties']->x_axis_step_size;
+ $showAllTicks = $this->properties['visualization_properties']->show_all_ticks;
+
+ $this->axes['xaxis']['labels'] = array_values($xLabels);
+
+ $ticks = array_values($xLabels);
+ if (!$showAllTicks) {
+ // unset labels so there are $xSteps number of blank ticks between labels
+ foreach ($ticks as $i => &$label) {
+ if ($i % $xSteps != 0) {
+ $label = ' ';
+ }
+ }
+ }
+ $this->axes['xaxis']['ticks'] = $ticks;
}
public function setAxisXOnClick(&$onClick)
@@ -63,54 +68,29 @@ class Chart
}
}
- protected function addTooltipToValue($seriesIndex, $valueIndex, $tooltipTitle, $tooltipText)
- {
- $this->tooltip[$seriesIndex][$valueIndex] = array($tooltipTitle, $tooltipText);
- }
-
- public function setAxisYUnit($yUnit)
- {
- $yUnits = array();
- for ($i = 0; $i < count($this->data); $i++) {
- $yUnits[] = $yUnit;
- }
- $this->setAxisYUnits($yUnits);
- }
-
public function setAxisYUnits($yUnits)
{
- // generate an axis config for each unit
+ $yUnits = array_values(array_map('strval', $yUnits));
+
+ // generate axis IDs for each unique y unit
$axesIds = array();
- // associate each series with the appropriate axis
- $seriesAxes = array();
- // units for tooltips
- $seriesUnits = array();
- foreach ($yUnits as $unit) {
- // handle axes ids: first y[]axis, then y[2]axis, y[3]axis...
- $nextAxisId = empty($axesIds) ? '' : count($axesIds) + 1;
-
- $unit = $unit ? $unit : '';
+ foreach ($yUnits as $idx => $unit) {
if (!isset($axesIds[$unit])) {
- $axesIds[$unit] = array('id' => $nextAxisId, 'unit' => $unit);
- $seriesAxes[] = 'y' . $nextAxisId . 'axis';
- } else {
- // reuse existing axis
- $seriesAxes[] = 'y' . $axesIds[$unit]['id'] . 'axis';
+ // handle axes ids: first y[]axis, then y[2]axis, y[3]axis...
+ $nextAxisId = empty($axesIds) ? '' : count($axesIds) + 1;
+
+ $axesIds[$unit] = 'y' . $nextAxisId . 'axis';
}
- $seriesUnits[] = $unit;
}
// generate jqplot axes config
- foreach ($axesIds as $axis) {
- $axisKey = 'y' . $axis['id'] . 'axis';
- $this->axes[$axisKey]['tickOptions']['formatString'] = '%s' . $axis['unit'];
+ foreach ($axesIds as $unit => $axisId) {
+ $this->axes[$axisId]['tickOptions']['formatString'] = '%s' . $unit;
}
- $this->tooltip['yUnits'] = $seriesUnits;
-
- // add axis config to series
- foreach ($seriesAxes as $i => $axisName) {
- $this->series[$i]['yaxis'] = $axisName;
+ // map each series to appropriate yaxis
+ foreach ($yUnits as $idx => $unit) {
+ $this->series[$idx]['yaxis'] = $axesIds[$unit];
}
}
@@ -124,14 +104,6 @@ class Chart
}
}
- /**
- * Show every x-axis tick instead of just every other one.
- */
- public function showAllTicks()
- {
- $this->showAllTicks = true;
- }
-
public function render()
{
Piwik::overrideCacheControlHeaders();
@@ -142,41 +114,9 @@ class Chart
'axes' => &$this->axes,
'series' => &$this->series
),
- 'data' => &$this->data,
- 'tooltip' => &$this->tooltip,
+ 'data' => &$this->data
);
return Common::json_encode($data);
}
-
- public function customizeChartProperties()
- {
- // x axis labels with steps
- if (isset($this->axes['xaxis']['ticks'])) {
- $xSteps = $this->properties['visualization_properties']->x_axis_step_size;
- foreach ($this->axes['xaxis']['ticks'] as $i => &$xLabel) {
- $this->axes['xaxis']['labels'][$i] = $xLabel;
- if (!$this->showAllTicks && ($i % $xSteps) != 0) {
- $xLabel = ' ';
- }
- }
- }
-
- if ($this->properties['visualization_properties']->display_percentage_in_tooltip) {
- foreach ($this->data as $seriesIndex => &$series) {
- $sum = array_sum($series);
-
- foreach ($series as $valueIndex => $value) {
- $value = (float)$value;
-
- $percentage = 0;
- if ($sum > 0) {
- $percentage = round(100 * $value / $sum);
- }
-
- $this->tooltip['percentages'][$seriesIndex][$valueIndex] = $percentage;
- }
- }
- }
- }
} \ No newline at end of file
diff --git a/plugins/CoreVisualizations/Visualizations/JqplotGraph.php b/plugins/CoreVisualizations/Visualizations/JqplotGraph.php
index 4f1e755a43..3e037f16c3 100644
--- a/plugins/CoreVisualizations/Visualizations/JqplotGraph.php
+++ b/plugins/CoreVisualizations/Visualizations/JqplotGraph.php
@@ -44,6 +44,11 @@ class JqplotGraph extends Graph
*/
const X_AXIS_STEP_SIZE = 'x_axis_step_size';
+ public static $clientSideProperties = array(
+ 'external_series_toggle',
+ 'external_series_toggle_show_all'
+ );
+
/**
* Constructor.
*
@@ -65,6 +70,8 @@ class JqplotGraph extends Graph
$result['filter_sort_column'] = $firstColumn;
$result['filter_sort_order'] = 'desc';
}
+
+ $view->datatable_js_type = 'JqplotGraphDataTable';
}
/**
diff --git a/plugins/CoreVisualizations/javascripts/jqplot.js b/plugins/CoreVisualizations/javascripts/jqplot.js
index 3c0f08bff9..2db36cde16 100644
--- a/plugins/CoreVisualizations/javascripts/jqplot.js
+++ b/plugins/CoreVisualizations/javascripts/jqplot.js
@@ -8,129 +8,260 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
-/**
- * Constructor function
- *
- * @param {object} data the data that would be passed to open flash chart
- * @param {int} dataTableId
- */
-function JQPlot(data, dataTableId) {
- this.init(data, dataTableId);
-}
+(function ($, require) {
-JQPlot.prototype = {
-
- /** Generic init function */
- init: function (data, dataTableId) {
- this.dataTableId = dataTableId;
- this.originalData = data;
- this.data = data.data;
-
- defaultParams = {
- grid: {
- drawGridLines: false,
- borderWidth: 0,
- shadow: false
- },
- title: {
- show: false
- },
- axesDefaults: {
- pad: 1.0,
- tickRenderer: $.jqplot.CanvasAxisTickRenderer,
- tickOptions: {
- showMark: false,
- fontSize: '11px',
- fontFamily: 'Arial'
- },
- rendererOptions: {
- drawBaseline: false
- }
+ var dataTable = window.dataTable,
+ dataTablePrototype = dataTable.prototype;
+
+ window.JqplotGraphDataTable = function () {
+ dataTable.call(this);
+ };
+
+ $.extend(window.JqplotGraphDataTable.prototype, dataTablePrototype, {
+
+ /**
+ * Constructor.
+ *
+ * @param {String} workingDivId The HTML ID of the data table DOM element.
+ * @param {Element} [domElem] The DOM element of the data table.
+ */
+ init: function (workingDivId, domElem) {
+ if (typeof domElem == "undefined") {
+ domElem = $('#' + workingDivId);
}
- };
- this.params = $.extend(true, {}, defaultParams, data.params);
- this._setColors();
+ dataTablePrototype.init.call(this, workingDivId, domElem);
- this.tooltip = data.tooltip;
- this.seriesPicker = data.seriesPicker;
+ var graphElement = $('.piwik-graph', domElem);
+ if (!graphElement.length) {
+ return;
+ }
- if (typeof this.params.axes.yaxis == 'undefined') {
- this.params.axes.yaxis = {};
- }
+ this._lang = {
+ noData: _pk_translate('General_NoDataForGraph_js'),
+ exportTitle: _pk_translate('General_ExportAsImage_js'),
+ exportText: _pk_translate('General_SaveImageOnYourComputer_js'),
+ metricsToPlot: _pk_translate('General_MetricsToPlot_js'),
+ metricToPlot: _pk_translate('General_MetricToPlot_js'),
+ recordsToPlot: _pk_translate('General_RecordsToPlot_js')
+ };
- if (typeof this.params.axes.yaxis.tickOptions == 'undefined') {
- this.params.axes.yaxis.tickOptions = {
- formatString: '%d'
+ // set a unique ID for the graph element (required by jqPlot)
+ this.targetDivId = workingDivId + 'Chart';
+ graphElement.attr('id', this.targetDivId);
+
+ try {
+ var graphData = JSON.parse(graphElement.attr('data-data'));
+ } catch (e) {
+ console.error('JSON.parse Error: "' + e + "\" in:\n" + graphElement.attr('data-data'));
+ return;
+ }
+
+ this.data = graphData.data;
+ this._setJqplotParameters(graphData.params);
+ this._setColors();
+
+ if (this.props.display_percentage_in_tooltip) {
+ this._setTooltipPercentages();
+ }
+
+ // determine the graph type
+ var dataTableDiv = $('#' + this.workingDivId);
+ if (dataTableDiv.hasClass('dataTableVizEvolution')) {
+ this.type = 'evolution';
+ } else if (dataTableDiv.hasClass('dataTableVizBar')) {
+ this.type = 'bar';
+ } else if (dataTableDiv.hasClass('dataTableVizPie')) {
+ this.type = 'pie';
+ }
+
+ this._bindEvents();
+
+ // add external series toggle if it should be added
+ if (this.props.external_series_toggle) {
+ this.addExternalSeriesToggle(
+ window[this.props.external_series_toggle], // get the function w/ string name
+ this.props.external_series_toggle_show_all == 1
+ );
+ }
+
+ // render the graph (setTimeout is required, otherwise the graph will not
+ // render initially)
+ var self = this;
+ setTimeout(function () { self.render(); }, 1);
+ },
+
+ _setJqplotParameters: function (params) {
+ defaultParams = {
+ grid: {
+ drawGridLines: false,
+ borderWidth: 0,
+ shadow: false
+ },
+ title: {
+ show: false
+ },
+ axesDefaults: {
+ pad: 1.0,
+ tickRenderer: $.jqplot.CanvasAxisTickRenderer,
+ tickOptions: {
+ showMark: false,
+ fontSize: '11px',
+ fontFamily: 'Arial'
+ },
+ rendererOptions: {
+ drawBaseline: false
+ }
+ },
+ axes: {
+ yaxis: {
+ tickOptions: {
+ formatString: '%d'
+ }
+ }
+ }
};
- }
- },
- /** Generic render function */
- render: function (targetDivId, lang) {
- var dataTableDiv = $('#' + targetDivId).closest('div.dataTable');
-
- // preapare the appropriate chart type
- var type;
- if (dataTableDiv.hasClass('dataTableVizEvolution')) {
- type = 'evolution';
- this.prepareEvolutionChart(targetDivId, lang);
- } else if (dataTableDiv.hasClass('dataTableVizBar')) {
- type = 'bar';
- this.prepareBarChart(targetDivId, lang);
- } else if (dataTableDiv.hasClass('dataTableVizPie')) {
- type = 'pie';
- this.preparePieChart(targetDivId, lang);
- } else {
- return;
- }
+ this.jqplotParams = $.extend(true, {}, defaultParams, params);
+ },
+
+ _setTooltipPercentages: function () {
+ this.tooltip = {percentages: []};
+ for (var seriesIdx = 0; seriesIdx != this.data.length; ++seriesIdx) {
+ var series = this.data[seriesIdx];
+ var sum = series.reduce(function (previousValue, currentValue) { return previousValue + currentValue; }, 0);
+
+ var percentages = this.tooltip.percentages[seriesIdx] = [];
+ for (var valueIdx = 0; valueIdx != series.length; ++valueIdx) {
+ percentages[valueIdx] = sum > 0 ? Math.round(100 * series[valueIdx] / sum) : 0;
+ }
+ }
+ },
+
+ _bindEvents: function () {
+ // preapare the appropriate chart type
+ if (this.type == 'evolution') {
+ this.prepareEvolutionChart();
+ } else if (this.type == 'bar') {
+ this.prepareBarChart();
+ } else if (this.type == 'pie') {
+ this.preparePieChart();
+ } else {
+ return;
+ }
- // handle replot
- // this has be bound before the check for an empty graph.
- // otherwise clicking on sparklines won't work anymore after an empty
- // report has been displayed.
- var self = this;
- var target = $('#' + targetDivId)
- .on('replot', function (e, data) {
- target.trigger('piwikDestroyPlot');
- if (target.data('oldHeight') > 0) {
- // handle replot after empty report
- target.height(target.data('oldHeight'));
- target.data('oldHeight', 0);
- this.innerHTML = '';
+ var self = this;
+ var target = $('#' + this.targetDivId);
+
+ // tooltip show/hide
+ target.on('jqplotDataHighlight', function (e, seriesIndex, valueIndex) {
+ self._showDataPointTooltip(this, seriesIndex, valueIndex);
+ })
+ .on('jqplotDataUnhighlight', function () {
+ if (self.type != 'evolution') {
+ if ($(this).is( ":data('ui-tooltip')" )) {
+ $(this).tooltip('destroy');
+ }
}
+ });
- (new JQPlot(data, self.dataTableId)).render(targetDivId, lang);
+ // handle window resize
+ this._plotWidth = target.innerWidth();
+ target.on('resizeGraph', function () { // TODO: shouldn't be a triggerable event.
+ self._resizeGraph();
});
- // show loading
- target.bind('showLoading', function () {
- var loading = $(document.createElement('div')).addClass('jqplot-loading');
- loading.css({
- width: target.innerWidth() + 'px',
- height: target.innerHeight() + 'px',
- opacity: 0
+ // export as image
+ target.on('piwikExportAsImage', function () {
+ self.exportAsImage(target, lang);
});
- target.prepend(loading);
- loading.css({opacity: .7});
- });
- // change series
- target.bind('changeColumns', function (e, columns) {
- target.trigger('changeSeries', [columns, []]);
- });
- target.bind('changeSeries', function (e, columns, rows) {
- target.trigger('showLoading');
+ // manage resources
+ target.on('piwikDestroyPlot', function () {
+ $(window).off('resize', this._resizeListener);
+ self._plot.destroy();
+ for (var i = 0; i < $.jqplot.visiblePlots.length; i++) {
+ if ($.jqplot.visiblePlots[i] == self._plot) {
+ $.jqplot.visiblePlots[i] = null;
+ }
+ }
+ });
+ },
+
+ _resizeGraph: function () {
+ var width = $('#' + this.targetDivId).innerWidth();
+ if (width > 0 && Math.abs(this._plotWidth - width) >= 5) {
+ this._plotWidth = width;
+ this.render();
+ }
+ },
+
+ _setWindowResizeListener: function () {
+ var self = this;
+
+ var timeout = false;
+ this._resizeListener = function () {
+ if (timeout) {
+ window.clearTimeout(timeout);
+ }
+
+ timeout = window.setTimeout(function () { $('#' + self.targetDivId).trigger('resizeGraph'); }, 300);
+ };
+ $(window).on('resize', this._resizeListener);
+ },
+
+ _showDataPointTooltip: function (element, seriesIndex, valueIndex) {
+ if (this.type == 'bar') {
+ var value = this.formatY(this.data[seriesIndex][valueIndex], seriesIndex);
+ var series = this.jqplotParams.series[seriesIndex].label;
+
+ var percentage = '';
+ if (typeof this.tooltip.percentages != 'undefined') {
+ percentage = this.tooltip.percentages[seriesIndex][valueIndex];
+ percentage = ' (' + percentage + '%)';
+ }
+
+ var label = this.jqplotParams.axes.xaxis.labels[valueIndex];
+ var text = '<strong>' + value + '</strong> ' + series + percentage;
+ $(element).tooltip({
+ track: true,
+ items: '*',
+ content: '<h3>' + label + '</h3>' + text,
+ show: false,
+ hide: false
+ }).trigger('mouseover');
+ } else if (this.type == 'pie') {
+ var value = this.formatY(this.data[0][valueIndex][1], 0);
+ var series = this.jqplotParams.series[0].label;
+ var percentage = this.tooltip.percentages[0][valueIndex];
+
+ var label = this.data[0][valueIndex][0];
+
+ var text = '<strong>' + percentage + '%</strong> (' + value + ' ' + series + ')';
+ $(element).tooltip({
+ track: true,
+ items: '*',
+ content: '<h3>' + label + '</h3>' + text,
+ show: false,
+ hide: false
+ }).trigger('mouseover');
+ }
+ },
+
+ changeSeries: function (columns, rows) {
+ this.showLoading();
+
+ columns = columns || [];
if (typeof columns == 'string') {
columns = columns.split(',');
}
- if (typeof rows == 'undefined') {
- rows = [];
- }
- else if (typeof rows == 'string') {
+
+ rows = rows || [];
+ if (typeof rows == 'string') {
rows = rows.split(',');
}
- var dataTable = $('#' + self.dataTableId).data('dataTableInstance');
+
+ var dataTable = $('#' + this.workingDivId).data('dataTableInstance');
dataTable.param.columns = columns.join(',');
dataTable.param.rows = rows.join(',');
delete dataTable.param.filter_limit;
@@ -140,498 +271,463 @@ JQPlot.prototype = {
}
dataTable.param.disable_generic_filters = '0';
dataTable.reloadAjaxDataTable(false);
- });
+ },
- // this case happens when there is no data for a line chart
- if (this.data.length == 0) {
- target.addClass('pk-emptyGraph');
- target.data('oldHeight', target.height());
- target.css('height', 'auto').html(lang.noData);
- return;
- }
+ destroyPlot: function () {
+ var target = $('#' + this.targetDivId);
- // create jqplot chart
- try {
- var plot = $.jqplot(targetDivId, this.data, this.params);
- } catch (e) {
- // this is thrown when refreshing piwik in the browser
- if (e != "No plot target specified") {
- throw e;
+ target.trigger('piwikDestroyPlot');
+ if (target.data('oldHeight') > 0) {
+ // handle replot after empty report
+ target.height(target.data('oldHeight'));
+ target.data('oldHeight', 0);
+ target.innerHTML = '';
}
- }
+ },
- // bind tooltip
- var self = this;
- target.on('jqplotDataHighlight', function (e, s, i, d) {
- if (type == 'bar') {
- var value = self.formatY(self.data[s][i], s);
- var series = self.params.series[s].label;
-
- var percentage = '';
- if (typeof self.tooltip.percentages != 'undefined') {
- percentage = self.tooltip.percentages[s][i];
- percentage = ' (' + percentage + '%)';
- }
-
- var label = self.params.axes.xaxis.labels[i];
- var text = '<strong>' + value + '</strong> ' + series + percentage;
- $(this).tooltip({
- track: true,
- items: '*',
- content: '<h3>' + label + '</h3>' + text,
- show: false,
- hide: false
- }).trigger('mouseover');
+ showLoading: function () {
+ var target = $('#' + this.targetDivId);
- } else if (type == 'pie') {
- var value = self.formatY(self.data[0][i][1], 1); // series index 1 because 0 is the label
- var series = self.params.series[0].label;
- var percentage = self.tooltip.percentages[0][i];
-
- var label = self.data[0][i][0];
-
- var text = '<strong>' + percentage + '%</strong> (' + value + ' ' + series + ')';
- $(this).tooltip({
- track: true,
- items: '*',
- content: '<h3>' + label + '</h3>' + text,
- show: false,
- hide: false
- }).trigger('mouseover');
- }
- })
- .on('jqplotDataUnhighlight', function (e, s, i, d) {
- if (type != 'evolution') {
- if ($(this).is( ":data('ui-tooltip')" )) {
- $(this).tooltip('destroy');
+ var loading = $(document.createElement('div')).addClass('jqplot-loading');
+ loading.css({
+ width: target.innerWidth() + 'px',
+ height: target.innerHeight() + 'px',
+ opacity: 0
+ });
+ target.prepend(loading);
+ loading.css({opacity: .7});
+ },
+
+ /** Generic render function */
+ render: function () {
+ if (this.data.length == 0) { // sanity check
+ return;
+ }
+
+ var targetDivId = this.workingDivId + 'Chart';
+ var lang = this._lang;
+ var dataTableDiv = $('#' + this.workingDivId);
+
+ // if the plot has already been rendered, get rid of the existing plot
+ var target = $('#' + targetDivId);
+ if (target.find('canvas').length > 0) {
+ this.destroyPlot();
+ }
+
+ // handle replot
+ // this has be bound before the check for an empty graph.
+ // otherwise clicking on sparklines won't work anymore after an empty
+ // report has been displayed.
+ var self = this;
+
+ // create jqplot chart
+ try {
+ var plot = self._plot = $.jqplot(targetDivId, this.data, this.jqplotParams);
+ } catch (e) {
+ // this is thrown when refreshing piwik in the browser
+ if (e != "No plot target specified") {
+ throw e;
}
}
- });
- // handle window resize
- var plotWidth = target.innerWidth();
- var timeout = false;
- target.on('resizeGraph', function () {
- var width = target.innerWidth();
- if (width > 0 && Math.abs(plotWidth - width) >= 5) {
- plotWidth = width;
- target.trigger('piwikDestroyPlot');
- (new JQPlot(self.originalData, self.dataTableId))
- .render(targetDivId, lang);
+ self._setWindowResizeListener();
+
+ var self = this;
+
+ // TODO: this code destroys plots when a page is switched. there must be a better way of managing memory.
+ if (typeof $.jqplot.visiblePlots == 'undefined') {
+ $.jqplot.visiblePlots = [];
+ $('.nav').on('piwikSwitchPage', function () {
+ for (var i = 0; i < $.jqplot.visiblePlots.length; i++) {
+ if ($.jqplot.visiblePlots[i] == null) {
+ continue;
+ }
+ $.jqplot.visiblePlots[i].destroy();
+ }
+ $.jqplot.visiblePlots = [];
+ });
}
- });
- var resizeListener = function () {
- if (timeout) {
- window.clearTimeout(timeout);
+
+ if (typeof plot != 'undefined') {
+ $.jqplot.visiblePlots.push(plot);
}
- timeout = window.setTimeout(function () {
- target.trigger('resizeGraph');
- }, 300);
- };
- $(window).on('resize', resizeListener);
-
- // export as image
- target.on('piwikExportAsImage', function (e) {
- self.exportAsImage(target, lang);
- });
+ },
+
+ /** Export the chart as an image */
+ exportAsImage: function (container, lang) {
+ var exportCanvas = document.createElement('canvas');
+ exportCanvas.width = container.width();
+ exportCanvas.height = container.height();
- // manage resources
- target.on('piwikDestroyPlot', function () {
- $(window).off('resize', resizeListener);
- plot.destroy();
- for (var i = 0; i < $.jqplot.visiblePlots.length; i++) {
- if ($.jqplot.visiblePlots[i] == plot) {
- $.jqplot.visiblePlots[i] = null;
+ if (!exportCanvas.getContext) {
+ alert("Sorry, not supported in your browser. Please upgrade your browser :)");
+ return;
+ }
+ var exportCtx = exportCanvas.getContext('2d');
+
+ var canvases = container.find('canvas');
+
+ for (var i = 0; i < canvases.length; i++) {
+ var canvas = canvases.eq(i);
+ var position = canvas.position();
+ var parent = canvas.parent();
+ if (parent.hasClass('jqplot-axis')) {
+ var addPosition = parent.position();
+ position.left += addPosition.left;
+ position.top += addPosition.top + parseInt(parent.css('marginTop'), 10);
}
+ exportCtx.drawImage(canvas[0], Math.round(position.left), Math.round(position.top));
}
- $(this).off();
- });
- if (typeof $.jqplot.visiblePlots == 'undefined') {
- $.jqplot.visiblePlots = [];
- $('.nav').on('piwikSwitchPage', function () {
- for (var i = 0; i < $.jqplot.visiblePlots.length; i++) {
- if ($.jqplot.visiblePlots[i] == null) {
- continue;
- }
- $.jqplot.visiblePlots[i].destroy();
+ var exported = exportCanvas.toDataURL("image/png");
+
+ var img = document.createElement('img');
+ img.src = exported;
+
+ img = $(img).css({
+ width: exportCanvas.width + 'px',
+ height: exportCanvas.height + 'px'
+ });
+
+ var popover = $(document.createElement('div'));
+
+ popover.append('<div style="font-size: 13px; margin-bottom: 10px;">'
+ + lang.exportText + '</div>').append($(img));
+
+ popover.dialog({
+ title: lang.exportTitle,
+ modal: true,
+ width: 'auto',
+ position: ['center', 'center'],
+ resizable: false,
+ autoOpen: true,
+ open: function (event, ui) {
+ $('.ui-widget-overlay').on('click.popover', function () {
+ popover.dialog('close');
+ });
+ },
+ close: function (event, ui) {
+ $(this).dialog("destroy").remove();
}
- $.jqplot.visiblePlots = [];
});
- }
+ },
- if (typeof plot != 'undefined') {
- $.jqplot.visiblePlots.push(plot);
- }
- },
- /** Export the chart as an image */
- exportAsImage: function (container, lang) {
- var exportCanvas = document.createElement('canvas');
- exportCanvas.width = container.width();
- exportCanvas.height = container.height();
+ // ------------------------------------------------------------
+ // EVOLUTION CHART
+ // ------------------------------------------------------------
- if (!exportCanvas.getContext) {
- alert("Sorry, not supported in your browser. Please upgrade your browser :)");
- return;
- }
- var exportCtx = exportCanvas.getContext('2d');
-
- var canvases = container.find('canvas');
-
- for (var i = 0; i < canvases.length; i++) {
- var canvas = canvases.eq(i);
- var position = canvas.position();
- var parent = canvas.parent();
- if (parent.hasClass('jqplot-axis')) {
- var addPosition = parent.position();
- position.left += addPosition.left;
- position.top += addPosition.top + parseInt(parent.css('marginTop'), 10);
- }
- exportCtx.drawImage(canvas[0], Math.round(position.left), Math.round(position.top));
- }
+ prepareEvolutionChart: function () {
+ var targetDivId = this.targetDivId;
+ var lang = this._lang;
+
+ this.setYTicks();
+
+ defaultParams.axes = {
+ xaxis: {
+ pad: 1.0,
+ renderer: $.jqplot.CategoryAxisRenderer,
+ tickOptions: {
+ showGridline: false
+ }
+ }
+ };
- var exported = exportCanvas.toDataURL("image/png");
+ defaultParams.seriesDefaults = {
+ lineWidth: 1,
+ markerOptions: {
+ style: "filledCircle",
+ size: 6,
+ shadow: false
+ }
+ };
- var img = document.createElement('img');
- img.src = exported;
+ defaultParams.piwikTicks = {
+ showTicks: true,
+ showGrid: true,
+ showHighlight: true,
+ tickColor: this.tickColor
+ };
- img = $(img).css({
- width: exportCanvas.width + 'px',
- height: exportCanvas.height + 'px'
- });
+ this.jqplotParams = $.extend(true, {}, defaultParams, this.jqplotParams);
- var popover = $(document.createElement('div'));
+ var self = this;
+ var lastTick = false;
+
+ $('#' + targetDivId)
+ .on('jqplotMouseLeave', function (e, s, i, d) {
+ $(this).css('cursor', 'default');
+ if ($(this).is( ":data('ui-tooltip')" )) {
+ $(this).tooltip('destroy');
+ }
+ })
+ .on('jqplotClick', function (e, s, i, d) {
+ if (lastTick !== false && typeof self.jqplotParams.axes.xaxis.onclick != 'undefined'
+ && typeof self.jqplotParams.axes.xaxis.onclick[lastTick] == 'string') {
+ var url = self.jqplotParams.axes.xaxis.onclick[lastTick];
+ piwikHelper.redirectToUrl(url);
+ }
+ })
+ .on('jqplotPiwikTickOver', function (e, tick) {
+ lastTick = tick;
+ var label;
+ if (typeof self.jqplotParams.axes.xaxis.labels != 'undefined') {
+ label = self.jqplotParams.axes.xaxis.labels[tick];
+ } else {
+ label = self.jqplotParams.axes.xaxis.ticks[tick];
+ }
- popover.append('<div style="font-size: 13px; margin-bottom: 10px;">'
- + lang.exportText + '</div>').append($(img));
-
- popover.dialog({
- title: lang.exportTitle,
- modal: true,
- width: 'auto',
- position: ['center', 'center'],
- resizable: false,
- autoOpen: true,
- open: function (event, ui) {
- $('.ui-widget-overlay').on('click.popover', function () {
- popover.dialog('close');
+ var text = [];
+ for (var d = 0; d < self.data.length; d++) {
+ var value = self.formatY(self.data[d][tick], d);
+ var series = self.jqplotParams.series[d].label;
+ text.push('<strong>' + value + '</strong> ' + series);
+ }
+ $(this).tooltip({
+ track: true,
+ items: 'div',
+ content: '<h3>'+label+'</h3>'+text.join('<br />'),
+ show: false,
+ hide: false
+ }).trigger('mouseover');
+ if (typeof self.jqplotParams.axes.xaxis.onclick != 'undefined'
+ && typeof self.jqplotParams.axes.xaxis.onclick[lastTick] == 'string') {
+ $(this).css('cursor', 'pointer');
+ }
});
- },
- close: function (event, ui) {
- $(this).dialog("destroy").remove();
- }
- });
- },
+ this.jqplotParams.legend = {
+ show: false
+ };
+ this.jqplotParams.canvasLegend = {
+ show: true
+ };
+ },
- // ------------------------------------------------------------
- // EVOLUTION CHART
- // ------------------------------------------------------------
+ // ------------------------------------------------------------
+ // PIE CHART
+ // ------------------------------------------------------------
- prepareEvolutionChart: function (targetDivId, lang) {
- this.setYTicks();
+ preparePieChart: function () {
+ var targetDivId = this.targetDivId;
+ var lang = this._lang;
- defaultParams.axes = {
- xaxis: {
- pad: 1.0,
- renderer: $.jqplot.CategoryAxisRenderer,
- tickOptions: {
- showGridline: false
+ this.jqplotParams.seriesDefaults = {
+ renderer: $.jqplot.PieRenderer,
+ rendererOptions: {
+ shadow: false,
+ showDataLabels: false,
+ sliceMargin: 1,
+ startAngle: 35
+ }
+ };
+
+ this.jqplotParams.piwikTicks = {
+ showTicks: false,
+ showGrid: false,
+ showHighlight: false,
+ tickColor: this.tickColor
+ };
+
+ this.jqplotParams.legend = {
+ show: false
+ };
+ this.jqplotParams.pieLegend = {
+ show: true,
+ labelColor: this.singleMetricColor
+ };
+ this.jqplotParams.canvasLegend = {
+ show: true,
+ singleMetric: true,
+ singleMetricColor: this.singleMetricColor
+ };
+
+ // pie charts have a different data format
+ if (!(this.data[0][0] instanceof Array)) { // check if already in different format
+ for (var i = 0; i < this.data[0].length; i++) {
+ this.data[0][i] = [this.jqplotParams.axes.xaxis.ticks[i], this.data[0][i]];
}
}
- };
-
- defaultParams.seriesDefaults = {
- lineWidth: 1,
- markerOptions: {
- style: "filledCircle",
- size: 6,
- shadow: false
- }
- };
+ },
- defaultParams.piwikTicks = {
- showTicks: true,
- showGrid: true,
- showHighlight: true,
- tickColor: this.tickColor
- };
+ // ------------------------------------------------------------
+ // BAR CHART
+ // ------------------------------------------------------------
- this.params = $.extend(true, {}, defaultParams, this.params);
+ prepareBarChart: function () {
+ var targetDivId = this.targetDivId;
+ var lang = this._lang;
- var self = this;
- var lastTick = false;
+ this.setYTicks();
- $('#' + targetDivId)
- .on('jqplotMouseLeave', function (e, s, i, d) {
- $(this).css('cursor', 'default');
- if ($(this).is( ":data('ui-tooltip')" )) {
- $(this).tooltip('destroy');
- }
- })
- .on('jqplotClick', function (e, s, i, d) {
- if (lastTick !== false && typeof self.params.axes.xaxis.onclick != 'undefined'
- && typeof self.params.axes.xaxis.onclick[lastTick] == 'string') {
- var url = self.params.axes.xaxis.onclick[lastTick];
- piwikHelper.redirectToUrl(url);
- }
- })
- .on('jqplotPiwikTickOver', function (e, tick) {
- lastTick = tick;
- var label;
- if (typeof self.params.axes.xaxis.labels != 'undefined') {
- label = self.params.axes.xaxis.labels[tick];
- } else {
- label = self.params.axes.xaxis.ticks[tick];
- }
-
- var text = [];
- for (var d = 0; d < self.data.length; d++) {
- var value = self.formatY(self.data[d][tick], d);
- var series = self.params.series[d].label;
- text.push('<strong>' + value + '</strong> ' + series);
- }
- $(this).tooltip({
- track: true,
- items: 'div',
- content: '<h3>'+label+'</h3>'+text.join('<br />'),
- show: false,
- hide: false
- }).trigger('mouseover');
- if (typeof self.params.axes.xaxis.onclick != 'undefined'
- && typeof self.params.axes.xaxis.onclick[lastTick] == 'string') {
- $(this).css('cursor', 'pointer');
+ this.jqplotParams.seriesDefaults = {
+ renderer: $.jqplot.BarRenderer,
+ rendererOptions: {
+ shadowOffset: 1,
+ shadowDepth: 2,
+ shadowAlpha: .2,
+ fillToZero: true,
+ barMargin: this.data[0].length > 10 ? 2 : 10
}
- });
+ };
- this.params.legend = {
- show: false
- };
- this.params.canvasLegend = {
- show: true
- };
- },
+ this.jqplotParams.piwikTicks = {
+ showTicks: true,
+ showGrid: false,
+ showHighlight: false,
+ tickColor: this.tickColor
+ };
- // ------------------------------------------------------------
- // PIE CHART
- // ------------------------------------------------------------
-
- preparePieChart: function (targetDivId, lang) {
- this.params.seriesDefaults = {
- renderer: $.jqplot.PieRenderer,
- rendererOptions: {
- shadow: false,
- showDataLabels: false,
- sliceMargin: 1,
- startAngle: 35
- }
- };
-
- this.params.piwikTicks = {
- showTicks: false,
- showGrid: false,
- showHighlight: false,
- tickColor: this.tickColor
- };
-
- this.params.legend = {
- show: false
- };
- this.params.pieLegend = {
- show: true,
- labelColor: this.singleMetricColor
- };
- this.params.canvasLegend = {
- show: true,
- singleMetric: true,
- singleMetricColor: this.singleMetricColor
- };
-
- // pie charts have a different data format
- if (!(this.data[0][0] instanceof Array)) { // check if already in different format
- for (var i = 0; i < this.data[0].length; i++) {
- this.data[0][i] = [this.params.axes.xaxis.ticks[i], this.data[0][i]];
- }
- }
- },
+ this.jqplotParams.axes.xaxis.renderer = $.jqplot.CategoryAxisRenderer;
+ this.jqplotParams.axes.xaxis.tickOptions = {
+ showGridline: false
+ };
- // ------------------------------------------------------------
- // BAR CHART
- // ------------------------------------------------------------
-
- prepareBarChart: function (targetDivId, lang) {
- this.setYTicks();
-
- this.params.seriesDefaults = {
- renderer: $.jqplot.BarRenderer,
- rendererOptions: {
- shadowOffset: 1,
- shadowDepth: 2,
- shadowAlpha: .2,
- fillToZero: true,
- barMargin: this.data[0].length > 10 ? 2 : 10
+ this.jqplotParams.canvasLegend = {
+ show: true
+ };
+ },
+
+ // ------------------------------------------------------------
+ // HELPER METHODS
+ // ------------------------------------------------------------
+
+ /** Generate ticks in y direction */
+ setYTicks: function () {
+ // default axis
+ this.setYTicksForAxis('yaxis', this.jqplotParams.axes.yaxis);
+ // other axes: y2axis, y3axis...
+ for (var i = 2; typeof this.jqplotParams.axes['y' + i + 'axis'] != 'undefined'; i++) {
+ this.setYTicksForAxis('y' + i + 'axis', this.jqplotParams.axes['y' + i + 'axis']);
}
- };
-
- this.params.piwikTicks = {
- showTicks: true,
- showGrid: false,
- showHighlight: false,
- tickColor: this.tickColor
- };
-
- this.params.axes.xaxis.renderer = $.jqplot.CategoryAxisRenderer;
- this.params.axes.xaxis.tickOptions = {
- showGridline: false
- };
-
- this.params.canvasLegend = {
- show: true
- };
- },
-
- // ------------------------------------------------------------
- // HELPER METHODS
- // ------------------------------------------------------------
-
- /** Generate ticks in y direction */
- setYTicks: function () {
- // default axis
- this.setYTicksForAxis('yaxis', this.params.axes.yaxis);
- // other axes: y2axis, y3axis...
- for (var i = 2; typeof this.params.axes['y' + i + 'axis'] != 'undefined'; i++) {
- this.setYTicksForAxis('y' + i + 'axis', this.params.axes['y' + i + 'axis']);
- }
- },
-
- setYTicksForAxis: function (axisName, axis) {
- // calculate maximum x value of all data sets
- var maxCrossDataSets = 0;
- for (var i = 0; i < this.data.length; i++) {
- if (this.params.series[i].yaxis == axisName) {
- var maxValue = Math.max.apply(Math, this.data[i]);
- if (maxValue > maxCrossDataSets) {
- maxCrossDataSets = maxValue;
+ },
+
+ setYTicksForAxis: function (axisName, axis) {
+ // calculate maximum x value of all data sets
+ var maxCrossDataSets = 0;
+ for (var i = 0; i < this.data.length; i++) {
+ if (this.jqplotParams.series[i].yaxis == axisName) {
+ var maxValue = Math.max.apply(Math, this.data[i]);
+ if (maxValue > maxCrossDataSets) {
+ maxCrossDataSets = maxValue;
+ }
+ maxCrossDataSets = parseFloat(maxCrossDataSets);
}
- maxCrossDataSets = parseFloat(maxCrossDataSets);
}
- }
-
- // add little padding on top
- maxCrossDataSets += Math.max(1, Math.round(maxCrossDataSets * .03));
- // round to the nearest multiple of ten
- if (maxCrossDataSets > 15) {
- maxCrossDataSets = maxCrossDataSets + 10 - maxCrossDataSets % 10;
- }
+ // add little padding on top
+ maxCrossDataSets += Math.max(1, Math.round(maxCrossDataSets * .03));
- if (maxCrossDataSets == 0) {
- maxCrossDataSets = 1;
- }
-
- // make sure percent axes don't go above 100%
- if (axis.tickOptions.formatString.substring(2, 3) == '%' && maxCrossDataSets > 100) {
- maxCrossDataSets = 100;
- }
+ // round to the nearest multiple of ten
+ if (maxCrossDataSets > 15) {
+ maxCrossDataSets = maxCrossDataSets + 10 - maxCrossDataSets % 10;
+ }
- // calculate y-values for ticks
- var ticks = [];
- var numberOfTicks = 2;
- var tickDistance = Math.ceil(maxCrossDataSets / numberOfTicks);
- for (var i = 0; i <= numberOfTicks; i++) {
- ticks.push(i * tickDistance);
- }
- axis.ticks = ticks;
- },
+ if (maxCrossDataSets == 0) {
+ maxCrossDataSets = 1;
+ }
- /** Get a formatted y values (with unit) */
- formatY: function (value, seriesIndex) {
- var floatVal = parseFloat(value);
- var intVal = parseInt(value, 10);
- if (Math.abs(floatVal - intVal) >= 0.005) {
- value = Math.round(floatVal * 100) / 100;
- } else if (parseFloat(intVal) == floatVal) {
- value = intVal;
- } else {
- value = floatVal;
- }
- if (typeof this.tooltip.yUnits[seriesIndex] != 'undefined') {
- value += this.tooltip.yUnits[seriesIndex];
- }
+ // make sure percent axes don't go above 100%
+ if (axis.tickOptions.formatString.substring(2, 3) == '%' && maxCrossDataSets > 100) {
+ maxCrossDataSets = 100;
+ }
- return value;
- },
+ // calculate y-values for ticks
+ var ticks = [];
+ var numberOfTicks = 2;
+ var tickDistance = Math.ceil(maxCrossDataSets / numberOfTicks);
+ for (var i = 0; i <= numberOfTicks; i++) {
+ ticks.push(i * tickDistance);
+ }
+ axis.ticks = ticks;
+ },
+
+ /** Get a formatted y values (with unit) */
+ formatY: function (value, seriesIndex) {
+ var floatVal = parseFloat(value);
+ var intVal = parseInt(value, 10);
+ if (Math.abs(floatVal - intVal) >= 0.005) {
+ value = Math.round(floatVal * 100) / 100;
+ } else if (parseFloat(intVal) == floatVal) {
+ value = intVal;
+ } else {
+ value = floatVal;
+ }
- /**
- * Add an external series toggle.
- * As opposed to addSeriesPicker, the external series toggle can only show/hide
- * series that are already loaded.
- *
- * @param seriesPickerClass a subclass of JQPlotExternalSeriesToggle
- * @param targetDivId
- * @param initiallyShowAll
- */
- addExternalSeriesToggle: function (seriesPickerClass, targetDivId, initiallyShowAll) {
- new seriesPickerClass(targetDivId, this.originalData, initiallyShowAll);
-
- if (!initiallyShowAll) {
- // initially, show only the first series
- this.data = [this.data[0]];
- this.params.series = [this.params.series[0]];
- }
- },
+ var axisId = this.jqplotParams.series[seriesIndex].yaxis;
+ var formatString = this.jqplotParams.axes[axisId].tickOptions.formatString;
+
+ return formatString.replace('%s', value);
+ },
+
+ /**
+ * Add an external series toggle.
+ * As opposed to addSeriesPicker, the external series toggle can only show/hide
+ * series that are already loaded.
+ *
+ * @param seriesPickerClass a subclass of JQPlotExternalSeriesToggle
+ * @param initiallyShowAll
+ */
+ addExternalSeriesToggle: function (seriesPickerClass, initiallyShowAll) {
+ new seriesPickerClass(this.targetDivId, this, initiallyShowAll);
+
+ if (!initiallyShowAll) {
+ // initially, show only the first series
+ this.data = [this.data[0]];
+ this.jqplotParams.series = [this.jqplotParams.series[0]];
+ }
+ },
+
+ /**
+ * Sets the colors used to render this graph.
+ */
+ _setColors: function () {
+ var colorManager = piwik.ColorManager,
+ seriesColorNames = ['series1', 'series2', 'series3', 'series4', 'series5',
+ 'series6', 'series7', 'series8', 'series9', 'series10'];
+
+ var viewDataTable = $('#' + this.workingDivId).data('dataTableInstance').param['viewDataTable'];
+
+ var graphType;
+ if (viewDataTable == 'graphEvolution') {
+ graphType = 'evolution';
+ } else if (viewDataTable == 'graphPie') {
+ graphType = 'pie';
+ } else if (viewDataTable == 'graphVerticalBar') {
+ graphType = 'bar';
+ }
+
+ var namespace = graphType + '-graph-colors';
- /**
- * Sets the colors used to render this graph.
- */
- _setColors: function () {
- var colorManager = piwik.ColorManager,
- seriesColorNames = ['series1', 'series2', 'series3', 'series4', 'series5',
- 'series6', 'series7', 'series8', 'series9', 'series10'];
-
- var viewDataTable = $('#' + this.dataTableId).data('dataTableInstance').param['viewDataTable'];
-
- var graphType;
- if (viewDataTable == 'graphEvolution') {
- graphType = 'evolution';
- } else if (viewDataTable == 'graphPie') {
- graphType = 'pie';
- } else if (viewDataTable == 'graphVerticalBar') {
- graphType = 'bar';
+ this.jqplotParams.seriesColors = colorManager.getColors(namespace, seriesColorNames, true);
+ this.jqplotParams.grid.background = colorManager.getColor(namespace, 'grid-background');
+ this.jqplotParams.grid.borderColor = colorManager.getColor(namespace, 'grid-border');
+ this.tickColor = colorManager.getColor(namespace, 'ticks');
+ this.singleMetricColor = colorManager.getColor(namespace, 'single-metric-label')
}
-
- var namespace = graphType + '-graph-colors';
-
- this.originalData.params.seriesColors = this.params.seriesColors =
- colorManager.getColors(namespace, seriesColorNames, true);
- this.params.grid.background = colorManager.getColor(namespace, 'grid-background');
- this.params.grid.borderColor = colorManager.getColor(namespace, 'grid-border');
- this.tickColor = colorManager.getColor(namespace, 'ticks');
- this.singleMetricColor = colorManager.getColor(namespace, 'single-metric-label')
- }
-};
+ });
+})(jQuery, require);
// ----------------------------------------------------------------
// EXTERNAL SERIES TOGGLE
// Use external dom elements and their events to show/hide series
// ----------------------------------------------------------------
-function JQPlotExternalSeriesToggle(targetDivId, originalConfig, initiallyShowAll) {
+function JQPlotExternalSeriesToggle(targetDivId, jqplotObject, initiallyShowAll) {
this.init(targetDivId, originalConfig, initiallyShowAll);
}
JQPlotExternalSeriesToggle.prototype = {
- init: function (targetDivId, originalConfig, initiallyShowAll) {
+ init: function (targetDivId, jqplotObject, initiallyShowAll) {
this.targetDivId = targetDivId;
- this.originalConfig = originalConfig;
- this.originalData = originalConfig.data;
- this.originalSeries = originalConfig.params.series;
- this.originalAxes = originalConfig.params.axes;
- this.originalTooltipUnits = originalConfig.tooltip.yUnits;
- this.originalSeriesColors = originalConfig.params.seriesColors;
+ this.jqplotObject = jqplotObject;
+ this.originalData = jqplotObject.data;
+ this.originalSeries = jqplotObject.jqplotParams.series;
+ this.originalAxes = jqplotObject.jqplotParams.axes;
+ this.originalParams = jqplotObject.jqplotParams;
+ this.originalSeriesColors = jqplotObject.jqplotParams.seriesColors;
this.initiallyShowAll = initiallyShowAll;
this.activated = [];
@@ -673,18 +769,16 @@ JQPlotExternalSeriesToggle.prototype = {
// build new config and replot
var usedAxes = [];
- var config = this.originalConfig;
+ var config = {data: this.originalData, params: this.originalParams};
config.data = [];
config.params.series = [];
config.params.axes = {xaxis: this.originalAxes.xaxis};
- config.tooltip.yUnits = [];
config.params.seriesColors = [];
for (var j = 0; j < this.activated.length; j++) {
if (!this.activated[j]) {
continue;
}
config.data.push(this.originalData[j]);
- config.tooltip.yUnits.push(this.originalTooltipUnits[j]);
config.params.seriesColors.push(this.originalSeriesColors[j]);
config.params.series.push($.extend(true, {}, this.originalSeries[j]));
// build array of used axes
@@ -709,7 +803,9 @@ JQPlotExternalSeriesToggle.prototype = {
series.yaxis = replaceAxes[series.yaxis];
}
- this.target.trigger('replot', config);
+ this.jqplotObject.data = config.data;
+ this.jqplotObject.jqplotParams = config.params;
+ this.jqplotObject.render();
},
// can be overridden
@@ -720,8 +816,8 @@ JQPlotExternalSeriesToggle.prototype = {
// ROW EVOLUTION SERIES TOGGLE
-function RowEvolutionSeriesToggle(targetDivId, originalConfig, initiallyShowAll) {
- this.init(targetDivId, originalConfig, initiallyShowAll);
+function RowEvolutionSeriesToggle(targetDivId, jqplotData, initiallyShowAll) {
+ this.init(targetDivId, jqplotData, initiallyShowAll);
}
RowEvolutionSeriesToggle.prototype = JQPlotExternalSeriesToggle.prototype;
@@ -1040,7 +1136,7 @@ RowEvolutionSeriesToggle.prototype.beforeReplot = function () {
$.jqplot.preInitHooks.push(function (target, data, options) {
var SeriesPicker = require('piwik/DataTableVisualizations/Widgets').SeriesPicker;
- // add plugin as an attribute to the plot
+ // create the series picker
var dataTable = $('#' + target).closest('.dataTable').data('dataTableInstance');
var seriesPicker = new SeriesPicker(dataTable);
@@ -1053,7 +1149,7 @@ RowEvolutionSeriesToggle.prototype.beforeReplot = function () {
// handle seriesPicked event
$(seriesPicker).bind('seriesPicked', function (e, columns, rows) {
- $('#' + this.dataTableId + ' .piwik-graph').trigger('changeSeries', [columns, rows]);
+ dataTable.changeSeries(columns, rows);
});
this.plugins.seriesPicker = seriesPicker;
@@ -1201,4 +1297,4 @@ RowEvolutionSeriesToggle.prototype.beforeReplot = function () {
$.jqplot.preInitHooks.push($.jqplot.PieLegend.init);
$.jqplot.postDrawHooks.push($.jqplot.PieLegend.postDraw);
-})(jQuery);
+})(jQuery); \ No newline at end of file
diff --git a/plugins/CoreVisualizations/javascripts/seriesPicker.js b/plugins/CoreVisualizations/javascripts/seriesPicker.js
index f483ba167e..c851b71ba8 100644
--- a/plugins/CoreVisualizations/javascripts/seriesPicker.js
+++ b/plugins/CoreVisualizations/javascripts/seriesPicker.js
@@ -70,7 +70,7 @@
/**
* Initializes the series picker by creating the element. Must be called when
- * the data table the picker is being attached to is ready for it to be drawn.
+ * the datatable the picker is being attached to is ready for it to be drawn.
*/
init: function () {
if (!this.show) {
diff --git a/plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig b/plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig
index 15f1a0e34f..a87fcb6123 100644
--- a/plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig
+++ b/plugins/CoreVisualizations/templates/_dataTableViz_jqplotGraph.twig
@@ -1,9 +1,4 @@
<div class="jqplot-graph">
- <div class="piwik-graph"
- data-data="{{ data|e('html') }}"
- {% if properties.visualization_properties.external_series_toggle %}
- data-external-series-toggle="{{ properties.visualization_properties.external_series_toggle }}"
- data-external-series-show-all="{% if properties.visualization_properties.external_series_toggle_show_all %}1{% else %}0{% endif %}"
- {% endif %}>
+ <div class="piwik-graph" data-data="{{ data|e('html') }}">
</div>
</div> \ No newline at end of file