Merge pull request #423 from ONLYOFFICE/feature/sse-chart-data

Feature/sse chart data
This commit is contained in:
Julia Radzhabova 2020-07-20 11:30:04 +03:00 committed by GitHub
commit a5f0371a9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 1116 additions and 107 deletions

View file

@ -9,27 +9,27 @@
</tr>
</table>
</div>
<div class="separator horizontal padding-large"></div>
<div class="inner-content">
<table cols="1" style="width: 100%;">
<tr>
<td>
<label class="header"><%= scope.textDataRange %></label>
</td>
</tr>
<tr>
<td class="padding-small" width="200">
<div id="chart-dlg-txt-range" class="input-row" style="margin-right: 10px;"></div>
</td>
</tr>
<tr>
<td class="padding-small">
<label class="input-label"><%= scope.textDataSeries %></label>
<div id="chart-dlg-combo-range" class="input-group-nr" style="width:120px;"></div>
</td>
</tr>
</table>
</div>
<!--<div class="separator horizontal padding-large"></div>-->
<!--<div class="inner-content">-->
<!--<table cols="1" style="width: 100%;">-->
<!--<tr>-->
<!--<td>-->
<!--<label class="header"><%= scope.textDataRange %></label>-->
<!--</td>-->
<!--</tr>-->
<!--<tr>-->
<!--<td class="padding-small" width="200">-->
<!--<div id="chart-dlg-txt-range" class="input-row" style="margin-right: 10px;"></div>-->
<!--</td>-->
<!--</tr>-->
<!--<tr>-->
<!--<td class="padding-small">-->
<!--<label class="input-label"><%= scope.textDataSeries %></label>-->
<!--<div id="chart-dlg-combo-range" class="input-group-nr" style="width:120px;"></div>-->
<!--</td>-->
<!--</tr>-->
<!--</table>-->
<!--</div>-->
</div>
<div id="id-chart-settings-dlg-layout" class="settings-panel">
<div class="inner-content">

View file

@ -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: [
'<div class="box" style="height:' + (me.options.height - 85) + 'px;">',
'<div class="content-panel" style="padding: 0 10px;"><div class="inner-content">',
'<div class="settings-panel active">',
'<table cols="1" style="width: 100%;">',
'<tr>',
'<td>',
'<label class="input-label">', me.textData, '</label>',
'</td>',
'</tr>',
'<tr>',
'<td class="padding-small" width="200">',
'<div id="chart-dlg-txt-range" class="input-row" style=""></div>',
'</td>',
'</tr>',
'<tr>',
'<td class="padding-small">',
'<label class="input-label">', me.textSeries, '</label>',
'<div id="chart-dlg-series-list" class="" style="width:100%; height: 93px;"></div>',
'</td>',
'</tr>',
'<tr>',
'<td class="padding-large">',
'<button type="button" class="btn btn-text-default auto" id="chart-dlg-btn-add" style="min-width: 70px;margin-right:5px;">', me.textAdd, '</button>',
'<button type="button" class="btn btn-text-default auto" id="chart-dlg-btn-edit" style="min-width: 70px;margin-right:5px;">', me.textEdit, '</button>',
'<button type="button" class="btn btn-text-default auto" id="chart-dlg-btn-delete" style="min-width: 70px;margin-right:5px;">', me.textDelete, '</button>',
'<div style="display: inline-block; float: right;">',
'<div id="chart-dlg-btn-up" style="display: inline-block;border: 1px solid #cfcfcf;border-radius: 1px;margin-right: 2px;"></div>',
'<div id="chart-dlg-btn-down" style="display: inline-block;border: 1px solid #cfcfcf;border-radius: 1px;"></div>',
'</div>',
'</td>',
'</tr>',
'<tr>',
'<td class="padding-large">',
'<button type="button" class="btn btn-text-default auto" id="chart-dlg-btn-switch" style="min-width: 70px;margin-right:5px;">', me.textSwitch, '</button>',
'</td>',
'</tr>',
'<tr>',
'<td class="padding-small">',
'<label class="input-label">', me.textCategory, '</label>',
'<div id="chart-dlg-category-list" class="" style="width:100%; height: 93px;"></div>',
'</td>',
'</tr>',
'<tr>',
'<td class="padding-small">',
'<button type="button" class="btn btn-text-default auto" id="chart-dlg-btn-category-edit" style="min-width: 70px;margin-right:5px;">', me.textEdit, '</button>',
'</td>',
'</tr>',
'</table>',
'</div></div>',
'</div>',
'</div>',
'<div class="separator horizontal"></div>'
].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('<div id="<%= id %>" class="list-item" style="min-height: 15px;"><%= value %></div>')
});
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('<div id="<%= id %>" class="list-item" style="min-height: 15px;"><%= value %></div>')
});
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:<br> 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 || {}))
});

View file

@ -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 = [
'<div class="box">',
'<table cols="2" style="width: 100%;">',
'<tr>',
'<td colspan="2">',
'<label>' + (this.type==1 ? this.txtSeriesName : this.txtAxisLabel) + '</label>',
'</td>',
'</tr>',
'<tr>',
'<td style="padding-bottom: 8px;width: 100%;">',
'<div id="id-dlg-chart-range-range1"></div>',
'</td>',
'<td style="padding-bottom: 8px;">',
'<label id="id-dlg-chart-range-lbl1" style="width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-left: 5px;margin-top: 4px;">' + this.txtChoose + '</label>',
'</td>',
'</tr>',
'<% if (type==1) { %>',
'<tr>',
'<td colspan="2">',
'<label>' + (this.isScatter ? this.txtXValues : this.txtValues) + '</label>',
'</td>',
'</tr>',
'<tr>',
'<td style="padding-bottom: 8px;width: 100%;">',
'<div id="id-dlg-chart-range-range2"></div>',
'</td>',
'<td style="padding-bottom: 8px;">',
'<label id="id-dlg-chart-range-lbl2" style="width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-left: 5px;margin-top: 4px;"></label>',
'</td>',
'</tr>',
'<% if (isScatter) { %>',
'<tr>',
'<td colspan="2">',
'<label>' + this.txtYValues + '</label>',
'</td>',
'</tr>',
'<tr>',
'<td style="padding-bottom: 8px;width: 100%;">',
'<div id="id-dlg-chart-range-range3"></div>',
'</td>',
'<td style="padding-bottom: 8px;">',
'<label id="id-dlg-chart-range-lbl3" style="width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-left: 5px;margin-top: 4px;"></label>',
'</td>',
'</tr>',
'<% } %>',
'<% } %>',
'</table>',
'</div>'
].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:<br> 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 || {}))
});

View file

@ -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;

View file

@ -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 () {

View file

@ -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:<br> 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:<br> 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",