jenkins-bot has submitted this change and it was merged.
Change subject: Edit a single graph data pipeline within VE
......................................................................
Edit a single graph data pipeline within VE
* Added a new Data tab in the graph dialog, which allows the user
to edit the data entries in a graph.
* The user can add and delete rows of data in a data sheet.
Bug: T100353
Change-Id: I8cc4cf5804c61a08c378ae414dd416a30b325dca
---
M Graph.body.php
M Graph.hooks.php
M i18n/en.json
M i18n/qqq.json
M modules/ve-graph/ve.dm.MWGraphModel.js
M modules/ve-graph/ve.ui.MWGraphDialog.js
6 files changed, 163 insertions(+), 7 deletions(-)
Approvals:
Mooeypoo: Looks good to me, approved
jenkins-bot: Verified
diff --git a/Graph.body.php b/Graph.body.php
index 1780a43..2a46ee7 100644
--- a/Graph.body.php
+++ b/Graph.body.php
@@ -4,7 +4,7 @@
* @license MIT
* @file
*
- * @author Dan Andreescu, Yuri Astrakhan
+ * @author Dan Andreescu, Yuri Astrakhan, Frédéric Bolduc
*/
namespace Graph;
diff --git a/Graph.hooks.php b/Graph.hooks.php
index daf51fd..156b723 100644
--- a/Graph.hooks.php
+++ b/Graph.hooks.php
@@ -47,8 +47,10 @@
'graph-ve-dialog-edit-field-graph-type',
'graph-ve-dialog-edit-field-raw-json',
'graph-ve-dialog-edit-json-invalid',
+ 'graph-ve-dialog-edit-page-data',
'graph-ve-dialog-edit-page-general',
'graph-ve-dialog-edit-page-raw',
+ 'graph-ve-dialog-edit-table-row-delete',
'graph-ve-dialog-edit-title',
'graph-ve-dialog-edit-type-area',
'graph-ve-dialog-edit-type-bar',
diff --git a/i18n/en.json b/i18n/en.json
index 5fd6e33..0321355 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -2,7 +2,8 @@
"@metadata": {
"authors": [
"Dan Andreescu",
- "Yuri Astrakhan"
+ "Yuri Astrakhan",
+ "Frédéric Bolduc"
]
},
"graph-desc": "Allows <graph> tags or entire pages to become
[http://trifacta.github.io/vega/ Vega]-based graphs",
@@ -11,8 +12,10 @@
"graph-ve-dialog-edit-field-graph-type": "Graph type",
"graph-ve-dialog-edit-field-raw-json": "Raw JSON specification",
"graph-ve-dialog-edit-json-invalid": "Invalid JSON string",
+ "graph-ve-dialog-edit-page-data": "Data",
"graph-ve-dialog-edit-page-general": "General",
"graph-ve-dialog-edit-page-raw": "Raw data",
+ "graph-ve-dialog-edit-table-row-delete": "Delete row",
"graph-ve-dialog-edit-title": "Edit graph",
"graph-ve-dialog-edit-type-area": "Area graph",
"graph-ve-dialog-edit-type-bar": "Bar graph",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 3eb63df..317d61f 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -13,8 +13,10 @@
"graph-ve-dialog-edit-field-graph-type": "Label for graph type",
"graph-ve-dialog-edit-field-raw-json": "Label for the raw JSON
specification in the graph editing dialog",
"graph-ve-dialog-edit-json-invalid": "Validation label for the JSON
specification string",
+ "graph-ve-dialog-edit-page-data": "Label for the graph dialog data
entry page",
"graph-ve-dialog-edit-page-general": "Label for the general page in the
graph edit dialog\n{{Identical|General}}",
"graph-ve-dialog-edit-page-raw": "Label for the raw data page in the
graph edit dialog",
+ "graph-ve-dialog-edit-table-row-delete": "Tooltip for the delete row
button in table widgets",
"graph-ve-dialog-edit-title": "Title for the graph editing dialog",
"graph-ve-dialog-edit-type-area": "Label for area graph",
"graph-ve-dialog-edit-type-bar": "Label for bar graph",
diff --git a/modules/ve-graph/ve.dm.MWGraphModel.js
b/modules/ve-graph/ve.dm.MWGraphModel.js
index 04b2eeb..6560cde 100644
--- a/modules/ve-graph/ve.dm.MWGraphModel.js
+++ b/modules/ve-graph/ve.dm.MWGraphModel.js
@@ -298,6 +298,75 @@
};
/**
+ * Get the fields for a data pipeline
+ *
+ * @param {number} [id] The pipeline's id
+ * @returns {Object} The fields for the pipeline
+ */
+ve.dm.MWGraphModel.prototype.getPipelineFields = function ( id ) {
+ return Object.keys( this.spec.data[ id ].values[0] );
+};
+
+/**
+ * Get a data pipeline
+ *
+ * @param {number} [id] The pipeline's id
+ * @returns {Object} The data pipeline within the spec
+ */
+ve.dm.MWGraphModel.prototype.getPipeline = function ( id ) {
+ return this.spec.data[ id ];
+};
+
+/**
+ * Set the field value of an entry in a pipeline
+ *
+ * @param {number} [entry] ID of the entry
+ * @param {string} [field] The field to change
+ * @param {number} [value] The new value
+ * @fires specChange
+ */
+ve.dm.MWGraphModel.prototype.setEntryField = function ( entry, field, value ) {
+ if ( this.spec.data[0].values[ entry ] === undefined ) {
+ this.spec.data[0].values[ entry ] = this.buildNewEntry( 0 );
+ }
+ this.spec.data[0].values[ entry ][ field ] = value;
+
+ this.emit( 'specChange', this.spec );
+};
+
+/**
+ * Builds and returns a new entry for a pipeline
+ *
+ * @private
+ * @param {number} [pipelineId] The ID of the pipeline the entry is intended
for
+ * @returns {Object} The new entry
+ */
+ve.dm.MWGraphModel.prototype.buildNewEntry = function ( pipelineId ) {
+ var fields = this.getPipelineFields( pipelineId ),
+ newEntry = {},
+ i;
+
+ for ( i = 0; i < fields.length; i++ ) {
+ newEntry[ fields[i] ] = '';
+ }
+
+ return newEntry;
+};
+
+/**
+ * Removes an entry from a pipeline
+ *
+ * @param {number} [index] The index of the entry to delete
+ * @fires specChange
+ */
+ve.dm.MWGraphModel.prototype.removeEntry = function ( index ) {
+ // FIXME: Support multiple pipelines
+ this.spec.data[0].values.splice( index, 1 );
+
+ this.emit( 'specChange', this.spec );
+};
+
+/**
* Returns whether the current spec has been modified since the dialog was
opened
*
* @return {boolean} The spec was changed
diff --git a/modules/ve-graph/ve.ui.MWGraphDialog.js
b/modules/ve-graph/ve.ui.MWGraphDialog.js
index 4d4c741..07c051c 100644
--- a/modules/ve-graph/ve.ui.MWGraphDialog.js
+++ b/modules/ve-graph/ve.ui.MWGraphDialog.js
@@ -79,10 +79,11 @@
} );
this.generalPage = new OO.ui.PageLayout( 'general' );
+ this.dataPage = new OO.ui.PageLayout( 'data' );
this.rawPage = new OO.ui.PageLayout( 'raw' );
this.rootLayout.addPages( [
- this.generalPage, this.rawPage
+ this.generalPage, this.dataPage, this.rawPage
] );
/* Graph type page */
@@ -104,6 +105,11 @@
graphTypeField.$element,
this.unknownGraphTypeWarningLabel.$element
);
+
+ /* Data page */
+ this.dataPage.getOutlineItem()
+ .setIcon( 'parameter' )
+ .setLabel( ve.msg( 'graph-ve-dialog-edit-page-data' ) );
/* Raw JSON page */
this.rawPage.getOutlineItem()
@@ -147,7 +153,7 @@
return ve.ui.MWGraphDialog.super.prototype.getSetupProcess.call( this,
data )
.next( function () {
// Set up model
- spec = this.selectedNode.getSpec();
+ spec = ve.copy( this.selectedNode.getSpec() );
this.graphModel = new ve.dm.MWGraphModel( spec );
this.graphModel.connect( this, {
@@ -174,7 +180,15 @@
.first( function () {
// Kill model
this.graphModel.disconnect( this );
+
this.graphModel = null;
+
+ // Clear data page
+ this.dataTable.clearItems();
+ this.dataTable.disconnect( this );
+ this.dataTable.$element.remove();
+
+ this.dataTable = null;
}, this );
};
@@ -220,9 +234,6 @@
label: ve.msg( 'graph-ve-dialog-edit-type-unknown' )
};
- // JSON text input
- this.jsonTextInput.setValue( this.graphModel.getSpecString() );
-
// Graph type
if ( graphType === 'unknown' ) {
options.push( unknownGraphTypeOption );
@@ -231,6 +242,55 @@
this.graphTypeDropdownInput
.setOptions( options )
.setValue( graphType );
+
+ // Data
+ this.updateDataPage();
+
+ // JSON text input
+ this.jsonTextInput.setValue( this.graphModel.getSpecString() );
+};
+
+/**
+ * Update data page widgets based on the current spec
+ */
+ve.ui.MWGraphDialog.prototype.updateDataPage = function () {
+ var pipeline = this.graphModel.getPipeline( 0 ),
+ i, row, rows, inputs, entry, field;
+
+ this.dataTable = new ve.ui.TableWidget(
this.graphModel.getPipelineFields( 0 ) );
+
+ // Iterate over each data entry
+ rows = [];
+ for ( i = 0; i < pipeline.values.length; i++ ) {
+ entry = pipeline.values[i];
+ row = new ve.ui.RowWidget();
+ inputs = [];
+
+ for ( field in entry ) {
+ if ( entry.hasOwnProperty( field ) ) {
+ inputs.push( new OO.ui.TextInputWidget( {
+ data: field,
+ value: entry[field],
+ validate: /^[0-9]+$/,
+ inputFilter:
this.dataTable.filterCellInput
+ } ) );
+ }
+ }
+
+ row.addItems( inputs );
+ rows.push( row );
+ }
+
+ this.dataTable.addItems( rows );
+
+ // Event listeners
+ this.dataTable.connect( this, {
+ change: 'onDataInputChange',
+ deleteRow: 'onDataInputRowDelete'
+ } );
+
+ // Initialization
+ this.dataPage.$element.append( this.dataTable.$element );
};
/**
@@ -283,6 +343,26 @@
};
/**
+ * React to data input change
+ * @param {number} [entry] The index of the entry updated
+ * @param {string} [field] The field that changed
+ * @param {string} [value] The new value for the field
+ */
+ve.ui.MWGraphDialog.prototype.onDataInputChange = function ( entry, field,
value ) {
+ if ( !isNaN( value ) ) {
+ this.graphModel.setEntryField( entry, field, parseFloat( value
) );
+ }
+};
+
+/**
+ * React to data input row deletion
+ * @param {number} [rowIndex] The index of the row deleted
+ */
+ve.ui.MWGraphDialog.prototype.onDataInputRowDelete = function ( rowIndex ) {
+ this.graphModel.removeEntry( rowIndex );
+};
+
+/**
* React to spec change
*
* @private
--
To view, visit https://gerrit.wikimedia.org/r/217170
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I8cc4cf5804c61a08c378ae414dd416a30b325dca
Gerrit-PatchSet: 23
Gerrit-Project: mediawiki/extensions/Graph
Gerrit-Branch: master
Gerrit-Owner: Ferdbold <[email protected]>
Gerrit-Reviewer: Ferdbold <[email protected]>
Gerrit-Reviewer: Legoktm <[email protected]>
Gerrit-Reviewer: Mooeypoo <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits