diff --git a/apps/spreadsheeteditor/main/app/template/ChartSettingsDlg.template b/apps/spreadsheeteditor/main/app/template/ChartSettingsDlg.template index afad9d9856..f73333cf48 100644 --- a/apps/spreadsheeteditor/main/app/template/ChartSettingsDlg.template +++ b/apps/spreadsheeteditor/main/app/template/ChartSettingsDlg.template @@ -9,27 +9,27 @@ -
-
- - - - - - - - - - -
- -
-
-
- -
-
-
+ + + + + + + + + + + + + + + + + + + + +
diff --git a/apps/spreadsheeteditor/main/app/view/ChartDataDialog.js b/apps/spreadsheeteditor/main/app/view/ChartDataDialog.js new file mode 100644 index 0000000000..496d0007c0 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/ChartDataDialog.js @@ -0,0 +1,565 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2020 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ + +/** + * ChartDataDialog.js + * + * Created by Julia Radzhabova on 06.07.2020 + * Copyright (c) 2020 Ascensio System SIA. All rights reserved. + * + */ + +define([ + 'common/main/lib/util/utils', + 'common/main/lib/component/MetricSpinner', + 'common/main/lib/component/ComboBox', + 'common/main/lib/component/ListView', + 'common/main/lib/view/AdvancedSettingsWindow' +], function () { 'use strict'; + + SSE.Views.ChartDataDialog = Common.Views.AdvancedSettingsWindow.extend(_.extend({ + options: { + contentWidth: 370, + height: 490 + }, + + initialize : function(options) { + var me = this; + + _.extend(this.options, { + title: this.textTitle, + template: [ + '
', + '
', + '
', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '
', + '', + '
', + '
', + '
', + '', + '
', + '
', + '', + '', + '', + '
', + '
', + '
', + '
', + '
', + '', + '
', + '', + '
', + '
', + '', + '
', + '
', + '
', + '
', + '
' + ].join('') + }, options); + + this.handler = options.handler; + + Common.Views.AdvancedSettingsWindow.prototype.initialize.call(this, this.options); + + this._noApply = true; + this._changedProps = null; + + this.api = this.options.api; + this.chartSettings = this.options.chartSettings; + this.currentChartType = Asc.c_oAscChartTypeSettings.barNormal; + }, + + render: function() { + Common.Views.AdvancedSettingsWindow.prototype.render.call(this); + var me = this; + + this.txtDataRange = new Common.UI.InputFieldBtn({ + el : $('#chart-dlg-txt-range'), + name : 'range', + style : 'width: 100%;', + btnHint : this.textSelectData, + allowBlank : true + // validateOnChange: true + }); + this.txtDataRange.on('button:click', _.bind(this.onSelectData, this)); + this.txtDataRange.on('changed:after', function(input, newValue, oldValue, e) { + if (newValue == oldValue) return; + me.changeChartRange(newValue); + }); + + // Chart data + this.seriesList = new Common.UI.ListView({ + el: $('#chart-dlg-series-list', this.$window), + store: new Common.UI.DataViewStore(), + emptyText: '', + scrollAlwaysVisible: true, + itemTemplate: _.template('
<%= value %>
') + }); + this.seriesList.onKeyDown = _.bind(this.onListKeyDown, this, 'series'); + this.seriesList.on('item:select', _.bind(this.onSelectSeries, this)); + this.seriesList.store.comparator = function(rec) { + return rec.get("order"); + }; + + this.btnAdd = new Common.UI.Button({ + el: $('#chart-dlg-btn-add') + }); + this.btnAdd.on('click', _.bind(this.onAddSeries, this, false)); + + this.btnDelete = new Common.UI.Button({ + el: $('#chart-dlg-btn-delete') + }); + this.btnDelete.on('click', _.bind(this.onDeleteSeries, this)); + + this.btnEdit = new Common.UI.Button({ + el: $('#chart-dlg-btn-edit') + }); + this.btnEdit.on('click', _.bind(this.onEditSeries, this, false)); + + this.btnUp = new Common.UI.Button({ + parentEl: $('#chart-dlg-btn-up'), + cls: 'btn-toolbar', + iconCls: 'caret-up', + hint: this.textUp + }); + this.btnUp.on('click', _.bind(this.onMoveClick, this, true)); + + this.btnDown = new Common.UI.Button({ + parentEl: $('#chart-dlg-btn-down'), + cls: 'btn-toolbar', + iconCls: 'caret-down', + hint: this.textDown + }); + this.btnDown.on('click', _.bind(this.onMoveClick, this, false)); + + this.btnSwitch = new Common.UI.Button({ + el: $('#chart-dlg-btn-switch') + }); + this.btnSwitch.on('click', _.bind(this.onSwitch, this)); + + this.categoryList = new Common.UI.ListView({ + el: $('#chart-dlg-category-list', this.$window), + store: new Common.UI.DataViewStore(), + emptyText: '', + scrollAlwaysVisible: true, + itemTemplate: _.template('
<%= value %>
') + }); + + this.btnEditCategory = new Common.UI.Button({ + el: $('#chart-dlg-btn-category-edit') + }); + this.btnEditCategory.on('click', _.bind(this.onEditCategory, this, false)); + + this.afterRender(); + }, + + afterRender: function() { + this._setDefaults(this.chartSettings); + }, + + show: function() { + Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); + + var me = this; + _.delay(function(){ + me.txtDataRange.cmpEl.find('input').focus(); + },50); + }, + + close: function () { + this.api.asc_onCloseChartFrame(); + Common.Views.AdvancedSettingsWindow.prototype.close.apply(this, arguments); + }, + + _setDefaults: function (props) { + var me = this; + if (props ){ + this.chartSettings = props; + + this.currentChartType = props.getType(); + + var value = props.getRange(); + this.txtDataRange.setValue((value) ? value : ''); + + this.txtDataRange.validation = function(value) { + return true; + }; + + this.updateSeriesList(props.getSeries(), 0); + this.updateCategoryList(props.getCatValues()); + } + this.updateButtons(); + }, + + getSettings: function () { + return { chartSettings: this.chartSettings}; + }, + + onDlgBtnClick: function(event) { + var state = (typeof(event) == 'object') ? event.currentTarget.attributes['result'].value : event; + if (state == 'ok') { + if (!this.isRangeValid()) return; + this.handler && this.handler.call(this, state, (state == 'ok') ? this.getSettings() : undefined); + } + + this.close(); + }, + + onPrimary: function() { + this.onDlgBtnClick('ok'); + return false; + }, + + isRangeValid: function() { + var isvalid; + isvalid = this.chartSettings.isValidRange(this.txtDataRange.getValue()); + if (isvalid === true || isvalid == Asc.c_oAscError.ID.No) + return true; + + var error = this.textInvalidRange; + switch (isvalid) { + case Asc.c_oAscError.ID.StockChartError: + error = this.errorStockChart; + break; + case Asc.c_oAscError.ID.MaxDataSeriesError: + error = this.errorMaxRows; + break; + case Asc.c_oAscError.ID.MaxDataPointsError: + error = this.errorMaxPoints; + break; + case Asc.c_oAscError.ID.ErrorInFormula: + error = this.errorInFormula; + break; + case Asc.c_oAscError.ID.InvalidReference: + error = this.errorInvalidReference; + break; + case Asc.c_oAscError.ID.NoSingleRowCol: + error = this.errorNoSingleRowCol; + break; + case Asc.c_oAscError.ID.NoValues: + error = this.errorNoValues; + break; + } + Common.UI.warning({msg: error, maxwidth: 600}); + return false; + }, + + changeChartRange: function(settings) { + var me = this; + if (me.isRangeValid(settings)) { + me.txtDataRange.checkValidate(); + me.chartSettings.setRange(settings); + + me.updateSeriesList(me.chartSettings.getSeries(), 0); + me.updateCategoryList(me.chartSettings.getCatValues()); + me.updateButtons(); + } + }, + + onSelectData: function(input) { + var me = this; + if (me.api) { + var handlerDlg = function(dlg, result) { + if (result == 'ok') { + input.setValue(dlg.getSettings()); + _.delay(function(){ + me.changeChartRange(dlg.getSettings()); + },10); + } + }; + + var win = new SSE.Views.CellRangeDialog({ + handler: handlerDlg + }).on('close', function() { + me.show(); + }); + + var xy = me.$window.offset(); + me.hide(); + win.show(xy.left + 160, xy.top + 125); + win.setSettings({ + api : me.api, + range : me.txtDataRange.getValue(), + type : Asc.c_oAscSelectionDialogType.Chart, + validation: function() {return true;} + }); + } + }, + + onListKeyDown: function (type, e, data) { + var record = null, listView = this.seriesList; + + if (listView.disabled) return; + if (_.isUndefined(undefined)) data = e; + + if (data.keyCode==Common.UI.Keys.DELETE && !this.btnDelete.isDisabled()) { + // this.onDeleteSeries(); + } else { + Common.UI.DataView.prototype.onKeyDown.call(listView, e, data); + } + }, + + onSelectSeries: function(lisvView, itemView, record) { + this.updateMoveButtons(); + }, + + updateRange: function() { + this.txtDataRange.setValue(this.chartSettings.getRange() || ''); + }, + + updateButtons: function() { + this.btnEdit.setDisabled(this.seriesList.store.length<1); + this.btnDelete.setDisabled(this.seriesList.store.length<1); + this.btnSwitch.setDisabled(this.seriesList.store.length<1 || !this.chartSettings.getRange()); + this.updateMoveButtons(); + }, + + updateMoveButtons: function() { + var rec = this.seriesList.getSelectedRec(), + index = rec ? this.seriesList.store.indexOf(rec) : -1; + this.btnUp.setDisabled(index<1); + this.btnDown.setDisabled(index<0 || index==this.seriesList.store.length-1); + }, + + onAddSeries: function() { + var rec = (this.seriesList.store.length>0) ? this.seriesList.store.at(this.seriesList.store.length-1) : null, + isScatter = false, + me = this; + rec && (isScatter = rec.get('series').asc_IsScatter()); + me.chartSettings.startEditData(); + var series; + if (isScatter) { + series = me.chartSettings.addScatterSeries(); + } else { + series = me.chartSettings.addSeries(); + } + var handlerDlg = function(dlg, result) { + if (result == 'ok') { + me.updateRange(); + me.updateSeriesList(me.chartSettings.getSeries(), me.seriesList.store.length-1); + me.updateCategoryList(me.chartSettings.getCatValues()); + me.updateButtons(); + me.chartSettings.endEditData(); + me._isEditRanges = false; + } + }; + this.changeDataRange(1, {series: series, isScatter: isScatter}, handlerDlg); + }, + + onDeleteSeries: function() { + var rec = this.seriesList.getSelectedRec(); + if (rec) { + var order = rec.get('order'); + rec.get('series').asc_Remove(); + this.updateRange(); + this.updateSeriesList(this.chartSettings.getSeries(), order); + this.updateCategoryList(this.chartSettings.getCatValues()); + this.updateButtons(); + } + }, + + onEditSeries: function() { + var rec = this.seriesList.getSelectedRec(); + if (rec) { + var series = rec.get('series'), + isScatter = series.asc_IsScatter(), + me = this; + var handlerDlg = function(dlg, result) { + if (result == 'ok') { + rec.set('value', series.asc_getSeriesName()); + me.updateRange(); + me.updateCategoryList(me.chartSettings.getCatValues()); + me.updateButtons(); + me.chartSettings.endEditData(); + me._isEditRanges = false; + } + }; + me.chartSettings.startEditData(); + this.changeDataRange(1, {series: series, isScatter: isScatter }, handlerDlg); + } + }, + + onEditCategory: function() { + var me = this; + var handlerDlg = function(dlg, result) { + if (result == 'ok') { + me.updateCategoryList(me.chartSettings.getCatValues()); + me.updateRange(); + me.updateButtons(); + me.chartSettings.endEditData(); + me._isEditRanges = false; + } + }; + me.chartSettings.startEditData(); + this.changeDataRange(0, {category: this.chartSettings.getCatFormula(), values: this.chartSettings.getCatValues()}, handlerDlg); + }, + + changeDataRange: function(type, props, handlerDlg) { + var me = this; + var win = new SSE.Views.ChartDataRangeDialog({ + type: type, //series + isScatter: !!props.isScatter, + handler: handlerDlg + }).on('close', function() { + me._isEditRanges && me.chartSettings.cancelEditData(); + me._isEditRanges = false; + me.show(); + }); + + me._isEditRanges = true; + var xy = me.$window.offset(); + me.hide(); + win.show(xy.left + 160, xy.top + 125); + win.setSettings({ + api : me.api, + props : props, + chartSettings: me.chartSettings + }); + }, + + onMoveClick: function(up) { + var store = this.seriesList.store, + length = store.length, + rec = this.seriesList.getSelectedRec(); + if (rec) { + var index = store.indexOf(rec), + order = rec.get('order'), + newindex = up ? Math.max(0, index-1) : Math.min(length-1, index+1), + newrec = store.at(newindex), + neworder = newrec.get('order'); + store.add(store.remove(rec), {at: newindex}); + rec.set('order', neworder); + newrec.set('order', order); + up ? rec.get('series').asc_MoveUp() : rec.get('series').asc_MoveDown(); + this.seriesList.selectRecord(rec); + this.seriesList.scrollToRecord(rec); + this.updateRange(); + this.updateCategoryList(this.chartSettings.getCatValues()); + this.updateButtons(); + } + }, + + updateSeriesList: function(series, index) { + this.btnEditCategory.setDisabled(series && series.length>0 ? series[0].asc_IsScatter() : false); + + var arr = []; + var store = this.seriesList.store; + for (var i = 0, len = series.length; i < len; i++) + { + var item = series[i], + rec = new Common.UI.DataViewModel(); + rec.set({ + value: item.asc_getSeriesName(), + index: item.asc_getIdx(), + order: item.asc_getOrder(), + series: item + }); + arr.push(rec); + } + store.reset(arr); + (len>0) && this.seriesList.selectByIndex(Math.min(index || 0, store.length-1)); + }, + + updateCategoryList: function(categories) { + var arr = []; + var store = this.categoryList.store; + for (var i = 0, len = categories.length; i < len; i++) + { + var item = categories[i], + rec = new Common.UI.DataViewModel(); + rec.set({ + value: item + }); + arr.push(rec); + } + store.reset(arr); + (len>0) && this.categoryList.selectByIndex(0); + }, + + onSwitch: function() { + this.chartSettings.switchRowCol(); + this.updateSeriesList(this.chartSettings.getSeries(), 0); + this.updateCategoryList(this.chartSettings.getCatValues()); + this.updateRange(); + this.updateButtons(); + }, + + textTitle: 'Chart Data', + textInvalidRange: 'Invalid cells range', + textSelectData: 'Select data', + errorMaxRows: 'The maximum number of data series per chart is 255.', + errorStockChart: 'Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.', + errorMaxPoints: 'The maximum number of points in series per chart is 4096.', + textSeries: 'Legend Entries (Series)', + textAdd: 'Add', + textEdit: 'Edit', + textDelete: 'Remove', + textSwitch: 'Switch Row/Column', + textCategory: 'Horizontal (Category) Axis Labels', + textUp: 'Up', + textDown: 'Down', + textData: 'Chart data range', + errorInFormula: "There's an error in formula you entered.", + errorInvalidReference: 'The reference is not valid. Reference must be to an open worksheet.', + errorNoSingleRowCol: 'The reference is not valid. References for titles, values, sizes, or data labels must be a single cell, row, or column.', + errorNoValues: 'To create a chart, the series must contain at least one value.' + +}, SSE.Views.ChartDataDialog || {})) +}); diff --git a/apps/spreadsheeteditor/main/app/view/ChartDataRangeDialog.js b/apps/spreadsheeteditor/main/app/view/ChartDataRangeDialog.js new file mode 100644 index 0000000000..8fe5b5db25 --- /dev/null +++ b/apps/spreadsheeteditor/main/app/view/ChartDataRangeDialog.js @@ -0,0 +1,380 @@ +/* + * + * (c) Copyright Ascensio System SIA 2010-2020 + * + * This program is a free software product. You can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License (AGPL) + * version 3 as published by the Free Software Foundation. In accordance with + * Section 7(a) of the GNU AGPL its Section 15 shall be amended to the effect + * that Ascensio System SIA expressly excludes the warranty of non-infringement + * of any third-party rights. + * + * This program is distributed WITHOUT ANY WARRANTY; without even the implied + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For + * details, see the GNU AGPL at: http://www.gnu.org/licenses/agpl-3.0.html + * + * You can contact Ascensio System SIA at 20A-12 Ernesta Birznieka-Upisha + * street, Riga, Latvia, EU, LV-1050. + * + * The interactive user interfaces in modified source and object code versions + * of the Program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU AGPL version 3. + * + * Pursuant to Section 7(b) of the License you must retain the original Product + * logo when distributing the program. Pursuant to Section 7(e) we decline to + * grant you any rights under trademark law for use of our trademarks. + * + * All the Product's GUI elements, including illustrations and icon sets, as + * well as technical writing content are licensed under the terms of the + * Creative Commons Attribution-ShareAlike 4.0 International. See the License + * terms at http://creativecommons.org/licenses/by-sa/4.0/legalcode + * + */ +/** + * ChartDataRangeDialog.js + * + * Created by Julia Radzhabova on 02.07.2020 + * Copyright (c) 2020 Ascensio System SIA. All rights reserved. + * + */ + + +if (Common === undefined) + var Common = {}; + +define([ + 'common/main/lib/component/InputField', + 'common/main/lib/component/Window' +], function () { 'use strict'; + + SSE.Views.ChartDataRangeDialog = Common.UI.Window.extend(_.extend({ + options: { + type: 0, // 0 - category, 1 - series + width : 350, + cls : 'modal-dlg', + buttons: ['ok', 'cancel'] + }, + + initialize : function(options) { + this.type = options.type || 0; + this.isScatter = options.isScatter; + + _.extend(this.options, { + title: this.type==1 ? this.txtTitleSeries : this.txtTitleCategory + }, options); + + this.template = [ + '
', + '', + '', + '', + '', + '', + '', + '', + '', + '<% if (type==1) { %>', + '', + '', + '', + '', + '', + '', + '', + '<% if (isScatter) { %>', + '', + '', + '', + '', + '', + '', + '', + '<% } %>', + '<% } %>', + '
', + '', + '
', + '
', + '
', + '', + '
', + '', + '
', + '
', + '
', + '', + '
', + '', + '
', + '
', + '
', + '', + '
', + '
' + ].join(''); + + this.options.tpl = _.template(this.template)(this.options); + + Common.UI.Window.prototype.initialize.call(this, this.options); + }, + + render: function() { + Common.UI.Window.prototype.render.call(this); + + var $window = this.getChild(), + me = this; + + me.inputRange1 = new Common.UI.InputFieldBtn({ + el: $('#id-dlg-chart-range-range1'), + style: '100%', + textSelectData: 'Select data', + // validateOnChange: true, + validateOnBlur: false + }).on('changed:after', function(input, newValue, oldValue, e) { + if (newValue == oldValue) return; + me.updateRangeData(1, newValue); + }).on('changing', function(input, newValue, oldValue, e) { + if (newValue == oldValue) return; + // me.onInputChanging(input, newValue, oldValue); + }).on('button:click', _.bind(this.onSelectData, this, 1)); + this.lblRange1 = $window.find('#id-dlg-chart-range-lbl1'); + + me.inputRange2 = new Common.UI.InputFieldBtn({ + el: $('#id-dlg-chart-range-range2'), + style: '100%', + textSelectData: 'Select data', + // validateOnChange: true, + validateOnBlur: false + }).on('changed:after', function(input, newValue, oldValue, e) { + if (newValue == oldValue) return; + me.updateRangeData(2, newValue); + }).on('changing', function(input, newValue, oldValue, e) { + if (newValue == oldValue) return; + // me.onInputChanging(input, newValue, oldValue); + }).on('button:click', _.bind(this.onSelectData, this, 2)); + this.lblRange2 = $window.find('#id-dlg-chart-range-lbl2'); + + me.inputRange3 = new Common.UI.InputFieldBtn({ + el: $('#id-dlg-chart-range-range3'), + style: '100%', + textSelectData: 'Select data', + // validateOnChange: true, + validateOnBlur: false + }).on('changed:after', function(input, newValue, oldValue, e) { + if (newValue == oldValue) return; + me.updateRangeData(3, newValue); + }).on('changing', function(input, newValue, oldValue, e) { + if (newValue == oldValue) return; + // me.onInputChanging(input, newValue, oldValue); + }).on('button:click', _.bind(this.onSelectData, this, 3)); + this.lblRange3 = $window.find('#id-dlg-chart-range-lbl3'); + + $window.find('.dlg-btn').on('click', _.bind(this.onBtnClick, this)); + + _.defer(function(){ + me.inputRange1.cmpEl.find('input').focus(); + }, 10); + }, + + onPrimary: function() { + this._handleInput('ok'); + return false; + }, + + setSettings: function(settings) { + var me = this; + this.api = settings.api; + this.props = settings.props; + this.chartSettings = settings.chartSettings; + + if (this.type==1) { + if (this.props.series) { + var series = this.props.series; + this.inputRange1.setValue(series.asc_getName()); + this.lblRange1.html((this.inputRange1.getValue()!=='') ? ('= ' + (series.asc_getNameVal() || '')) : this.txtChoose); + if (this.props.isScatter) { + var arr = series.asc_getXValuesArr(); + this.inputRange2.setValue(series.asc_getXValues()); + this.lblRange2.html((this.inputRange2.getValue()!=='') ? ('= ' + (arr ? arr.join('; ') : '')) : this.txtChoose); + + this.inputRange3.setValue(series.asc_getYValues()); + arr = series.asc_getYValuesArr(); + this.lblRange3.html((this.inputRange3.getValue()!=='') ? ('= ' + (arr ? arr.join('; ') : '')) : this.txtChoose); + } else { + var arr = series.asc_getValuesArr(); + this.inputRange2.setValue(series.asc_getValues()); + this.lblRange2.html((this.inputRange2.getValue()!=='') ? ('= ' + (arr ? arr.join('; ') : '')) : this.txtChoose); + } + } + } else { + var arr = this.props.values; + this.inputRange1.setValue(this.props.category || ''); + this.lblRange1.html((this.inputRange1.getValue()!=='') ? ('= ' + (arr ? arr.join('; ') : '')) : this.txtChoose); + } + }, + + getSettings: function () { + return {name: this.inputRange1.getValue(), valuesX: this.inputRange2.getValue(), valuesY: this.inputRange3.getValue()}; + }, + + onSelectData: function(type, input) { + var me = this; + if (me.api) { + var handlerDlg = function(dlg, result) { + if (result == 'ok') { + input.setValue(dlg.getSettings()); + _.delay(function(){ + me.updateRangeData(type, dlg.getSettings()); + },10); + } + }; + + var win = new SSE.Views.CellRangeDialog({ + allowBlank: true, + handler: handlerDlg + }).on('close', function() { + // me.onInputChanging(input); + me.show(); + _.delay(function(){ + me._noApply = true; + input.cmpEl.find('input').focus(); + me._noApply = false; + },1); + }); + + var xy = me.$window.offset(); + me.hide(); + win.show(xy.left + 65, xy.top + 77); + win.setSettings({ + api : me.api, + range : !_.isEmpty(input.getValue()) ? input.getValue() : '', + type : Asc.c_oAscSelectionDialogType.Chart, + validation: function() {return true;} + }); + } + }, + + isRangeValid: function(type, value) { + var isvalid; + switch (type) { + case 1: + if (this.props.series) { + isvalid = this.props.series.asc_IsValidName(value); + } else { + isvalid = this.chartSettings.isValidCatFormula(value); + } + break; + case 2: + if (this.props.isScatter) { + isvalid = this.props.series.asc_IsValidXValues(value); + } else { + isvalid = this.props.series.asc_IsValidValues(value); + } + break; + case 3: + isvalid = this.props.series.asc_IsValidYValues(value); + break; + } + if (isvalid === true || isvalid == Asc.c_oAscError.ID.No) + return true; + + var error = this.textInvalidRange; + switch (isvalid) { + case Asc.c_oAscError.ID.StockChartError: + error = this.errorStockChart; + break; + case Asc.c_oAscError.ID.MaxDataSeriesError: + error = this.errorMaxRows; + break; + case Asc.c_oAscError.ID.MaxDataPointsError: + error = this.errorMaxPoints; + break; + case Asc.c_oAscError.ID.ErrorInFormula: + error = this.errorInFormula; + break; + case Asc.c_oAscError.ID.InvalidReference: + error = this.errorInvalidReference; + break; + case Asc.c_oAscError.ID.NoSingleRowCol: + error = this.errorNoSingleRowCol; + break; + case Asc.c_oAscError.ID.NoValues: + error = this.errorNoValues; + break; + } + Common.UI.warning({msg: error, maxwidth: 600}); + return false; + }, + + updateRangeData: function(type, value) { + if (!this.isRangeValid(type, value)) return; + + if (this.props.series) { + var series = this.props.series; + switch (type) { + case 1: + series.asc_setName(value); + this.lblRange1.html((this.inputRange1.getValue()!=='') ? ('= ' + (series.asc_getNameVal() || '')) : this.txtChoose); + break; + case 2: + if (this.isScatter) { + var arr = series.asc_getXValuesArr(); + series.asc_setXValues(value); + this.lblRange2.html((this.inputRange2.getValue()!=='') ? ('= ' + (arr ? arr.join('; ') : '')) : this.txtChoose); + } else { + var arr = series.asc_getValuesArr(); + series.asc_setValues(value); + this.lblRange2.html((this.inputRange2.getValue()!=='') ? ('= ' + (arr ? arr.join('; ') : '')) : this.txtChoose); + } + break; + case 3: + var arr = series.asc_getYValuesArr(); + series.asc_setYValues(value); + this.lblRange3.html((this.inputRange3.getValue()!=='') ? ('= ' + (arr ? arr.join('; ') : '')) : this.txtChoose); + break; + } + } else { + this.chartSettings.setCatFormula(value); + var arr = this.chartSettings.getCatValues(); + this.lblRange1.html((this.inputRange1.getValue()!=='') ? ('= ' + (arr ? arr.join('; ') : '')) : this.txtChoose); + } + }, + + onBtnClick: function(event) { + this._handleInput(event.currentTarget.attributes['result'].value); + }, + + _handleInput: function(state) { + if (this.options.handler) { + if (state == 'ok') { + if (!this.isRangeValid(1, this.inputRange1.getValue())) return; + if (this.type==1 && !this.isRangeValid(2, this.inputRange2.getValue())) return; + if (this.type==1 && this.isScatter && !this.isRangeValid(3, this.inputRange3.getValue())) return; + } + if (this.options.handler.call(this, this, state)) + return; + } + + this.close(); + }, + + txtTitleSeries: 'Edit Series', + txtTitleCategory: 'Axis Labels', + txtSeriesName: 'Series name', + txtValues: 'Values', + txtXValues: 'X Values', + txtYValues: 'Y Values', + txtAxisLabel: 'Axis label range', + txtChoose: 'Choose range', + textSelectData: 'Select data', + textInvalidRange: 'Invalid cells range', + errorMaxRows: 'The maximum number of data series per chart is 255.', + errorStockChart: 'Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.', + errorMaxPoints: 'The maximum number of points in series per chart is 4096.', + errorInFormula: "There's an error in formula you entered.", + errorInvalidReference: 'The reference is not valid. Reference must be to an open worksheet.', + errorNoSingleRowCol: 'The reference is not valid. References for titles, values, sizes, or data labels must be a single cell, row, or column.', + errorNoValues: 'To create a chart, the series must contain at least one value.' + + }, SSE.Views.ChartDataRangeDialog || {})) +}); diff --git a/apps/spreadsheeteditor/main/app/view/ChartSettings.js b/apps/spreadsheeteditor/main/app/view/ChartSettings.js index 831622d309..e205fb0de7 100644 --- a/apps/spreadsheeteditor/main/app/view/ChartSettings.js +++ b/apps/spreadsheeteditor/main/app/view/ChartSettings.js @@ -46,7 +46,8 @@ define([ 'common/main/lib/component/Button', 'common/main/lib/component/MetricSpinner', 'common/main/lib/component/ComboDataView', - 'spreadsheeteditor/main/app/view/ChartSettingsDlg' + 'spreadsheeteditor/main/app/view/ChartSettingsDlg', + 'spreadsheeteditor/main/app/view/ChartDataDialog' ], function (menuTemplate, $, _, Backbone) { 'use strict'; @@ -851,7 +852,7 @@ define([ } }, - onSelectData: function() { + onSelectData_simple: function() { var me = this; if (me.api) { var props = me.api.asc_getChartObject(), @@ -895,7 +896,34 @@ define([ }); } }, - + + onSelectData: function() { + var me = this; + var props; + if (me.api){ + props = me.api.asc_getChartObject(); + if (props) { + me._isEditRanges = true; + props.startEdit(); + var win = new SSE.Views.ChartDataDialog({ + chartSettings: props, + api: me.api, + handler: function(result, value) { + if (result == 'ok') { + props.endEdit(); + me._isEditRanges = false; + } + Common.NotificationCenter.trigger('edit:complete', me); + } + }).on('close', function() { + me._isEditRanges && props.cancelEdit(); + me._isEditRanges = false; + }); + win.show(); + } + } + }, + onSelectType: function(btn, picker, itemView, record) { if (this._noApply) return; diff --git a/apps/spreadsheeteditor/main/app/view/ChartSettingsDlg.js b/apps/spreadsheeteditor/main/app/view/ChartSettingsDlg.js index 4729d53c3e..cbd4b42a7e 100644 --- a/apps/spreadsheeteditor/main/app/view/ChartSettingsDlg.js +++ b/apps/spreadsheeteditor/main/app/view/ChartSettingsDlg.js @@ -42,7 +42,8 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' 'common/main/lib/view/AdvancedSettingsWindow', 'common/main/lib/component/CheckBox', 'common/main/lib/component/InputField', - 'spreadsheeteditor/main/app/view/CellRangeDialog' + 'spreadsheeteditor/main/app/view/CellRangeDialog', + 'spreadsheeteditor/main/app/view/ChartDataRangeDialog' ], function (contentTemplate) { 'use strict'; @@ -58,7 +59,7 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' _.extend(this.options, { title: this.textTitle, items: [ - {panelId: 'id-chart-settings-dlg-style', panelCaption: this.textTypeData}, + {panelId: 'id-chart-settings-dlg-style', panelCaption: this.textType}, {panelId: 'id-chart-settings-dlg-layout', panelCaption: this.textLayout}, {panelId: 'id-chart-settings-dlg-vert', panelCaption: this.textVertAxis}, {panelId: 'id-chart-settings-dlg-hor', panelCaption: this.textHorAxis}, @@ -137,26 +138,26 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' this.btnChartType.render($('#chart-dlg-button-type')); this.mnuChartTypePicker.on('item:click', _.bind(this.onSelectType, this, this.btnChartType)); - this.cmbDataDirect = new Common.UI.ComboBox({ - el : $('#chart-dlg-combo-range'), - menuStyle : 'min-width: 120px;', - editable : false, - cls : 'input-group-nr', - data : [ - { value: 0, displayValue: this.textDataRows }, - { value: 1, displayValue: this.textDataColumns } - ] - }); - - this.txtDataRange = new Common.UI.InputFieldBtn({ - el : $('#chart-dlg-txt-range'), - name : 'range', - style : 'width: 100%;', - btnHint : this.textSelectData, - allowBlank : true, - validateOnChange: true - }); - this.txtDataRange.on('button:click', _.bind(this.onSelectData, this)); + // this.cmbDataDirect = new Common.UI.ComboBox({ + // el : $('#chart-dlg-combo-range'), + // menuStyle : 'min-width: 120px;', + // editable : false, + // cls : 'input-group-nr', + // data : [ + // { value: 0, displayValue: this.textDataRows }, + // { value: 1, displayValue: this.textDataColumns } + // ] + // }); + // + // this.txtDataRange = new Common.UI.InputFieldBtn({ + // el : $('#chart-dlg-txt-range'), + // name : 'range', + // style : 'width: 100%;', + // btnHint : this.textSelectData, + // allowBlank : true, + // validateOnChange: true + // }); + // this.txtDataRange.on('button:click', _.bind(this.onSelectData, this)); this.cmbChartTitle = new Common.UI.ComboBox({ el : $('#chart-dlg-combo-chart-title'), @@ -1292,24 +1293,24 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' this._noApply = false; - var value = props.getRange(); - this.txtDataRange.setValue((value) ? value : ''); - this.dataRangeValid = value; - - this.txtDataRange.validation = function(value) { - if (_.isEmpty(value)) { - if (!me.cmbDataDirect.isDisabled()) me.cmbDataDirect.setDisabled(true); - return true; - } - - if (me.cmbDataDirect.isDisabled()) me.cmbDataDirect.setDisabled(false); - - var isvalid = me.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.Chart, value, false); - return (isvalid==Asc.c_oAscError.ID.DataRangeError) ? me.textInvalidRange : true; - }; - - this.cmbDataDirect.setDisabled(value===null); - this.cmbDataDirect.setValue(props.getInColumns() ? 1 : 0); + // var value = props.getRange(); + // this.txtDataRange.setValue((value) ? value : ''); + // this.dataRangeValid = value; + // + // this.txtDataRange.validation = function(value) { + // if (_.isEmpty(value)) { + // if (!me.cmbDataDirect.isDisabled()) me.cmbDataDirect.setDisabled(true); + // return true; + // } + // + // if (me.cmbDataDirect.isDisabled()) me.cmbDataDirect.setDisabled(false); + // + // var isvalid = me.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.Chart, value, false); + // return (isvalid==Asc.c_oAscError.ID.DataRangeError) ? me.textInvalidRange : true; + // }; + // + // this.cmbDataDirect.setDisabled(value===null); + // this.cmbDataDirect.setValue(props.getInColumns() ? 1 : 0); this.cmbChartTitle.setValue(props.getTitle()); this.cmbLegendPos.setValue(props.getLegendPos()); @@ -1320,7 +1321,7 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' this.chCategoryName.setValue(this.chartSettings.getShowCatName(), true); this.chValue.setValue(this.chartSettings.getShowVal(), true); - value = props.getSeparator(); + var value = props.getSeparator(); this.txtSeparator.setValue((value) ? value : ''); // Vertical Axis @@ -1422,8 +1423,8 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' this.chartSettings.putType(type); - this.chartSettings.putInColumns(this.cmbDataDirect.getValue()==1); - this.chartSettings.putRange(this.txtDataRange.getValue()); + // this.chartSettings.putInColumns(this.cmbDataDirect.getValue()==1); + // this.chartSettings.putRange(this.txtDataRange.getValue()); this.chartSettings.putTitle(this.cmbChartTitle.getValue()); this.chartSettings.putLegendPos(this.cmbLegendPos.getValue()); @@ -1484,12 +1485,13 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' isRangeValid: function() { if (this.isChart) { - var isvalid; - if (!_.isEmpty(this.txtDataRange.getValue())) { + var isvalid, + range = this.chartSettings.getRange(); + if (!_.isEmpty(range)) { var rec = this.mnuChartTypePicker.getSelectedRec(), type = (rec) ? rec.get('type') : this.currentChartType; - isvalid = this.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.Chart, this.txtDataRange.getValue(), true, this.cmbDataDirect.getValue()==0, type); + isvalid = this.api.asc_checkDataRange(Asc.c_oAscSelectionDialogType.Chart, range, true, !this.chartSettings.getInColumns(), type); if (isvalid == Asc.c_oAscError.ID.No) return true; } else @@ -1502,44 +1504,42 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' Common.UI.warning({msg: this.errorMaxRows}); } else if (isvalid == Asc.c_oAscError.ID.MaxDataPointsError) Common.UI.warning({msg: this.errorMaxPoints}); - else - this.txtDataRange.cmpEl.find('input').focus(); return false; } else return true; }, - onSelectData: function() { - var me = this; - if (me.api) { - me.btnChartType.menu.options.additionalAlign = me.menuAddAlign; - me.btnSparkType.menu.options.additionalAlign = me.menuAddAlign; - - var handlerDlg = function(dlg, result) { - if (result == 'ok') { - me.dataRangeValid = dlg.getSettings(); - me.txtDataRange.setValue(me.dataRangeValid); - me.txtDataRange.checkValidate(); - } - }; - - var win = new SSE.Views.CellRangeDialog({ - handler: handlerDlg - }).on('close', function() { - me.show(); - }); - - var xy = me.$window.offset(); - me.hide(); - win.show(xy.left + 160, xy.top + 125); - win.setSettings({ - api : me.api, - isRows : (me.cmbDataDirect.getValue()==0), - range : (!_.isEmpty(me.txtDataRange.getValue()) && (me.txtDataRange.checkValidate()==true)) ? me.txtDataRange.getValue() : me.dataRangeValid, - type : Asc.c_oAscSelectionDialogType.Chart - }); - } - }, + // onSelectData: function() { + // var me = this; + // if (me.api) { + // me.btnChartType.menu.options.additionalAlign = me.menuAddAlign; + // me.btnSparkType.menu.options.additionalAlign = me.menuAddAlign; + // + // var handlerDlg = function(dlg, result) { + // if (result == 'ok') { + // me.dataRangeValid = dlg.getSettings(); + // me.txtDataRange.setValue(me.dataRangeValid); + // me.txtDataRange.checkValidate(); + // } + // }; + // + // var win = new SSE.Views.CellRangeDialog({ + // handler: handlerDlg + // }).on('close', function() { + // me.show(); + // }); + // + // var xy = me.$window.offset(); + // me.hide(); + // win.show(xy.left + 160, xy.top + 125); + // win.setSettings({ + // api : me.api, + // isRows : (me.cmbDataDirect.getValue()==0), + // range : (!_.isEmpty(me.txtDataRange.getValue()) && (me.txtDataRange.checkValidate()==true)) ? me.txtDataRange.getValue() : me.dataRangeValid, + // type : Asc.c_oAscSelectionDialogType.Chart + // }); + // } + // }, onSelectDataLabels: function(obj, rec, e) { var disable = rec.value == Asc.c_oAscChartDataLabelsPos.none; @@ -1613,10 +1613,10 @@ define([ 'text!spreadsheeteditor/main/app/template/ChartSettingsDlg.template' show: function() { Common.Views.AdvancedSettingsWindow.prototype.show.apply(this, arguments); - var me = this; - _.delay(function(){ - me.txtDataRange.cmpEl.find('input').focus(); - },50); + // var me = this; + // _.delay(function(){ + // me.txtDataRange.cmpEl.find('input').focus(); + // },50); }, close: function () { diff --git a/apps/spreadsheeteditor/main/locale/en.json b/apps/spreadsheeteditor/main/locale/en.json index 166c3607b5..9b5d80dd2c 100644 --- a/apps/spreadsheeteditor/main/locale/en.json +++ b/apps/spreadsheeteditor/main/locale/en.json @@ -1281,6 +1281,42 @@ "SSE.Views.CellSettings.textControl": "Text Control", "SSE.Views.CellSettings.strWrap": "Wrap text", "SSE.Views.CellSettings.strShrink": "Shrink to fit", + "SSE.Views.ChartDataDialog.textTitle": "Chart Data", + "SSE.Views.ChartDataDialog.textInvalidRange": "Invalid cells range", + "SSE.Views.ChartDataDialog.textSelectData": "Select data", + "SSE.Views.ChartDataDialog.errorMaxRows": "The maximum number of data series per chart is 255.", + "SSE.Views.ChartDataDialog.errorStockChart": "Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.", + "SSE.Views.ChartDataDialog.errorMaxPoints": "The maximum number of points in series per chart is 4096.", + "SSE.Views.ChartDataDialog.textSeries": "Legend Entries (Series)", + "SSE.Views.ChartDataDialog.textAdd": "Add", + "SSE.Views.ChartDataDialog.textEdit": "Edit", + "SSE.Views.ChartDataDialog.textDelete": "Remove", + "SSE.Views.ChartDataDialog.textSwitch": "Switch Row/Column", + "SSE.Views.ChartDataDialog.textCategory": "Horizontal (Category) Axis Labels", + "SSE.Views.ChartDataDialog.textUp": "Up", + "SSE.Views.ChartDataDialog.textDown": "Down", + "SSE.Views.ChartDataDialog.textData": "Chart data range", + "SSE.Views.ChartDataDialog.errorInFormula": "There's an error in formula you entered.", + "SSE.Views.ChartDataDialog.errorInvalidReference": "The reference is not valid. Reference must be to an open worksheet.", + "SSE.Views.ChartDataDialog.errorNoSingleRowCol": "The reference is not valid. References for titles, values, sizes, or data labels must be a single cell, row, or column.", + "SSE.Views.ChartDataDialog.errorNoValues": "To create a chart, the series must contain at least one value.", + "SSE.Views.ChartDataRangeDialog.txtTitleSeries": "Edit Series", + "SSE.Views.ChartDataRangeDialog.txtTitleCategory": "Axis Labels", + "SSE.Views.ChartDataRangeDialog.txtSeriesName": "Series name", + "SSE.Views.ChartDataRangeDialog.txtValues": "Values", + "SSE.Views.ChartDataRangeDialog.txtXValues": "X Values", + "SSE.Views.ChartDataRangeDialog.txtYValues": "Y Values", + "SSE.Views.ChartDataRangeDialog.txtAxisLabel": "Axis label range", + "SSE.Views.ChartDataRangeDialog.txtChoose": "Choose range", + "SSE.Views.ChartDataRangeDialog.textInvalidRange": "Invalid cells range", + "SSE.Views.ChartDataRangeDialog.textSelectData": "Select data", + "SSE.Views.ChartDataRangeDialog.errorMaxRows": "The maximum number of data series per chart is 255.", + "SSE.Views.ChartDataRangeDialog.errorStockChart": "Incorrect row order. To build a stock chart place the data on the sheet in the following order:
opening price, max price, min price, closing price.", + "SSE.Views.ChartDataRangeDialog.errorMaxPoints": "The maximum number of points in series per chart is 4096.", + "SSE.Views.ChartDataRangeDialog.errorInFormula": "There's an error in formula you entered.", + "SSE.Views.ChartDataRangeDialog.errorInvalidReference": "The reference is not valid. Reference must be to an open worksheet.", + "SSE.Views.ChartDataRangeDialog.errorNoSingleRowCol": "The reference is not valid. References for titles, values, sizes, or data labels must be a single cell, row, or column.", + "SSE.Views.ChartDataRangeDialog.errorNoValues": "To create a chart, the series must contain at least one value.", "SSE.Views.ChartSettings.strLineWeight": "Line Weight", "SSE.Views.ChartSettings.strSparkColor": "Color", "SSE.Views.ChartSettings.strTemplate": "Template",