File size: 6,597 Bytes
76a7a50 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | /**
* Matomo - free/libre analytics platform
*
* Series Picker control addition for DataTable visualizations.
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function ($, require) {
/**
* This class creates and manages the Series Picker for certain DataTable visualizations.
*
* To add the series picker to your DataTable visualization, create a SeriesPicker instance
* and after your visualization has been rendered, call the 'init' method.
*
* To customize SeriesPicker placement and behavior, you can bind callbacks to the following
* events before calling 'init':
*
* 'placeSeriesPicker': Triggered after the DOM element for the series picker link is created.
* You must use this event to add the link to the dataTable. YOu can also
* use this event to position the link however you want.
*
* Callback Signature: function () {}
*
* 'seriesPicked': Triggered when the user selects one or more columns/rows.
*
* Callback Signature: function (eventInfo, columns, rows) {}
*
* Events are triggered via jQuery, so you bind callbacks to them like this:
*
* var picker = new SeriesPicker(dataTable);
* $(picker).bind('placeSeriesPicker', function () {
* $(this.domElem).doSomething(...);
* });
*
* @param {dataTable} dataTable The dataTable instance to add a series picker to.
* @constructor
* @deprecated use the SeriesPicker Vue component instead
*/
var SeriesPicker = function (dataTable) {
this.domElem = null;
this.app = null;
this.dataTableId = dataTable.workingDivId;
// the columns that can be selected
this.selectableColumns = dataTable.props.selectable_columns;
// the rows that can be selected
this.selectableRows = dataTable.props.selectable_rows;
// render the picker?
this.show = !! dataTable.props.show_series_picker
&& (this.selectableColumns || this.selectableRows);
// can multiple rows we selected?
this.multiSelect = !! dataTable.props.allow_multi_select_series_picker;
// render the new "Choose metrics" button variant instead of the legacy "+" popover.
// Opted into by jqplot graphs.
this.useChooseMetricsButton = false;
};
SeriesPicker.prototype = {
/**
* Initializes the series picker by creating the element. Must be called when
* the datatable the picker is being attached to is ready for it to be drawn.
*/
init: function () {
if (!this.show) {
return;
}
var self = this;
var selectedColumns = this.selectableColumns
.filter(isItemDisplayed)
.map(function (columnConfig) {
return columnConfig.column;
});
var selectedRows = this.selectableRows
.filter(isItemDisplayed)
.map(function (rowConfig) {
return rowConfig.matcher;
});
// initialize dom element
this.domElem = $('<div class="series-picker-wrapper" style="display:inline-block"><div></div></div>');
$(this).trigger('placeSeriesPicker');
var createVNode = Vue.createVNode;
var createVueApp = CoreHome.createVueApp;
var PickerComponent = self.useChooseMetricsButton
? CoreVisualizations.MetricsPicker
: CoreVisualizations.SeriesPicker;
this.app = createVueApp({
render: function () {
return createVNode(PickerComponent, {
multiselect: self.multiSelect,
selectableColumns: self.selectableColumns,
selectableRows: self.selectableRows,
selectedColumns: selectedColumns,
selectedRows: selectedRows,
onSelect: function selectionChanged(event) {
var columns = event.columns, rows = event.rows;
if (columns.length === 0 && rows.length === 0) {
return;
}
rows = rows.map(encodeURIComponent);
$(self).trigger('seriesPicked', [columns, rows]);
// inform dashboard widget about changed parameters (to be restored on reload)
var UI = require('piwik/UI');
var params = {
columns: columns,
columns_to_display: columns,
rows: rows,
rows_to_display: rows
};
var tableNode = $('#' + self.dataTableId);
UI.DataTable.prototype.notifyWidgetParametersChange(tableNode, params);
}
});
}
});
this.app.mount(this.domElem.children()[0]);
function isItemDisplayed(columnOrRowConfig) {
return columnOrRowConfig.displayed;
}
},
/**
* Unmounts the picker's Vue app so directive listeners (e.g. ExpandOnClick)
* are removed and it can be garbage collected. Safe to call when unmounted.
*/
destroy: function () {
if (this.app) {
this.app.unmount();
this.app = null;
}
$(this).off();
if (this.domElem) {
this.domElem.remove();
this.domElem = null;
}
},
/**
* Returns the translation of a metric that can be selected.
*
* @param {String} metric The name of the metric, ie, 'nb_visits' or 'nb_actions'.
* @return {String} The metric translation. If one cannot be found, the metric itself
* is returned.
*/
getMetricTranslation: function (metric) {
for (var i = 0; i !== this.selectableColumns.length; ++i) {
if (this.selectableColumns[i].column === metric) {
return this.selectableColumns[i].translation;
}
}
return metric;
}
};
var exports = require('piwik/DataTableVisualizations/Widgets');
exports.SeriesPicker = SeriesPicker;
})(jQuery, require);
|