Merge branch 'hotfix/v4.1.2' into develop

This commit is contained in:
Julia Radzhabova 2016-09-20 10:50:17 +03:00
commit a9cc2ce9ad
142 changed files with 47628 additions and 244 deletions

View file

@ -1,6 +1,7 @@
<div id="header-container">
<div id="header-logo"></div>
<div id="header-caption"><div><%= headerCaption %></div></div>
<div id="header-developer" class="hidden"><div><%= headerDeveloper %></div></div>
<div id="header-documentcaption"><%= documentCaption %></div>
<div id="header-back" style="display: <%= canBack ? 'table-cell' : 'none' %>;"><div><%= textBack %></div></div>
</div>

View file

@ -53,6 +53,7 @@ define([
options : {
branding: {},
headerCaption: 'Default Caption',
headerDeveloper: 'DEVELOPER MODE',
documentCaption: '',
canBack: false
},
@ -77,6 +78,7 @@ define([
this.options = this.options ? _({}).extend(this.options, options) : options;
this.headerCaption = this.options.headerCaption;
this.headerDeveloper = this.txtHeaderDeveloper;
this.documentCaption = this.options.documentCaption;
this.canBack = this.options.canBack;
this.branding = this.options.customization;
@ -85,6 +87,7 @@ define([
render: function () {
$(this.el).html(this.template({
headerCaption : this.headerCaption,
headerDeveloper : this.headerDeveloper,
documentCaption : Common.Utils.String.htmlEncode(this.documentCaption),
canBack : this.canBack,
textBack : this.textBack
@ -219,7 +222,12 @@ define([
}
},
setDeveloperMode: function(mode) {
$('#header-developer').toggleClass('hidden', !mode);
},
textBack: 'Go to Documents',
openNewTabText: 'Open in New Tab'
openNewTabText: 'Open in New Tab',
txtHeaderDeveloper: 'DEVELOPER MODE'
}, Common.Views.Header || {}))
});

View file

@ -46,6 +46,34 @@
}
}
#header-developer {
background-color: #ffb400;
padding-left: 15px + @app-header-height / 3;
& > div {
position: relative;
background-color: #ffb400;
color: #6e4e00 !important;
padding-right: 15px;
cursor: default;
z-index: 1;
white-space: nowrap;
height: @app-header-height;
line-height: @app-header-height;
&:after {
content: '';
position: absolute;
top: 0;
right: -@app-header-height / 2;
width: @app-header-height / 2;
height: @app-header-height;
border-top: @app-header-height / 2 solid transparent;
border-left: @app-header-height / 3 solid #ffb400;
border-bottom: @app-header-height / 2 solid transparent;
}
}
}
#header-documentcaption {
width: 100%;
max-width: 100px;

View file

@ -7,6 +7,10 @@
}
&.x-list-round.x-list-grouped {
.x-list-footer-wrap.x-list-item-tpl {
padding-bottom: 0;
}
.x-list-header-wrap {
.x-dock-horizontal {
padding-top: 0;

View file

@ -104,15 +104,15 @@
}
.round {
@include border-radius($panel-border-radius);
@include border-radius($form-fieldset-radius);
}
// Hide group header
.x-list-header-wrap {
@include border-top-radius($panel-border-radius !important);
@include border-top-radius($form-fieldset-radius !important);
.x-innerhtml {
@include border-top-radius($panel-border-radius !important);
@include border-top-radius($form-fieldset-radius !important);
}
}

View file

@ -964,13 +964,11 @@ define([
this._state.licenseWarning = (licType===Asc.c_oLicenseResult.Connections) && this.appOptions.canEdit && this.editorConfig.mode !== 'view';
this.appOptions.canBranding = params.asc_getCanBranding() && (typeof this.editorConfig.customization == 'object');
if (this.appOptions.canBranding) {
this.getApplication()
.getController('Viewport')
.getView('Common.Views.Header')
.setBranding(this.editorConfig.customization);
}
if (this.appOptions.canBranding)
this.getApplication().getController('Viewport').getView('Common.Views.Header').setBranding(this.editorConfig.customization);
params.asc_getTrial() && this.getApplication().getController('Viewport').getView('Common.Views.Header').setDeveloperMode(true);
this.applyModeCommonElements();
this.applyModeEditorElements();

View file

@ -86,6 +86,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Alle ersetzen",
"Common.UI.SynchronizeTip.textDontShow": "Diese Meldung nicht mehr anzeigen",
"Common.UI.SynchronizeTip.textSynchronize": "Das Dokument wurde von einem anderen Benutzer geändert.<br/>Bitte klicken hier, um Ihre Änderungen zu speichern und die Aktualisierungen neu zu laden.",
"Common.UI.ThemeColorPalette.textStandartColors": "Standardfarben",
"Common.UI.ThemeColorPalette.textThemeColors": "Designfarben",
"Common.UI.Window.cancelButtonText": "Abbrechen",
"Common.UI.Window.closeButtonText": "Schließen",
"Common.UI.Window.noButtonText": "Nein",
@ -156,7 +158,13 @@
"Common.Views.OpenDialog.cancelButtonText": "Abbrechen",
"Common.Views.OpenDialog.okButtonText": "OK",
"Common.Views.OpenDialog.txtEncoding": "Verschlüsselung ",
"Common.Views.OpenDialog.txtPassword": "Password",
"Common.Views.OpenDialog.txtTitle": "%1-Optionen wählen",
"Common.Views.OpenDialog.txtTitleProtected": "Protected File",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"Common.Views.ReviewChanges.txtAccept": "Annehmen",
"Common.Views.ReviewChanges.txtAcceptAll": "Alle Änderungen annehmen",
"Common.Views.ReviewChanges.txtAcceptCurrent": "Aktuelle Änderungen annehmen",
@ -202,6 +210,7 @@
"DE.Controllers.Main.errorUpdateVersion": "Die Dateiversion wurde geändert. Die Seite wird neu geladen.",
"DE.Controllers.Main.errorUserDrop": "Kein Zugriff auf diese Datei ist möglich.",
"DE.Controllers.Main.errorUsersExceed": "Die nach dem Zahlungsplan erlaubte Anzahl der Benutzer ist überschritten",
"DE.Controllers.Main.errorViewerDisconnect": "Connection is lost. You can still view the document,<br>but will not be able to download until the connection is restored.",
"DE.Controllers.Main.leavePageText": "Dieses Dokument enthält ungespeicherte Änderungen. Klicken Sie auf \"Auf dieser Seite bleiben\" und dann auf \"Speichern\", um sie zu speichern. Klicken Sie auf \"Diese Seite verlassen\", um alle nicht gespeicherten Änderungen zu verwerfen.\n",
"DE.Controllers.Main.loadFontsTextText": "Daten werden geladen...",
"DE.Controllers.Main.loadFontsTitleText": "Daten werden geladen",
@ -216,6 +225,7 @@
"DE.Controllers.Main.mailMergeLoadFileText": "Laden der Datenquellen...",
"DE.Controllers.Main.mailMergeLoadFileTitle": "Laden der Datenquellen",
"DE.Controllers.Main.notcriticalErrorTitle": "Achtung",
"DE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"DE.Controllers.Main.openTextText": "Dokument wird geöffnet",
"DE.Controllers.Main.openTitleText": "Das Dokument wird geöffnet",
"DE.Controllers.Main.printTextText": "Dokument wird ausgedruckt...",
@ -223,6 +233,7 @@
"DE.Controllers.Main.reloadButtonText": "Seite erneut laden\t",
"DE.Controllers.Main.requestEditFailedMessageText": "Jemand bearbeitet dieses Dokument in diesem Moment. Bitte versuchen Sie es später erneut.",
"DE.Controllers.Main.requestEditFailedTitleText": "Zugriff verweigert",
"DE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"DE.Controllers.Main.savePreparingText": "Speichervorbereitung",
"DE.Controllers.Main.savePreparingTitle": "Speichervorbereitung. Bitte warten...",
"DE.Controllers.Main.saveTextText": "Dokument wird gespeichert...",
@ -240,6 +251,7 @@
"DE.Controllers.Main.textNoLicenseTitle": "ONLYOFFICE open source version",
"DE.Controllers.Main.textStrict": "Formaler Modus",
"DE.Controllers.Main.textTryUndoRedo": "Undo/Redo Optionen sind für den halbformalen Zusammenbearbeitungsmodus deaktiviert.<br>Klicken Sie auf den Button \"Formaler Modus\", um den formalen Zusammenbearbeitungsmodus zu aktivieren, um die Datei, ohne Störungen anderer Benutzer zu bearbeiten und die Änderungen erst nachdem Sie sie gespeichert haben, zu senden. Sie können zwischen den Zusammenbearbeitungsmodi mit der Hilfe der erweiterten Einstellungen von Editor umschalten.",
"DE.Controllers.Main.titleLicenseExp": "License expired",
"DE.Controllers.Main.titleUpdateVersion": "Version wurde geändert",
"DE.Controllers.Main.txtArt": "Hier den Text eingeben",
"DE.Controllers.Main.txtBasicShapes": "Standardformen",
@ -267,6 +279,7 @@
"DE.Controllers.Main.uploadImageTitleText": "Bild wird hochgeladen",
"DE.Controllers.Main.warnBrowserIE9": "Die Applkation hat geringte Fähigkeiten in IE9. Nutzen Sie IE10 oder höher.",
"DE.Controllers.Main.warnBrowserZoom": "Die aktuelle Zoom-Einstellung Ihres Webbrowsers wird nicht völlig unterstützt. Bitte stellen Sie die Standardeinstellung mithilfe der Tastenkombination Strg+0 wieder her.",
"DE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"DE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"DE.Controllers.Main.warnProcessRightsChange": "Das Recht, die Datei zu bearbeiten, wurde Ihnen verweigert.",
"DE.Controllers.Statusbar.textHasChanges": "Neue Änderungen wurden zurückverfolgt",
@ -829,7 +842,7 @@
"DE.Views.DropcapSettingsAdvanced.textLeft": "Links",
"DE.Views.DropcapSettingsAdvanced.textMargin": "Rand",
"DE.Views.DropcapSettingsAdvanced.textMove": "Mit Text verschieben",
"DE.Views.DropcapSettingsAdvanced.textNewColor": "Neue benutzerdefinierte Farbe hinzufügen",
"DE.Views.DropcapSettingsAdvanced.textNewColor": "Benutzerdefinierte Farbe",
"DE.Views.DropcapSettingsAdvanced.textNone": "Kein",
"DE.Views.DropcapSettingsAdvanced.textPage": "Seite",
"DE.Views.DropcapSettingsAdvanced.textParagraph": "Absatz",
@ -838,8 +851,6 @@
"DE.Views.DropcapSettingsAdvanced.textRelative": "Im Bezug auf ",
"DE.Views.DropcapSettingsAdvanced.textRight": "Rechts",
"DE.Views.DropcapSettingsAdvanced.textRowHeight": "Höhe in Zeilen",
"DE.Views.DropcapSettingsAdvanced.textStandartColors": "Standardfarben",
"DE.Views.DropcapSettingsAdvanced.textThemeColors": "Designfarben",
"DE.Views.DropcapSettingsAdvanced.textTitle": "Initialbuchstaben - Erweiterte Einstellungen",
"DE.Views.DropcapSettingsAdvanced.textTitleFrame": "Rahmen - Erweiterte Einstellungen",
"DE.Views.DropcapSettingsAdvanced.textTop": "Oben",
@ -909,6 +920,8 @@
"DE.Views.FileMenuPanels.Settings.textMinute": "Jede Minute",
"DE.Views.FileMenuPanels.Settings.txtAll": "Alle anzeigen",
"DE.Views.FileMenuPanels.Settings.txtCm": "Zentimeter",
"DE.Views.FileMenuPanels.Settings.txtFitPage": "Fit to Page",
"DE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit to Width",
"DE.Views.FileMenuPanels.Settings.txtInch": "Zoll",
"DE.Views.FileMenuPanels.Settings.txtInput": "Alternative Eingabe",
"DE.Views.FileMenuPanels.Settings.txtLast": "Letzte anzeigen",
@ -943,6 +956,8 @@
"DE.Views.HyperlinkSettingsDialog.txtEmpty": "Dieses Feld ist erforderlich",
"DE.Views.HyperlinkSettingsDialog.txtNotUrl": "Dieses Feld muss eine URL im Format \"http://www.example.com\" enthalten",
"DE.Views.ImageSettings.textAdvanced": "Erweiterte Einstellungen anzeigen",
"DE.Views.ImageSettings.textEdit": "Edit",
"DE.Views.ImageSettings.textEditObject": "Edit Object",
"DE.Views.ImageSettings.textFromFile": "Aus Datei",
"DE.Views.ImageSettings.textFromUrl": "Aus URL",
"DE.Views.ImageSettings.textHeight": "Höhe",
@ -1026,6 +1041,7 @@
"DE.Views.LeftMenu.tipChat": "Chat",
"DE.Views.LeftMenu.tipComments": "Kommentare",
"DE.Views.LeftMenu.tipFile": "Datei",
"DE.Views.LeftMenu.tipPlugins": "Plugins",
"DE.Views.LeftMenu.tipSearch": "Suchen",
"DE.Views.LeftMenu.tipSupport": "Feedback und Support",
"DE.Views.LeftMenu.tipTitles": "Titel",
@ -1107,9 +1123,7 @@
"DE.Views.ParagraphSettings.textAuto": "Mehrfach",
"DE.Views.ParagraphSettings.textBackColor": "Hintergrundfarbe",
"DE.Views.ParagraphSettings.textExact": "Genau",
"DE.Views.ParagraphSettings.textNewColor": "Neue benutzerdefinierte Farbe hinzufügen",
"DE.Views.ParagraphSettings.textStandartColors": "Standardfarben",
"DE.Views.ParagraphSettings.textThemeColors": "Designfarben",
"DE.Views.ParagraphSettings.textNewColor": "Benutzerdefinierte Farbe",
"DE.Views.ParagraphSettings.txtAutoText": "Auto",
"DE.Views.ParagraphSettingsAdvanced.cancelButtonText": "Abbrechen",
"DE.Views.ParagraphSettingsAdvanced.noTabs": "Die festgelegten Registerkarten werden in diesem Feld erscheinen",
@ -1143,19 +1157,17 @@
"DE.Views.ParagraphSettingsAdvanced.textDefault": "Standardregisterkarte",
"DE.Views.ParagraphSettingsAdvanced.textEffects": "Effekte",
"DE.Views.ParagraphSettingsAdvanced.textLeft": "Links",
"DE.Views.ParagraphSettingsAdvanced.textNewColor": "Neue benutzerdefinierte Farbe hinzufügen",
"DE.Views.ParagraphSettingsAdvanced.textNewColor": "Benutzerdefinierte Farbe",
"DE.Views.ParagraphSettingsAdvanced.textPosition": "Position",
"DE.Views.ParagraphSettingsAdvanced.textRemove": "Löschen",
"DE.Views.ParagraphSettingsAdvanced.textRemoveAll": "Alle löschen",
"DE.Views.ParagraphSettingsAdvanced.textRight": "Rechts",
"DE.Views.ParagraphSettingsAdvanced.textSet": "Angeben",
"DE.Views.ParagraphSettingsAdvanced.textSpacing": "Abstand",
"DE.Views.ParagraphSettingsAdvanced.textStandartColors": "Standardfarben",
"DE.Views.ParagraphSettingsAdvanced.textTabCenter": "Zentriert",
"DE.Views.ParagraphSettingsAdvanced.textTabLeft": "Links",
"DE.Views.ParagraphSettingsAdvanced.textTabPosition": "Tabulatorposition",
"DE.Views.ParagraphSettingsAdvanced.textTabRight": "Rechts",
"DE.Views.ParagraphSettingsAdvanced.textThemeColors": "Designfarben",
"DE.Views.ParagraphSettingsAdvanced.textTitle": "Absatz - Erweiterte Einstellungen",
"DE.Views.ParagraphSettingsAdvanced.textTop": "Oben",
"DE.Views.ParagraphSettingsAdvanced.tipAll": "Äußere Rahmenlinie und alle inneren Linien festlegen",
@ -1184,6 +1196,7 @@
"DE.Views.ShapeSettings.strSize": "Größe",
"DE.Views.ShapeSettings.strStroke": "Strich",
"DE.Views.ShapeSettings.strTransparency": "Undurchsichtigkeit",
"DE.Views.ShapeSettings.strType": "Type",
"DE.Views.ShapeSettings.textAdvanced": "Erweiterte Einstellungen anzeigen",
"DE.Views.ShapeSettings.textBorderSizeErr": "Der eingegebene Wert ist falsch.<br>Bitte geben Sie einen Wert zwischen 0 pt und 1584 pt ein.",
"DE.Views.ShapeSettings.textColor": "Farbfüllung",
@ -1195,16 +1208,14 @@
"DE.Views.ShapeSettings.textGradientFill": "Füllung mit Farbverlauf",
"DE.Views.ShapeSettings.textImageTexture": "Bild oder Textur",
"DE.Views.ShapeSettings.textLinear": "Linear",
"DE.Views.ShapeSettings.textNewColor": "Neue benutzerdefinierte Farbe hinzufügen",
"DE.Views.ShapeSettings.textNewColor": "Benutzerdefinierte Farbe",
"DE.Views.ShapeSettings.textNoFill": "Keine Füllung",
"DE.Views.ShapeSettings.textPatternFill": "Muster",
"DE.Views.ShapeSettings.textRadial": "Radial",
"DE.Views.ShapeSettings.textSelectTexture": "Auswählen",
"DE.Views.ShapeSettings.textStandartColors": "Standardfarben",
"DE.Views.ShapeSettings.textStretch": "Ausdehnung",
"DE.Views.ShapeSettings.textStyle": "Stil",
"DE.Views.ShapeSettings.textTexture": "Aus Textur",
"DE.Views.ShapeSettings.textThemeColors": "Designfarben",
"DE.Views.ShapeSettings.textTile": "Kachel",
"DE.Views.ShapeSettings.textWrap": "Textumbruch",
"DE.Views.ShapeSettings.txtBehind": "Hinten",
@ -1281,13 +1292,11 @@
"DE.Views.TableSettings.textFirst": "Erste",
"DE.Views.TableSettings.textHeader": "Kopfzeile",
"DE.Views.TableSettings.textLast": "Letzte",
"DE.Views.TableSettings.textNewColor": "Neue benutzerdefinierte Farbe hinzufügen",
"DE.Views.TableSettings.textNewColor": "Benutzerdefinierte Farbe",
"DE.Views.TableSettings.textOK": "OK",
"DE.Views.TableSettings.textRows": "Zeilen",
"DE.Views.TableSettings.textSelectBorders": "Wählen Sie Rahmenlinien, auf die ein anderer Stil angewandt wird",
"DE.Views.TableSettings.textStandartColors": "Standardfarben",
"DE.Views.TableSettings.textTemplate": "Vorlage auswählen",
"DE.Views.TableSettings.textThemeColors": "Designfarben",
"DE.Views.TableSettings.textTotal": "Insgesamt",
"DE.Views.TableSettings.textWrap": "Textumbruch",
"DE.Views.TableSettings.textWrapNoneTooltip": "Inline-Tabelle",
@ -1333,7 +1342,7 @@
"DE.Views.TableSettingsAdvanced.textMargins": "Zellenränder",
"DE.Views.TableSettingsAdvanced.textMeasure": "Maßeinheit in",
"DE.Views.TableSettingsAdvanced.textMove": "Objekt mit Text verschieben",
"DE.Views.TableSettingsAdvanced.textNewColor": "Neue benutzerdefinierte Farbe hinzufügen",
"DE.Views.TableSettingsAdvanced.textNewColor": "Benutzerdefinierte Farbe",
"DE.Views.TableSettingsAdvanced.textOnlyCells": "Nur für gewählte Zellen",
"DE.Views.TableSettingsAdvanced.textOptions": "Optionen",
"DE.Views.TableSettingsAdvanced.textOverlap": "Überlappung zulassen",
@ -1345,12 +1354,10 @@
"DE.Views.TableSettingsAdvanced.textRight": "Rechts",
"DE.Views.TableSettingsAdvanced.textRightOf": "rechts von",
"DE.Views.TableSettingsAdvanced.textRightTooltip": "Rechts",
"DE.Views.TableSettingsAdvanced.textStandartColors": "Standardfarben",
"DE.Views.TableSettingsAdvanced.textTable": "Tabelle",
"DE.Views.TableSettingsAdvanced.textTableBackColor": "Tabellenhintergrund",
"DE.Views.TableSettingsAdvanced.textTablePosition": "Tabellenposition",
"DE.Views.TableSettingsAdvanced.textTableSize": "Größe der Tabelle",
"DE.Views.TableSettingsAdvanced.textThemeColors": "Designfarben",
"DE.Views.TableSettingsAdvanced.textTitle": "Tabelle - Erweiterte Einstellungen",
"DE.Views.TableSettingsAdvanced.textTop": "Oben",
"DE.Views.TableSettingsAdvanced.textVertical": "Vertikal",
@ -1381,20 +1388,19 @@
"DE.Views.TextArtSettings.strSize": "Größe",
"DE.Views.TextArtSettings.strStroke": "Strich",
"DE.Views.TextArtSettings.strTransparency": "Undurchsichtigkeit",
"DE.Views.TextArtSettings.strType": "Type",
"DE.Views.TextArtSettings.textBorderSizeErr": "Der eingegebene Wert ist falsch.<br>Bitte geben Sie einen Wert zwischen 0 pt und 1584 pt ein.",
"DE.Views.TextArtSettings.textColor": "Farbfüllung",
"DE.Views.TextArtSettings.textDirection": "Richtung",
"DE.Views.TextArtSettings.textGradient": "Farbverlauf",
"DE.Views.TextArtSettings.textGradientFill": "Füllung mit Farbverlauf",
"DE.Views.TextArtSettings.textLinear": "Linear",
"DE.Views.TextArtSettings.textNewColor": "Neue benutzerdefinierte Farbe hinzufügen",
"DE.Views.TextArtSettings.textNewColor": "Benutzerdefinierte Farbe",
"DE.Views.TextArtSettings.textNoFill": "Keine Füllung",
"DE.Views.TextArtSettings.textRadial": "Radial",
"DE.Views.TextArtSettings.textSelectTexture": "Auswählen",
"DE.Views.TextArtSettings.textStandartColors": "Standardfarben",
"DE.Views.TextArtSettings.textStyle": "Stil",
"DE.Views.TextArtSettings.textTemplate": "Vorlage",
"DE.Views.TextArtSettings.textThemeColors": "Designfarben",
"DE.Views.TextArtSettings.textTransform": "Transformieren\t",
"DE.Views.TextArtSettings.txtNoBorders": "Keine Linie",
"DE.Views.Toolbar.mniCustomTable": "Benutzerdefinierte Tabelle einfügen",
@ -1434,6 +1440,7 @@
"DE.Views.Toolbar.textInsTextArt": "Text Art einfügen",
"DE.Views.Toolbar.textInText": "Im Text",
"DE.Views.Toolbar.textItalic": "Kursiv",
"DE.Views.Toolbar.textLandscape": "Landscape",
"DE.Views.Toolbar.textLeft": "Links: ",
"DE.Views.Toolbar.textLine": "Linie",
"DE.Views.Toolbar.textMarginsLast": " Benutzerdefiniert als letzte",
@ -1442,7 +1449,7 @@
"DE.Views.Toolbar.textMarginsNormal": "Normal",
"DE.Views.Toolbar.textMarginsUsNormal": "Normal (US)",
"DE.Views.Toolbar.textMarginsWide": "Breit",
"DE.Views.Toolbar.textNewColor": "Neue benutzerdefinierte Farbe hinzufügen",
"DE.Views.Toolbar.textNewColor": "Benutzerdefinierte Farbe",
"DE.Views.Toolbar.textNextPage": "Nächste Seite",
"DE.Views.Toolbar.textNone": "Kein",
"DE.Views.Toolbar.textOddPage": "Ungerade Seite",
@ -1450,8 +1457,8 @@
"DE.Views.Toolbar.textPageSizeCustom": "Benutzerdefiniertes Seitenformat",
"DE.Views.Toolbar.textPie": "Kreis",
"DE.Views.Toolbar.textPoint": "Punkt",
"DE.Views.Toolbar.textPortrait": "Portrait",
"DE.Views.Toolbar.textRight": "Rechts: ",
"DE.Views.Toolbar.textStandartColors": "Standardfarben",
"DE.Views.Toolbar.textStock": "Kurs",
"DE.Views.Toolbar.textStrikeout": "Durchgestrichen",
"DE.Views.Toolbar.textStyleMenuDelete": "Stil löschen\t",
@ -1462,7 +1469,6 @@
"DE.Views.Toolbar.textStyleMenuUpdate": "Aus der Auswahl neu aktualisieren",
"DE.Views.Toolbar.textSubscript": "Tiefgestellt",
"DE.Views.Toolbar.textSuperscript": "Hochgestellt",
"DE.Views.Toolbar.textThemeColors": "Designfarben",
"DE.Views.Toolbar.textTitleError": "Fehler",
"DE.Views.Toolbar.textToCurrent": "An aktueller Position",
"DE.Views.Toolbar.textTop": "Oben: ",

View file

@ -141,6 +141,7 @@
"Common.Views.ExternalMergeEditor.textTitle": "Mail Merge Recipients",
"Common.Views.Header.openNewTabText": "Open in New Tab",
"Common.Views.Header.textBack": "Go to Documents",
"Common.Views.Header.txtHeaderDeveloper": "DEVELOPER MODE",
"Common.Views.History.textHistoryHeader": "Back to Document",
"Common.Views.ImageFromUrlDialog.cancelButtonText": "Cancel",
"Common.Views.ImageFromUrlDialog.okButtonText": "OK",
@ -158,13 +159,13 @@
"Common.Views.OpenDialog.cancelButtonText": "Cancel",
"Common.Views.OpenDialog.okButtonText": "OK",
"Common.Views.OpenDialog.txtEncoding": "Encoding ",
"Common.Views.OpenDialog.txtTitle": "Choose %1 options",
"Common.Views.OpenDialog.txtPassword": "Password",
"Common.Views.OpenDialog.txtTitle": "Choose %1 options",
"Common.Views.OpenDialog.txtTitleProtected": "Protected File",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.ReviewChanges.txtAccept": "Accept",
"Common.Views.ReviewChanges.txtAcceptAll": "Accept All Changes",
"Common.Views.ReviewChanges.txtAcceptCurrent": "Accept Current Change",
@ -227,6 +228,7 @@
"DE.Controllers.Main.mailMergeLoadFileText": "Loading Data Source...",
"DE.Controllers.Main.mailMergeLoadFileTitle": "Loading Data Source",
"DE.Controllers.Main.notcriticalErrorTitle": "Warning",
"DE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"DE.Controllers.Main.openTextText": "Opening document...",
"DE.Controllers.Main.openTitleText": "Opening Document",
"DE.Controllers.Main.printTextText": "Printing document...",
@ -234,6 +236,7 @@
"DE.Controllers.Main.reloadButtonText": "Reload Page",
"DE.Controllers.Main.requestEditFailedMessageText": "Someone is editing this document right now. Please try again later.",
"DE.Controllers.Main.requestEditFailedTitleText": "Access denied",
"DE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"DE.Controllers.Main.savePreparingText": "Preparing to save",
"DE.Controllers.Main.savePreparingTitle": "Preparing to save. Please wait...",
"DE.Controllers.Main.saveTextText": "Saving document...",
@ -251,6 +254,7 @@
"DE.Controllers.Main.textNoLicenseTitle": "ONLYOFFICE open source version",
"DE.Controllers.Main.textStrict": "Strict mode",
"DE.Controllers.Main.textTryUndoRedo": "The Undo/Redo functions are disabled for the Fast co-editing mode.<br>Click the 'Strict mode' button to switch to the Strict co-editing mode to edit the file without other users interference and send your changes only after you save them. You can switch between the co-editing modes using the editor Advanced settings.",
"DE.Controllers.Main.titleLicenseExp": "License expired",
"DE.Controllers.Main.titleUpdateVersion": "Version changed",
"DE.Controllers.Main.txtArt": "Your text here",
"DE.Controllers.Main.txtBasicShapes": "Basic Shapes",
@ -278,10 +282,9 @@
"DE.Controllers.Main.uploadImageTitleText": "Uploading Image",
"DE.Controllers.Main.warnBrowserIE9": "The application has low capabilities on IE9. Use IE10 or higher",
"DE.Controllers.Main.warnBrowserZoom": "Your browser current zoom setting is not fully supported. Please reset to the default zoom by pressing Ctrl+0.",
"DE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"DE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"DE.Controllers.Main.warnProcessRightsChange": "You have been denied the right to edit the file.",
"DE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"DE.Controllers.Main.titleLicenseExp": "License expired",
"DE.Controllers.Statusbar.textHasChanges": "New changes have been tracked",
"DE.Controllers.Statusbar.textTrackChanges": "The document is opened with the Track Changes mode enabled",
"DE.Controllers.Statusbar.zoomText": "Zoom {0}%",
@ -630,7 +633,7 @@
"DE.Views.ChartSettings.textLine": "Line Chart",
"DE.Views.ChartSettings.textOriginalSize": "Default Size",
"DE.Views.ChartSettings.textPie": "Pie Chart",
"DE.Views.ChartSettings.textPoint": "Point Chart",
"DE.Views.ChartSettings.textPoint": "XY (Scatter) Chart",
"DE.Views.ChartSettings.textSize": "Size",
"DE.Views.ChartSettings.textStock": "Stock Chart",
"DE.Views.ChartSettings.textStyle": "Style",
@ -920,6 +923,8 @@
"DE.Views.FileMenuPanels.Settings.textMinute": "Every Minute",
"DE.Views.FileMenuPanels.Settings.txtAll": "View All",
"DE.Views.FileMenuPanels.Settings.txtCm": "Centimeter",
"DE.Views.FileMenuPanels.Settings.txtFitPage": "Fit to Page",
"DE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit to Width",
"DE.Views.FileMenuPanels.Settings.txtInch": "Inch",
"DE.Views.FileMenuPanels.Settings.txtInput": "Alternate Input",
"DE.Views.FileMenuPanels.Settings.txtLast": "View Last",
@ -1245,8 +1250,8 @@
"DE.Views.Statusbar.textChangesPanel": "Changes Panel",
"DE.Views.Statusbar.textTrackChanges": "Track Changes",
"DE.Views.Statusbar.tipAccessRights": "Manage document access rights",
"DE.Views.Statusbar.tipFitPage": "Fit Page",
"DE.Views.Statusbar.tipFitWidth": "Fit Width",
"DE.Views.Statusbar.tipFitPage": "Fit to Page",
"DE.Views.Statusbar.tipFitWidth": "Fit to Width",
"DE.Views.Statusbar.tipMoreUsers": "and %1 users.",
"DE.Views.Statusbar.tipReview": "Review",
"DE.Views.Statusbar.tipSetDocLang": "Set Document Language",
@ -1426,8 +1431,8 @@
"DE.Views.Toolbar.textCompactView": "View Compact Toolbar",
"DE.Views.Toolbar.textContPage": "Continuous Page",
"DE.Views.Toolbar.textEvenPage": "Even Page",
"DE.Views.Toolbar.textFitPage": "Fit Page",
"DE.Views.Toolbar.textFitWidth": "Fit Width",
"DE.Views.Toolbar.textFitPage": "Fit to Page",
"DE.Views.Toolbar.textFitWidth": "Fit to Width",
"DE.Views.Toolbar.textHideLines": "Hide Rulers",
"DE.Views.Toolbar.textHideStatusBar": "Hide Status Bar",
"DE.Views.Toolbar.textHideTitleBar": "Hide Title Bar",
@ -1456,7 +1461,7 @@
"DE.Views.Toolbar.textPageMarginsCustom": "Custom margins",
"DE.Views.Toolbar.textPageSizeCustom": "Custom Page Size",
"DE.Views.Toolbar.textPie": "Pie Chart",
"DE.Views.Toolbar.textPoint": "Point Chart",
"DE.Views.Toolbar.textPoint": "XY (Scatter) Chart",
"DE.Views.Toolbar.textPortrait": "Portrait",
"DE.Views.Toolbar.textRight": "Right: ",
"DE.Views.Toolbar.textStock": "Stock Chart",

View file

@ -86,6 +86,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Reemplazar todo",
"Common.UI.SynchronizeTip.textDontShow": "No volver a mostrar este mensaje",
"Common.UI.SynchronizeTip.textSynchronize": "El documento ha sido cambiado por otro usuario.<br/>Por favor haga clic para guardar sus cambios y recargue las actualizaciones.",
"Common.UI.ThemeColorPalette.textStandartColors": "Colores estándar",
"Common.UI.ThemeColorPalette.textThemeColors": "Colores de tema",
"Common.UI.Window.cancelButtonText": "Cancelar",
"Common.UI.Window.closeButtonText": "Cerrar",
"Common.UI.Window.noButtonText": "No",
@ -156,7 +158,13 @@
"Common.Views.OpenDialog.cancelButtonText": "Cancelar",
"Common.Views.OpenDialog.okButtonText": "Aceptar",
"Common.Views.OpenDialog.txtEncoding": "Codificación",
"Common.Views.OpenDialog.txtPassword": "Password",
"Common.Views.OpenDialog.txtTitle": "Elegir opciones de %1",
"Common.Views.OpenDialog.txtTitleProtected": "Protected File",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"Common.Views.ReviewChanges.txtAccept": "Aceptar",
"Common.Views.ReviewChanges.txtAcceptAll": "Aceptar Todos los Cambios",
"Common.Views.ReviewChanges.txtAcceptCurrent": "Aceptar Cambios Actuales",
@ -202,6 +210,7 @@
"DE.Controllers.Main.errorUpdateVersion": "Se ha cambiado la versión del archivo. La página será actualizada.",
"DE.Controllers.Main.errorUserDrop": "No se puede acceder al archivo ahora.",
"DE.Controllers.Main.errorUsersExceed": "El número de usuarios permitido según su plan de precios fue excedido",
"DE.Controllers.Main.errorViewerDisconnect": "Connection is lost. You can still view the document,<br>but will not be able to download until the connection is restored.",
"DE.Controllers.Main.leavePageText": "Hay cambios no guardados en este documento. Haga clic en 'Permanecer en esta página', después 'Guardar' para guardarlos. Haga clic en 'Abandonar esta página' para descartar todos los cambios no guardados.",
"DE.Controllers.Main.loadFontsTextText": "Cargando datos...",
"DE.Controllers.Main.loadFontsTitleText": "Cargando datos",
@ -216,6 +225,7 @@
"DE.Controllers.Main.mailMergeLoadFileText": "Cargando fuente de datos...",
"DE.Controllers.Main.mailMergeLoadFileTitle": "Cargando fuente de datos",
"DE.Controllers.Main.notcriticalErrorTitle": "Aviso",
"DE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"DE.Controllers.Main.openTextText": "Abriendo documento...",
"DE.Controllers.Main.openTitleText": "Abriendo documento",
"DE.Controllers.Main.printTextText": "Imprimiendo documento...",
@ -223,6 +233,7 @@
"DE.Controllers.Main.reloadButtonText": "Recargar página",
"DE.Controllers.Main.requestEditFailedMessageText": "Alguien está editando este documento en este momento. Por favor, inténtelo de nuevo más tarde.",
"DE.Controllers.Main.requestEditFailedTitleText": "Acceso negado",
"DE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"DE.Controllers.Main.savePreparingText": "Preparando para guardar",
"DE.Controllers.Main.savePreparingTitle": "Preparando para guardar.Espere por favor...",
"DE.Controllers.Main.saveTextText": "Guardando documento...",
@ -240,6 +251,7 @@
"DE.Controllers.Main.textNoLicenseTitle": "ONLYOFFICE open source version",
"DE.Controllers.Main.textStrict": "Modo estricto",
"DE.Controllers.Main.textTryUndoRedo": "Las funciones Anular/Rehacer se desactivan para el modo co-edición rápido.<br>Haga Clic en el botón \"modo estricto\" para cambiar al modo de co-edición estricta para editar el archivo sin la interferencia de otros usuarios y enviar sus cambios sólo después de guardarlos. Se puede cambiar entre los modos de co-edición usando los ajustes avanzados de edición.",
"DE.Controllers.Main.titleLicenseExp": "License expired",
"DE.Controllers.Main.titleUpdateVersion": "Versión ha cambiado",
"DE.Controllers.Main.txtArt": "Su texto aquí",
"DE.Controllers.Main.txtBasicShapes": "Formas básicas",
@ -267,6 +279,7 @@
"DE.Controllers.Main.uploadImageTitleText": "Subiendo imagen",
"DE.Controllers.Main.warnBrowserIE9": "Este aplicación tiene baja capacidad en IE9. Utilice IE10 o superior",
"DE.Controllers.Main.warnBrowserZoom": "La configuración actual de zoom de su navegador no está soportada por completo. Por favor restablezca zoom predeterminado pulsando Ctrl+0.",
"DE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"DE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"DE.Controllers.Main.warnProcessRightsChange": "El derecho de edición del archivo es denegado",
"DE.Controllers.Statusbar.textHasChanges": "Nuevos cambios han sido encontrado",
@ -838,8 +851,6 @@
"DE.Views.DropcapSettingsAdvanced.textRelative": "En relación a\n",
"DE.Views.DropcapSettingsAdvanced.textRight": "Derecho",
"DE.Views.DropcapSettingsAdvanced.textRowHeight": "Altura en filas",
"DE.Views.DropcapSettingsAdvanced.textStandartColors": "Colores estándar",
"DE.Views.DropcapSettingsAdvanced.textThemeColors": "Colores de tema",
"DE.Views.DropcapSettingsAdvanced.textTitle": "Letra capital - ajustes avanzados",
"DE.Views.DropcapSettingsAdvanced.textTitleFrame": "Marco-ajustes avanzados",
"DE.Views.DropcapSettingsAdvanced.textTop": "Superior",
@ -909,6 +920,8 @@
"DE.Views.FileMenuPanels.Settings.textMinute": "Cada minuto",
"DE.Views.FileMenuPanels.Settings.txtAll": "Ver todo",
"DE.Views.FileMenuPanels.Settings.txtCm": "Centímetro",
"DE.Views.FileMenuPanels.Settings.txtFitPage": "Fit to Page",
"DE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit to Width",
"DE.Views.FileMenuPanels.Settings.txtInch": "Pulgada",
"DE.Views.FileMenuPanels.Settings.txtInput": "Entrada alternativa",
"DE.Views.FileMenuPanels.Settings.txtLast": "Ver últimos",
@ -943,6 +956,8 @@
"DE.Views.HyperlinkSettingsDialog.txtEmpty": "Este campo es obligatorio",
"DE.Views.HyperlinkSettingsDialog.txtNotUrl": "Este campo debe ser URL en el formato \"http://www.example.com\"",
"DE.Views.ImageSettings.textAdvanced": "Mostrar ajustes avanzados",
"DE.Views.ImageSettings.textEdit": "Edit",
"DE.Views.ImageSettings.textEditObject": "Edit Object",
"DE.Views.ImageSettings.textFromFile": "De archivo",
"DE.Views.ImageSettings.textFromUrl": "De URL",
"DE.Views.ImageSettings.textHeight": "Altura",
@ -1026,6 +1041,7 @@
"DE.Views.LeftMenu.tipChat": "Chat",
"DE.Views.LeftMenu.tipComments": "Comentarios",
"DE.Views.LeftMenu.tipFile": "Archivo",
"DE.Views.LeftMenu.tipPlugins": "Plugins",
"DE.Views.LeftMenu.tipSearch": "Búsqueda",
"DE.Views.LeftMenu.tipSupport": "Feedback y Soporte",
"DE.Views.LeftMenu.tipTitles": "Títulos",
@ -1108,8 +1124,6 @@
"DE.Views.ParagraphSettings.textBackColor": "Color de fondo",
"DE.Views.ParagraphSettings.textExact": "Exacto",
"DE.Views.ParagraphSettings.textNewColor": "Añadir Color Personalizado Nuevo",
"DE.Views.ParagraphSettings.textStandartColors": "Colores estándar",
"DE.Views.ParagraphSettings.textThemeColors": "Colores de tema",
"DE.Views.ParagraphSettings.txtAutoText": "Auto",
"DE.Views.ParagraphSettingsAdvanced.cancelButtonText": "Cancelar",
"DE.Views.ParagraphSettingsAdvanced.noTabs": "Las pestañas especificadas aparecerán en este campo",
@ -1150,12 +1164,10 @@
"DE.Views.ParagraphSettingsAdvanced.textRight": "Derecho",
"DE.Views.ParagraphSettingsAdvanced.textSet": "Especificar",
"DE.Views.ParagraphSettingsAdvanced.textSpacing": "Espaciado",
"DE.Views.ParagraphSettingsAdvanced.textStandartColors": "Colores estándar",
"DE.Views.ParagraphSettingsAdvanced.textTabCenter": "Al centro",
"DE.Views.ParagraphSettingsAdvanced.textTabLeft": "Izquierdo",
"DE.Views.ParagraphSettingsAdvanced.textTabPosition": "Posición de tab",
"DE.Views.ParagraphSettingsAdvanced.textTabRight": "Derecho",
"DE.Views.ParagraphSettingsAdvanced.textThemeColors": "Colores de tema",
"DE.Views.ParagraphSettingsAdvanced.textTitle": "Párrafo - Ajustes avanzados",
"DE.Views.ParagraphSettingsAdvanced.textTop": "Superior",
"DE.Views.ParagraphSettingsAdvanced.tipAll": "Fijar borde exterior y todas líneas interiores ",
@ -1184,6 +1196,7 @@
"DE.Views.ShapeSettings.strSize": "Tamaño",
"DE.Views.ShapeSettings.strStroke": "Trazo",
"DE.Views.ShapeSettings.strTransparency": "Opacidad ",
"DE.Views.ShapeSettings.strType": "Type",
"DE.Views.ShapeSettings.textAdvanced": "Mostrar ajustes avanzados",
"DE.Views.ShapeSettings.textBorderSizeErr": "El valor numérico es incorrecto.<br>Por favor, introduzca un valor de 0 a 1584 puntos.",
"DE.Views.ShapeSettings.textColor": "Color de relleno",
@ -1200,11 +1213,9 @@
"DE.Views.ShapeSettings.textPatternFill": "Patrón",
"DE.Views.ShapeSettings.textRadial": "Radial",
"DE.Views.ShapeSettings.textSelectTexture": "Seleccionar",
"DE.Views.ShapeSettings.textStandartColors": "Colores estándar",
"DE.Views.ShapeSettings.textStretch": "Estirar",
"DE.Views.ShapeSettings.textStyle": "Estilo",
"DE.Views.ShapeSettings.textTexture": "De textura",
"DE.Views.ShapeSettings.textThemeColors": "Colores de tema",
"DE.Views.ShapeSettings.textTile": "Mosaico",
"DE.Views.ShapeSettings.textWrap": "Ajuste de texto",
"DE.Views.ShapeSettings.txtBehind": "Detrás",
@ -1285,9 +1296,7 @@
"DE.Views.TableSettings.textOK": "Aceptar",
"DE.Views.TableSettings.textRows": "Filas",
"DE.Views.TableSettings.textSelectBorders": "Seleccione bordes que usted desea cambiar aplicando estilo seleccionado",
"DE.Views.TableSettings.textStandartColors": "Colores estándar",
"DE.Views.TableSettings.textTemplate": "Seleccionar de plantilla",
"DE.Views.TableSettings.textThemeColors": "Colores de tema",
"DE.Views.TableSettings.textTotal": "Total",
"DE.Views.TableSettings.textWrap": "Ajuste de texto",
"DE.Views.TableSettings.textWrapNoneTooltip": "Tabla en línea",
@ -1345,12 +1354,10 @@
"DE.Views.TableSettingsAdvanced.textRight": "Derecho",
"DE.Views.TableSettingsAdvanced.textRightOf": "a la derecha de",
"DE.Views.TableSettingsAdvanced.textRightTooltip": "Derecho",
"DE.Views.TableSettingsAdvanced.textStandartColors": "Colores estándar",
"DE.Views.TableSettingsAdvanced.textTable": "Tabla",
"DE.Views.TableSettingsAdvanced.textTableBackColor": "Fondo de tabla",
"DE.Views.TableSettingsAdvanced.textTablePosition": "Posición de la tabla",
"DE.Views.TableSettingsAdvanced.textTableSize": "Tamaño de tabla",
"DE.Views.TableSettingsAdvanced.textThemeColors": "Colores de tema",
"DE.Views.TableSettingsAdvanced.textTitle": "Tabla - Ajustes avanzados",
"DE.Views.TableSettingsAdvanced.textTop": "Superior",
"DE.Views.TableSettingsAdvanced.textVertical": "Vertical",
@ -1381,6 +1388,7 @@
"DE.Views.TextArtSettings.strSize": "Tamaño",
"DE.Views.TextArtSettings.strStroke": "Trazo",
"DE.Views.TextArtSettings.strTransparency": "Opacidad ",
"DE.Views.TextArtSettings.strType": "Type",
"DE.Views.TextArtSettings.textBorderSizeErr": "El valor numérico es incorrecto.<br>Por favor, introduzca un valor de 0 a 1584 puntos.",
"DE.Views.TextArtSettings.textColor": "Color Fill",
"DE.Views.TextArtSettings.textDirection": "Dirección ",
@ -1391,10 +1399,8 @@
"DE.Views.TextArtSettings.textNoFill": "Sin relleno",
"DE.Views.TextArtSettings.textRadial": "Radial",
"DE.Views.TextArtSettings.textSelectTexture": "Seleccionar",
"DE.Views.TextArtSettings.textStandartColors": "Colores estándar",
"DE.Views.TextArtSettings.textStyle": "Estilo",
"DE.Views.TextArtSettings.textTemplate": "Plantilla",
"DE.Views.TextArtSettings.textThemeColors": "Colores de tema",
"DE.Views.TextArtSettings.textTransform": "Transformar",
"DE.Views.TextArtSettings.txtNoBorders": "Sin línea",
"DE.Views.Toolbar.mniCustomTable": "Insertar tabla personalizada",
@ -1434,6 +1440,7 @@
"DE.Views.Toolbar.textInsTextArt": "Insertar Texto de Arte",
"DE.Views.Toolbar.textInText": "En texto",
"DE.Views.Toolbar.textItalic": "Cursiva",
"DE.Views.Toolbar.textLandscape": "Landscape",
"DE.Views.Toolbar.textLeft": "Izquierdo: ",
"DE.Views.Toolbar.textLine": "Gráfico de líneas",
"DE.Views.Toolbar.textMarginsLast": "último personalizado",
@ -1450,8 +1457,8 @@
"DE.Views.Toolbar.textPageSizeCustom": "Tamaño de página personalizado",
"DE.Views.Toolbar.textPie": "Gráfico circular",
"DE.Views.Toolbar.textPoint": "Gráfico de Punto",
"DE.Views.Toolbar.textPortrait": "Portrait",
"DE.Views.Toolbar.textRight": "Derecho: ",
"DE.Views.Toolbar.textStandartColors": "Colores estándar",
"DE.Views.Toolbar.textStock": "De cotizaciones",
"DE.Views.Toolbar.textStrikeout": "Tachado",
"DE.Views.Toolbar.textStyleMenuDelete": "Eliminar estilo",
@ -1462,7 +1469,6 @@
"DE.Views.Toolbar.textStyleMenuUpdate": "Actualizar de la selección",
"DE.Views.Toolbar.textSubscript": "Subíndice",
"DE.Views.Toolbar.textSuperscript": "Sobreíndice",
"DE.Views.Toolbar.textThemeColors": "Colores de tema",
"DE.Views.Toolbar.textTitleError": "Error",
"DE.Views.Toolbar.textToCurrent": "A la posición actual",
"DE.Views.Toolbar.textTop": "Top: ",

View file

@ -86,6 +86,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Remplacer tout",
"Common.UI.SynchronizeTip.textDontShow": "N'afficher plus ce message",
"Common.UI.SynchronizeTip.textSynchronize": "Le document a été modifié par un autre utilisateur.<br/>Cliquez pour enregistrer vos modifications et recharger les mises à jour.",
"Common.UI.ThemeColorPalette.textStandartColors": "Couleurs standard",
"Common.UI.ThemeColorPalette.textThemeColors": "Couleurs de thème",
"Common.UI.Window.cancelButtonText": "Annuler",
"Common.UI.Window.closeButtonText": "Fermer",
"Common.UI.Window.noButtonText": "Non",
@ -156,7 +158,13 @@
"Common.Views.OpenDialog.cancelButtonText": "Annuler",
"Common.Views.OpenDialog.okButtonText": "OK",
"Common.Views.OpenDialog.txtEncoding": "Codage ",
"Common.Views.OpenDialog.txtPassword": "Password",
"Common.Views.OpenDialog.txtTitle": "Choisir %1 des options ",
"Common.Views.OpenDialog.txtTitleProtected": "Protected File",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"Common.Views.ReviewChanges.txtAccept": "Accepter",
"Common.Views.ReviewChanges.txtAcceptAll": "Accepter toutes les modifications",
"Common.Views.ReviewChanges.txtAcceptCurrent": "Accepter la modification actuelle",
@ -202,6 +210,7 @@
"DE.Controllers.Main.errorUpdateVersion": "La version du fichier a été changée. La page sera rechargée.",
"DE.Controllers.Main.errorUserDrop": "Impossible d'accéder au fichier",
"DE.Controllers.Main.errorUsersExceed": "Le nombre d'utilisateurs autorisés par le plan tarifaire a été dépassé",
"DE.Controllers.Main.errorViewerDisconnect": "Connection is lost. You can still view the document,<br>but will not be able to download until the connection is restored.",
"DE.Controllers.Main.leavePageText": "Vous avez des modifications non enregistrées dans ce document. Cliquez sur 'Rester sur cette page', ensuite sur 'Enregistrer' pour enregistrer les modifications. Cliquez sur 'Quitter cette page' pour annuler toutes les modifications non enregistrées.",
"DE.Controllers.Main.loadFontsTextText": "Chargement des données...",
"DE.Controllers.Main.loadFontsTitleText": "Chargement des données",
@ -216,6 +225,7 @@
"DE.Controllers.Main.mailMergeLoadFileText": "Chargement de la source des données...",
"DE.Controllers.Main.mailMergeLoadFileTitle": "Chargement de la source des données",
"DE.Controllers.Main.notcriticalErrorTitle": "Avertissement",
"DE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"DE.Controllers.Main.openTextText": "Ouverture du document...",
"DE.Controllers.Main.openTitleText": "Ouverture du document",
"DE.Controllers.Main.printTextText": "Impression d'un document...",
@ -223,6 +233,7 @@
"DE.Controllers.Main.reloadButtonText": "Recharger la page",
"DE.Controllers.Main.requestEditFailedMessageText": "Quelqu'un est en train de modifier ce document. Veuillez réessayer plus tard.",
"DE.Controllers.Main.requestEditFailedTitleText": "Accès refusé",
"DE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"DE.Controllers.Main.savePreparingText": "Préparation à l'enregistrement ",
"DE.Controllers.Main.savePreparingTitle": "Préparation à l'enregistrement en cours. Veuillez patienter...",
"DE.Controllers.Main.saveTextText": "Enregistrement du document...",
@ -240,6 +251,7 @@
"DE.Controllers.Main.textNoLicenseTitle": "ONLYOFFICE open source version",
"DE.Controllers.Main.textStrict": "Mode strict",
"DE.Controllers.Main.textTryUndoRedo": "Les fonctions annuler/rétablir sont désactivées pour le mode de co-édition rapide.<br>Cliquez sur le bouton \"Mode strict\" pour passer au mode de la co-édition stricte pour modifier le fichier sans interférence d'autres utilisateurs et envoyer vos modifications seulement après que vous les enregistrez. Vous pouvez basculer entre les modes de co-édition à l'aide de paramètres avancés d'éditeur.",
"DE.Controllers.Main.titleLicenseExp": "License expired",
"DE.Controllers.Main.titleUpdateVersion": "Version a été modifiée",
"DE.Controllers.Main.txtArt": "Votre texte ici",
"DE.Controllers.Main.txtBasicShapes": "Formes de base",
@ -267,6 +279,7 @@
"DE.Controllers.Main.uploadImageTitleText": "Chargement d'une image",
"DE.Controllers.Main.warnBrowserIE9": "L'application est peu compatible avec IE9. Utilisez IE10 ou version plus récente",
"DE.Controllers.Main.warnBrowserZoom": "Le paramètre actuel de zoom de votre navigateur n'est pas accepté. Veuillez rétablir le niveau de zoom par défaut en appuyant sur Ctrl+0.",
"DE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"DE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"DE.Controllers.Main.warnProcessRightsChange": "Le droit d'édition du fichier vous a été refusé.",
"DE.Controllers.Statusbar.textHasChanges": "Nouveaux changements ont été suivis",
@ -829,7 +842,7 @@
"DE.Views.DropcapSettingsAdvanced.textLeft": "A gauche",
"DE.Views.DropcapSettingsAdvanced.textMargin": "Marge",
"DE.Views.DropcapSettingsAdvanced.textMove": "Déplacer avec le texte",
"DE.Views.DropcapSettingsAdvanced.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"DE.Views.DropcapSettingsAdvanced.textNewColor": "Couleur Personnalisée",
"DE.Views.DropcapSettingsAdvanced.textNone": "Aucune",
"DE.Views.DropcapSettingsAdvanced.textPage": "Page",
"DE.Views.DropcapSettingsAdvanced.textParagraph": "Paragraphe",
@ -838,8 +851,6 @@
"DE.Views.DropcapSettingsAdvanced.textRelative": "par rapport à",
"DE.Views.DropcapSettingsAdvanced.textRight": "A droite",
"DE.Views.DropcapSettingsAdvanced.textRowHeight": "Hauteur des lignes",
"DE.Views.DropcapSettingsAdvanced.textStandartColors": "Couleurs standard",
"DE.Views.DropcapSettingsAdvanced.textThemeColors": "Couleurs de thème",
"DE.Views.DropcapSettingsAdvanced.textTitle": "Lettrine - Paramètres avancés",
"DE.Views.DropcapSettingsAdvanced.textTitleFrame": "Cadre - Paramètres avancés",
"DE.Views.DropcapSettingsAdvanced.textTop": "En haut",
@ -909,6 +920,8 @@
"DE.Views.FileMenuPanels.Settings.textMinute": "Chaque minute",
"DE.Views.FileMenuPanels.Settings.txtAll": "Voir tout",
"DE.Views.FileMenuPanels.Settings.txtCm": "Centimètre",
"DE.Views.FileMenuPanels.Settings.txtFitPage": "Fit to Page",
"DE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit to Width",
"DE.Views.FileMenuPanels.Settings.txtInch": "Pouce",
"DE.Views.FileMenuPanels.Settings.txtInput": "Entrée alternative",
"DE.Views.FileMenuPanels.Settings.txtLast": "Voir le dernier",
@ -943,6 +956,8 @@
"DE.Views.HyperlinkSettingsDialog.txtEmpty": "Ce champ est obligatoire",
"DE.Views.HyperlinkSettingsDialog.txtNotUrl": "Ce champ doit être une URL au format \"http://www.example.com\"",
"DE.Views.ImageSettings.textAdvanced": "Afficher les paramètres avancés",
"DE.Views.ImageSettings.textEdit": "Edit",
"DE.Views.ImageSettings.textEditObject": "Edit Object",
"DE.Views.ImageSettings.textFromFile": "Depuis un fichier",
"DE.Views.ImageSettings.textFromUrl": "D'une URL",
"DE.Views.ImageSettings.textHeight": "Hauteur",
@ -1026,6 +1041,7 @@
"DE.Views.LeftMenu.tipChat": "Chat",
"DE.Views.LeftMenu.tipComments": "Commentaires",
"DE.Views.LeftMenu.tipFile": "Fichier",
"DE.Views.LeftMenu.tipPlugins": "Plugins",
"DE.Views.LeftMenu.tipSearch": "Recherche",
"DE.Views.LeftMenu.tipSupport": "Commentaires & assistance",
"DE.Views.LeftMenu.tipTitles": "Titres",
@ -1107,9 +1123,7 @@
"DE.Views.ParagraphSettings.textAuto": "Plusieurs",
"DE.Views.ParagraphSettings.textBackColor": "Couleur d'arrière-plan",
"DE.Views.ParagraphSettings.textExact": "Exactement",
"DE.Views.ParagraphSettings.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"DE.Views.ParagraphSettings.textStandartColors": "Couleurs standard",
"DE.Views.ParagraphSettings.textThemeColors": "Couleurs de thème",
"DE.Views.ParagraphSettings.textNewColor": "Couleur Personnalisée",
"DE.Views.ParagraphSettings.txtAutoText": "Auto",
"DE.Views.ParagraphSettingsAdvanced.cancelButtonText": "Annuler",
"DE.Views.ParagraphSettingsAdvanced.noTabs": "Les onglets spécifiés s'affichent dans ce champ",
@ -1143,19 +1157,17 @@
"DE.Views.ParagraphSettingsAdvanced.textDefault": "Onglet par défaut",
"DE.Views.ParagraphSettingsAdvanced.textEffects": "Effets",
"DE.Views.ParagraphSettingsAdvanced.textLeft": "A gauche",
"DE.Views.ParagraphSettingsAdvanced.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"DE.Views.ParagraphSettingsAdvanced.textNewColor": "Couleur Personnalisée",
"DE.Views.ParagraphSettingsAdvanced.textPosition": "Position",
"DE.Views.ParagraphSettingsAdvanced.textRemove": "Supprimer",
"DE.Views.ParagraphSettingsAdvanced.textRemoveAll": "Supprimer tout",
"DE.Views.ParagraphSettingsAdvanced.textRight": "A droite",
"DE.Views.ParagraphSettingsAdvanced.textSet": "Spécifier",
"DE.Views.ParagraphSettingsAdvanced.textSpacing": "Espacement",
"DE.Views.ParagraphSettingsAdvanced.textStandartColors": "Couleurs standard",
"DE.Views.ParagraphSettingsAdvanced.textTabCenter": "Centre",
"DE.Views.ParagraphSettingsAdvanced.textTabLeft": "A gauche",
"DE.Views.ParagraphSettingsAdvanced.textTabPosition": "Position d'onglet",
"DE.Views.ParagraphSettingsAdvanced.textTabRight": "A droite",
"DE.Views.ParagraphSettingsAdvanced.textThemeColors": "Couleurs de thème",
"DE.Views.ParagraphSettingsAdvanced.textTitle": "Paragraphe - Paramètres avancés",
"DE.Views.ParagraphSettingsAdvanced.textTop": "En haut",
"DE.Views.ParagraphSettingsAdvanced.tipAll": "Bordure extérieure et la totalité des lignes intérieures",
@ -1184,6 +1196,7 @@
"DE.Views.ShapeSettings.strSize": "Taille",
"DE.Views.ShapeSettings.strStroke": "Trait",
"DE.Views.ShapeSettings.strTransparency": "Opacité",
"DE.Views.ShapeSettings.strType": "Type",
"DE.Views.ShapeSettings.textAdvanced": "Afficher les paramètres avancés",
"DE.Views.ShapeSettings.textBorderSizeErr": "La valeur saisie est incorrecte. <br>Entrez une valeur de 0 à 1584 points.",
"DE.Views.ShapeSettings.textColor": "Couleur de remplissage",
@ -1195,16 +1208,14 @@
"DE.Views.ShapeSettings.textGradientFill": "Remplissage en dégradé",
"DE.Views.ShapeSettings.textImageTexture": "Image ou texture",
"DE.Views.ShapeSettings.textLinear": "Linéaire",
"DE.Views.ShapeSettings.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"DE.Views.ShapeSettings.textNewColor": "Couleur Personnalisée",
"DE.Views.ShapeSettings.textNoFill": "Pas de remplissage",
"DE.Views.ShapeSettings.textPatternFill": "Modèle",
"DE.Views.ShapeSettings.textRadial": "Radial",
"DE.Views.ShapeSettings.textSelectTexture": "Sélectionner",
"DE.Views.ShapeSettings.textStandartColors": "Couleurs standard",
"DE.Views.ShapeSettings.textStretch": "Étirement",
"DE.Views.ShapeSettings.textStyle": "Style",
"DE.Views.ShapeSettings.textTexture": "D'une texture",
"DE.Views.ShapeSettings.textThemeColors": "Couleurs de thème",
"DE.Views.ShapeSettings.textTile": "Tuile",
"DE.Views.ShapeSettings.textWrap": "Style d'habillage",
"DE.Views.ShapeSettings.txtBehind": "Derrière",
@ -1281,13 +1292,11 @@
"DE.Views.TableSettings.textFirst": "Premier",
"DE.Views.TableSettings.textHeader": "En-tête",
"DE.Views.TableSettings.textLast": "Dernier",
"DE.Views.TableSettings.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"DE.Views.TableSettings.textNewColor": "Couleur Personnalisée",
"DE.Views.TableSettings.textOK": "OK",
"DE.Views.TableSettings.textRows": "Lignes",
"DE.Views.TableSettings.textSelectBorders": "Sélectionnez les bordures à modifier en appliquant le style choisi ci-dessus",
"DE.Views.TableSettings.textStandartColors": "Couleurs standard",
"DE.Views.TableSettings.textTemplate": "Sélectionner à partir d'un modèle",
"DE.Views.TableSettings.textThemeColors": "Couleurs de thème",
"DE.Views.TableSettings.textTotal": "Total",
"DE.Views.TableSettings.textWrap": "Habillage du texte",
"DE.Views.TableSettings.textWrapNoneTooltip": "Tableau aligné",
@ -1333,7 +1342,7 @@
"DE.Views.TableSettingsAdvanced.textMargins": "Marges de la cellule",
"DE.Views.TableSettingsAdvanced.textMeasure": "Mesure en",
"DE.Views.TableSettingsAdvanced.textMove": "Déplacer avec le texte",
"DE.Views.TableSettingsAdvanced.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"DE.Views.TableSettingsAdvanced.textNewColor": "Couleur Personnalisée",
"DE.Views.TableSettingsAdvanced.textOnlyCells": "Seulement pour des cellules sélectionnées",
"DE.Views.TableSettingsAdvanced.textOptions": "Options",
"DE.Views.TableSettingsAdvanced.textOverlap": "Autoriser le chevauchement",
@ -1345,12 +1354,10 @@
"DE.Views.TableSettingsAdvanced.textRight": "A droite",
"DE.Views.TableSettingsAdvanced.textRightOf": "à droite de",
"DE.Views.TableSettingsAdvanced.textRightTooltip": "A droite",
"DE.Views.TableSettingsAdvanced.textStandartColors": "Couleurs standard",
"DE.Views.TableSettingsAdvanced.textTable": "Tableau",
"DE.Views.TableSettingsAdvanced.textTableBackColor": "Tableau de fond",
"DE.Views.TableSettingsAdvanced.textTablePosition": "Position du tableau",
"DE.Views.TableSettingsAdvanced.textTableSize": "Taille du tableau",
"DE.Views.TableSettingsAdvanced.textThemeColors": "Couleurs de thème",
"DE.Views.TableSettingsAdvanced.textTitle": "Tableau - Paramètres avancés",
"DE.Views.TableSettingsAdvanced.textTop": "En haut",
"DE.Views.TableSettingsAdvanced.textVertical": "Vertical",
@ -1381,20 +1388,19 @@
"DE.Views.TextArtSettings.strSize": "Size",
"DE.Views.TextArtSettings.strStroke": "Trait",
"DE.Views.TextArtSettings.strTransparency": "Opacité",
"DE.Views.TextArtSettings.strType": "Type",
"DE.Views.TextArtSettings.textBorderSizeErr": "La valeur saisie est incorrecte. <br>Entrez une valeur de 0 à 1584 points.",
"DE.Views.TextArtSettings.textColor": "Couleur de remplissage",
"DE.Views.TextArtSettings.textDirection": "Direction",
"DE.Views.TextArtSettings.textGradient": "Dégradé",
"DE.Views.TextArtSettings.textGradientFill": "Remplissage en dégradé",
"DE.Views.TextArtSettings.textLinear": "Linéaire",
"DE.Views.TextArtSettings.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"DE.Views.TextArtSettings.textNewColor": "Couleur Personnalisée",
"DE.Views.TextArtSettings.textNoFill": "Pas de remplissage",
"DE.Views.TextArtSettings.textRadial": "Radial",
"DE.Views.TextArtSettings.textSelectTexture": "Sélectionner",
"DE.Views.TextArtSettings.textStandartColors": "Couleurs standard",
"DE.Views.TextArtSettings.textStyle": "Style",
"DE.Views.TextArtSettings.textTemplate": "Modèle",
"DE.Views.TextArtSettings.textThemeColors": "Couleurs de thème",
"DE.Views.TextArtSettings.textTransform": "Transformer",
"DE.Views.TextArtSettings.txtNoBorders": "Pas de ligne",
"DE.Views.Toolbar.mniCustomTable": "Inserer tableau personnalisé",
@ -1434,6 +1440,7 @@
"DE.Views.Toolbar.textInsTextArt": "Insérer le texte Art",
"DE.Views.Toolbar.textInText": "Dans le Texte",
"DE.Views.Toolbar.textItalic": "Italique",
"DE.Views.Toolbar.textLandscape": "Landscape",
"DE.Views.Toolbar.textLeft": "À gauche:",
"DE.Views.Toolbar.textLine": "Graphique en ligne",
"DE.Views.Toolbar.textMarginsLast": "Dernière mesure",
@ -1442,7 +1449,7 @@
"DE.Views.Toolbar.textMarginsNormal": "Normal",
"DE.Views.Toolbar.textMarginsUsNormal": "US normale",
"DE.Views.Toolbar.textMarginsWide": "Large",
"DE.Views.Toolbar.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"DE.Views.Toolbar.textNewColor": "Couleur Personnalisée",
"DE.Views.Toolbar.textNextPage": "Page suivante",
"DE.Views.Toolbar.textNone": "Aucune",
"DE.Views.Toolbar.textOddPage": "Page impaire",
@ -1450,8 +1457,8 @@
"DE.Views.Toolbar.textPageSizeCustom": "Taille de page personnalisé",
"DE.Views.Toolbar.textPie": "Graphiques à secteurs",
"DE.Views.Toolbar.textPoint": "Diagramme de dispersion",
"DE.Views.Toolbar.textPortrait": "Portrait",
"DE.Views.Toolbar.textRight": "A droite: ",
"DE.Views.Toolbar.textStandartColors": "Couleurs standard",
"DE.Views.Toolbar.textStock": "Graphique d'état de stocks",
"DE.Views.Toolbar.textStrikeout": "Barré",
"DE.Views.Toolbar.textStyleMenuDelete": "Supprimer le style",
@ -1462,7 +1469,6 @@
"DE.Views.Toolbar.textStyleMenuUpdate": "Mise à jour de la sélection",
"DE.Views.Toolbar.textSubscript": "Indice",
"DE.Views.Toolbar.textSuperscript": "Exposant",
"DE.Views.Toolbar.textThemeColors": "Couleurs de thème",
"DE.Views.Toolbar.textTitleError": "Erreur",
"DE.Views.Toolbar.textToCurrent": "A la position actuelle",
"DE.Views.Toolbar.textTop": "En haut: ",

View file

@ -211,6 +211,7 @@ Ext.define('DE.controller.Main', {
onLongActionEnd: function(type) {
Ext.Viewport.unmask();
Common.Gateway.setDocumentModified(this.api.isDocumentModified());
},
onError: function(id, level, errData) {

View file

@ -130,6 +130,24 @@ Ext.define('DE.controller.toolbar.Edit', {
}
}, this);
if (Ext.os.is.iOS) {
Ext.each(Ext.ComponentQuery.query('button'), function(button) {
button.element.dom.ontouchstart = Ext.emptyFn();
button.element.dom.ontouchmove = Ext.emptyFn();
button.element.dom.ontouchend = Ext.emptyFn();
}, this);
Ext.each(Ext.ComponentQuery.query('toolbar'), function(toolbar) {
var preventFn = function(e){
e.preventDefault();
};
toolbar.element.dom.ontouchstart = preventFn;
toolbar.element.dom.ontouchmove = preventFn;
toolbar.element.dom.ontouchend = preventFn;
}, this);
}
Common.Gateway.on('init', Ext.bind(this.loadConfig, this));
},
@ -148,6 +166,7 @@ Ext.define('DE.controller.toolbar.Edit', {
this.api.asc_registerCallback('asc_onCanUndo', Ext.bind(this.onApiCanUndo, this));
this.api.asc_registerCallback('asc_onCoAuthoringDisconnect', Ext.bind(this.onCoAuthoringDisconnect, this));
this.api.asc_registerCallback('asc_onDocumentModifiedChanged', Ext.bind(this.onApiDocumentModified, this));
this.api.asc_registerCallback('asc_onDocumentCanSaveChanged', Ext.bind(this.onApiDocumentCanSaveChanged, this));
}
},
@ -181,7 +200,7 @@ Ext.define('DE.controller.toolbar.Edit', {
},
onApiDocumentModified: function() {
var isModified = this.api.isDocumentModified();
var isModified = this.api.asc_isDocumentCanSave();
if (this.isDocModified !== isModified) {
if (this.getSaveButton()) {
this.getSaveButton().setDisabled(!isModified);
@ -192,6 +211,12 @@ Ext.define('DE.controller.toolbar.Edit', {
}
},
onApiDocumentCanSaveChanged: function (isCanSave) {
if (this.getSaveButton()) {
this.getSaveButton().setDisabled(!isCanSave);
}
},
showToolbarPanel: function(panel, button){
if (panel && button){
panel.on('hide', Ext.bind(function(){
@ -240,6 +265,8 @@ Ext.define('DE.controller.toolbar.Edit', {
onTapSave: function() {
this.api && this.api.asc_Save();
this.getSaveButton().setDisabled(true);
Common.component.Analytics.trackEvent('ToolBar', 'Save');
},

View file

@ -87,6 +87,24 @@ Ext.define('DE.controller.toolbar.View', {
launch: function() {
this.callParent(arguments);
if (Ext.os.is.iOS) {
Ext.each(Ext.ComponentQuery.query('button'), function(button) {
button.element.dom.ontouchstart = Ext.emptyFn();
button.element.dom.ontouchmove = Ext.emptyFn();
button.element.dom.ontouchend = Ext.emptyFn();
}, this);
Ext.each(Ext.ComponentQuery.query('toolbar'), function(toolbar) {
var preventFn = function(e){
e.preventDefault();
};
toolbar.element.dom.ontouchstart = preventFn;
toolbar.element.dom.ontouchmove = preventFn;
toolbar.element.dom.ontouchend = preventFn;
}, this);
}
Common.Gateway.on('init', Ext.bind(this.loadConfig, this));
Common.Gateway.on('opendocument', Ext.bind(this.loadDocument, this));
Common.Gateway.on('applyeditrights',Ext.bind(this.onApplyEditRights, this));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -742,12 +742,10 @@ define([
this._state.licenseWarning = (licType===Asc.c_oLicenseResult.Connections) && this.appOptions.canEdit && this.editorConfig.mode !== 'view';
this.appOptions.canBranding = params.asc_getCanBranding() && (typeof this.editorConfig.customization == 'object');
if (this.appOptions.canBranding) {
this.getApplication()
.getController('Viewport')
.getView('Common.Views.Header')
.setBranding(this.editorConfig.customization);
}
if (this.appOptions.canBranding)
this.getApplication().getController('Viewport').getView('Common.Views.Header').setBranding(this.editorConfig.customization);
params.asc_getTrial() && this.getApplication().getController('Viewport').getView('Common.Views.Header').setDeveloperMode(true);
this.applyModeCommonElements();
this.applyModeEditorElements();

View file

@ -28,6 +28,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Alle ersetzen",
"Common.UI.SynchronizeTip.textDontShow": "Diese Meldung nicht mehr anzeigen",
"Common.UI.SynchronizeTip.textSynchronize": "Das Dokument wurde von einem anderen Benutzer geändert.<br/>Bitte speichern Sie Ihre Änderungen und aktualisieren Sie Ihre Seite.",
"Common.UI.ThemeColorPalette.textStandartColors": "Standardfarben",
"Common.UI.ThemeColorPalette.textThemeColors": "Designfarben",
"Common.UI.Window.cancelButtonText": "Abbrechen",
"Common.UI.Window.closeButtonText": "Schließen",
"Common.UI.Window.noButtonText": "Nein",
@ -215,6 +217,7 @@
"PE.Controllers.Main.uploadImageTitleText": "Bild wird hochgeladen",
"PE.Controllers.Main.warnBrowserIE9": "Die Anwendung hat geringe Fähigkeiten in IE9. Nutzen Sie IE10 oder höher.",
"PE.Controllers.Main.warnBrowserZoom": "Die aktuelle Zoom-Einstellung Ihres Webbrowsers wird nicht völlig unterstützt. Bitte stellen Sie die Standardeinstellung mithilfe der Tastenkombination Strg+0 wieder her.",
"PE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"PE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"PE.Controllers.Main.warnProcessRightsChange": "Das Recht, die Datei zu bearbeiten, wurde Ihnen verweigert.",
"PE.Controllers.Statusbar.zoomText": "Zoom {0}%",
@ -371,6 +374,7 @@
"PE.Views.FileMenuPanels.Settings.txtAll": "Alle anzeigen",
"PE.Views.FileMenuPanels.Settings.txtCm": "Zentimeter",
"PE.Views.FileMenuPanels.Settings.txtFitSlide": "Folie anpassen",
"PE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit to Width",
"PE.Views.FileMenuPanels.Settings.txtInch": "Zoll",
"PE.Views.FileMenuPanels.Settings.txtInput": "Eingabe ändern",
"PE.Views.FileMenuPanels.Settings.txtLast": "Letzte anzeigen",
@ -397,6 +401,8 @@
"PE.Views.HyperlinkSettingsDialog.txtPrev": "Vorherige Folie",
"PE.Views.HyperlinkSettingsDialog.txtSlide": "Folie",
"PE.Views.ImageSettings.textAdvanced": "Erweiterte Einstellungen anzeigen",
"PE.Views.ImageSettings.textEdit": "Edit",
"PE.Views.ImageSettings.textEditObject": "Edit Object",
"PE.Views.ImageSettings.textFromFile": "Aus Datei",
"PE.Views.ImageSettings.textFromUrl": "Aus URL",
"PE.Views.ImageSettings.textHeight": "Höhe",
@ -417,6 +423,7 @@
"PE.Views.LeftMenu.tipChat": "Chat",
"PE.Views.LeftMenu.tipComments": "Kommentare",
"PE.Views.LeftMenu.tipFile": "Datei",
"PE.Views.LeftMenu.tipPlugins": "Plugins",
"PE.Views.LeftMenu.tipSearch": "Suche",
"PE.Views.LeftMenu.tipSlides": "Folien",
"PE.Views.LeftMenu.tipSupport": "Feedback und Support",
@ -474,6 +481,7 @@
"PE.Views.ShapeSettings.strSize": "Größe",
"PE.Views.ShapeSettings.strStroke": "Strich",
"PE.Views.ShapeSettings.strTransparency": "Undurchsichtigkeit",
"PE.Views.ShapeSettings.strType": "Type",
"PE.Views.ShapeSettings.textAdvanced": "Erweiterte Einstellungen anzeigen",
"PE.Views.ShapeSettings.textBorderSizeErr": "Der eingegebene Wert ist falsch.<br>Bitte geben Sie einen Wert zwischen 0 pt und 1584 pt ein.",
"PE.Views.ShapeSettings.textColor": "Farbfüllung",
@ -490,11 +498,9 @@
"PE.Views.ShapeSettings.textPatternFill": "Muster",
"PE.Views.ShapeSettings.textRadial": "Radial",
"PE.Views.ShapeSettings.textSelectTexture": "Wählen",
"PE.Views.ShapeSettings.textStandartColors": "Standardfarben",
"PE.Views.ShapeSettings.textStretch": "Ausdehnung",
"PE.Views.ShapeSettings.textStyle": "Stil",
"PE.Views.ShapeSettings.textTexture": "Aus Textur",
"PE.Views.ShapeSettings.textThemeColors": "Designfarben",
"PE.Views.ShapeSettings.textTile": "Kachel",
"PE.Views.ShapeSettings.txtBrownPaper": "Kraftpapier",
"PE.Views.ShapeSettings.txtCanvas": "Canvas",
@ -580,11 +586,9 @@
"PE.Views.SlideSettings.textSelectTexture": "Wählen",
"PE.Views.SlideSettings.textSmoothly": "Gleitend",
"PE.Views.SlideSettings.textSplit": "Aufteilen",
"PE.Views.SlideSettings.textStandartColors": "Standardfarben",
"PE.Views.SlideSettings.textStretch": "Ausdehnung",
"PE.Views.SlideSettings.textStyle": "Stil",
"PE.Views.SlideSettings.textTexture": "Aus Textur",
"PE.Views.SlideSettings.textThemeColors": "Designfarben",
"PE.Views.SlideSettings.textTile": "Kachel",
"PE.Views.SlideSettings.textTop": "Oben",
"PE.Views.SlideSettings.textTopLeft": "Oben links",
@ -609,9 +613,16 @@
"PE.Views.SlideSettings.txtLeather": "Leder",
"PE.Views.SlideSettings.txtPapyrus": "Papyrus",
"PE.Views.SlideSettings.txtWood": "Holz",
"PE.Views.SlideshowSettings.cancelButtonText": "Cancel",
"PE.Views.SlideshowSettings.okButtonText": "Ok",
"PE.Views.SlideshowSettings.textLoop": "Loop continuously until 'Esc' is pressed",
"PE.Views.SlideshowSettings.textTitle": "Show Settings",
"PE.Views.SlideSizeSettings.cancelButtonText": "Abbrechen",
"PE.Views.SlideSizeSettings.okButtonText": "OK",
"PE.Views.SlideSizeSettings.strLandscape": "Landscape",
"PE.Views.SlideSizeSettings.strPortrait": "Portrait",
"PE.Views.SlideSizeSettings.textHeight": "Höhe",
"PE.Views.SlideSizeSettings.textSlideOrientation": "Slide Orientation",
"PE.Views.SlideSizeSettings.textSlideSize": "Foliengröße",
"PE.Views.SlideSizeSettings.textTitle": "Einstellungen der Foliengröße",
"PE.Views.SlideSizeSettings.textWidth": "Breite",
@ -671,9 +682,7 @@
"PE.Views.TableSettings.textNewColor": "Benutzerdefinierte Farbe",
"PE.Views.TableSettings.textRows": "Zeilen",
"PE.Views.TableSettings.textSelectBorders": "Wählen Sie die Rahmenlinien, auf die ein anderer Stil angewandt wird",
"PE.Views.TableSettings.textStandartColors": "Standardfarben",
"PE.Views.TableSettings.textTemplate": "Vorlage auswählen",
"PE.Views.TableSettings.textThemeColors": "Designfarben",
"PE.Views.TableSettings.textTotal": "Insgesamt",
"PE.Views.TableSettings.tipAll": "Äußere Rahmenlinie und alle inneren Linien festlegen",
"PE.Views.TableSettings.tipBottom": "Nur äußere untere Rahmenlinie festlegen",
@ -705,6 +714,7 @@
"PE.Views.TextArtSettings.strSize": "Größe",
"PE.Views.TextArtSettings.strStroke": "Strich",
"PE.Views.TextArtSettings.strTransparency": "Undurchsichtigkeit",
"PE.Views.TextArtSettings.strType": "Type",
"PE.Views.TextArtSettings.textBorderSizeErr": "Der eingegebene Wert ist falsch.<br>Bitte geben Sie einen Wert zwischen 0 pt und 1584 pt ein.",
"PE.Views.TextArtSettings.textColor": "Farbfüllung",
"PE.Views.TextArtSettings.textDirection": "Direction",
@ -715,17 +725,15 @@
"PE.Views.TextArtSettings.textGradientFill": "Füllung mit Farbverlauf",
"PE.Views.TextArtSettings.textImageTexture": "Bild oder Textur",
"PE.Views.TextArtSettings.textLinear": "Linear",
"PE.Views.TextArtSettings.textNewColor": "Neue benutzerdefinierte Farbpalette hinzufügen",
"PE.Views.TextArtSettings.textNewColor": "Benutzerdefinierte Farbe",
"PE.Views.TextArtSettings.textNoFill": "Keine Füllung",
"PE.Views.TextArtSettings.textPatternFill": "Muster",
"PE.Views.TextArtSettings.textRadial": "Radial",
"PE.Views.TextArtSettings.textSelectTexture": "Wählen",
"PE.Views.TextArtSettings.textStandartColors": "Standardfarben",
"PE.Views.TextArtSettings.textStretch": "Ausdehnung",
"PE.Views.TextArtSettings.textStyle": "Stil",
"PE.Views.TextArtSettings.textTemplate": "Vorlage",
"PE.Views.TextArtSettings.textTexture": "Aus Textur",
"PE.Views.TextArtSettings.textThemeColors": "Designfarben",
"PE.Views.TextArtSettings.textTile": "Kachel",
"PE.Views.TextArtSettings.textTransform": "Transformieren\t",
"PE.Views.TextArtSettings.txtBrownPaper": "Kraftpapier",
@ -782,12 +790,13 @@
"PE.Views.Toolbar.textShapeAlignMiddle": "Mittig ausrichten",
"PE.Views.Toolbar.textShapeAlignRight": "Rechts ausrichten",
"PE.Views.Toolbar.textShapeAlignTop": "Oben ausrichten",
"PE.Views.Toolbar.textStandartColors": "Standardfarben",
"PE.Views.Toolbar.textShowBegin": "Show from Beginning",
"PE.Views.Toolbar.textShowCurrent": "Show from Current slide",
"PE.Views.Toolbar.textShowSettings": "Show Settings",
"PE.Views.Toolbar.textStock": "Kurs",
"PE.Views.Toolbar.textStrikeout": "Durchgestrichen",
"PE.Views.Toolbar.textSubscript": "Tiefgestellt",
"PE.Views.Toolbar.textSuperscript": "Hochgestellt",
"PE.Views.Toolbar.textThemeColors": "Designfarben",
"PE.Views.Toolbar.textTitleError": "Fehler",
"PE.Views.Toolbar.textUnderline": "Unterstrichen",
"PE.Views.Toolbar.textZoom": "Zoom",

View file

@ -80,6 +80,7 @@
"Common.Views.ExternalDiagramEditor.textTitle": "Chart Editor",
"Common.Views.Header.openNewTabText": "Open in New Tab",
"Common.Views.Header.textBack": "Go to Documents",
"Common.Views.Header.txtHeaderDeveloper": "DEVELOPER MODE",
"Common.Views.ImageFromUrlDialog.cancelButtonText": "Cancel",
"Common.Views.ImageFromUrlDialog.okButtonText": "OK",
"Common.Views.ImageFromUrlDialog.textUrl": "Paste an image URL:",
@ -93,10 +94,10 @@
"Common.Views.InsertTableDialog.txtMinText": "The minimum value for this field is {0}.",
"Common.Views.InsertTableDialog.txtRows": "Number of Rows",
"Common.Views.InsertTableDialog.txtTitle": "Table Size",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"Common.Views.PluginDlg.textLoading": "Loading",
"PE.Controllers.LeftMenu.newDocumentTitle": "Unnamed presentation",
"PE.Controllers.LeftMenu.requestEditRightsText": "Requesting editing rights...",
"PE.Controllers.LeftMenu.textNoTextFound": "The data you have been searching for could not be found. Please adjust your search options.",
@ -140,6 +141,7 @@
"PE.Controllers.Main.loadThemeTextText": "Loading theme...",
"PE.Controllers.Main.loadThemeTitleText": "Loading Theme",
"PE.Controllers.Main.notcriticalErrorTitle": "Warning",
"PE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"PE.Controllers.Main.openTextText": "Opening presentation...",
"PE.Controllers.Main.openTitleText": "Opening Presentation",
"PE.Controllers.Main.printTextText": "Printing presentation...",
@ -147,6 +149,7 @@
"PE.Controllers.Main.reloadButtonText": "Reload Page",
"PE.Controllers.Main.requestEditFailedMessageText": "Someone is editing this presentation right now. Please try again later.",
"PE.Controllers.Main.requestEditFailedTitleText": "Access denied",
"PE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"PE.Controllers.Main.savePreparingText": "Preparing to save",
"PE.Controllers.Main.savePreparingTitle": "Preparing to save. Please wait...",
"PE.Controllers.Main.saveTextText": "Saving presentation...",
@ -163,6 +166,7 @@
"PE.Controllers.Main.textShape": "Shape",
"PE.Controllers.Main.textStrict": "Strict mode",
"PE.Controllers.Main.textTryUndoRedo": "The Undo/Redo functions are disabled for the Fast co-editing mode.<br>Click the 'Strict mode' button to switch to the Strict co-editing mode to edit the file without other users interference and send your changes only after you save them. You can switch between the co-editing modes using the editor Advanced settings.",
"PE.Controllers.Main.titleLicenseExp": "License expired",
"PE.Controllers.Main.txtArt": "Your text here",
"PE.Controllers.Main.txtBasicShapes": "Basic Shapes",
"PE.Controllers.Main.txtButtons": "Buttons",
@ -224,10 +228,9 @@
"PE.Controllers.Main.uploadImageTitleText": "Uploading Image",
"PE.Controllers.Main.warnBrowserIE9": "The application has low capabilities on IE9. Use IE10 or higher",
"PE.Controllers.Main.warnBrowserZoom": "Your browser current zoom setting is not fully supported. Please reset to the default zoom by pressing Ctrl+0.",
"PE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"PE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"PE.Controllers.Main.warnProcessRightsChange": "You have been denied the right to edit the file.",
"PE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"PE.Controllers.Main.titleLicenseExp": "License expired",
"PE.Controllers.Statusbar.zoomText": "Zoom {0}%",
"PE.Controllers.Toolbar.confirmAddFontName": "The font you are going to save is not available on the current device.<br>The text style will be displayed using one of the system fonts, the saved font will be used when it is available.<br>Do you want to continue?",
"PE.Controllers.Toolbar.textEmptyImgUrl": "You need to specify image URL.",
@ -242,7 +245,7 @@
"PE.Views.ChartSettings.textKeepRatio": "Constant Proportions",
"PE.Views.ChartSettings.textLine": "Line Chart",
"PE.Views.ChartSettings.textPie": "Pie Chart",
"PE.Views.ChartSettings.textPoint": "Point Chart",
"PE.Views.ChartSettings.textPoint": "XY (Scatter) Chart",
"PE.Views.ChartSettings.textSize": "Size",
"PE.Views.ChartSettings.textStock": "Stock Chart",
"PE.Views.ChartSettings.textStyle": "Style",
@ -381,8 +384,8 @@
"PE.Views.FileMenuPanels.Settings.textMinute": "Every Minute",
"PE.Views.FileMenuPanels.Settings.txtAll": "View All",
"PE.Views.FileMenuPanels.Settings.txtCm": "Centimeter",
"PE.Views.FileMenuPanels.Settings.txtFitSlide": "Fit Slide",
"PE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit Width",
"PE.Views.FileMenuPanels.Settings.txtFitSlide": "Fit to Slide",
"PE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit to Width",
"PE.Views.FileMenuPanels.Settings.txtInch": "Inch",
"PE.Views.FileMenuPanels.Settings.txtInput": "Alternate Input",
"PE.Views.FileMenuPanels.Settings.txtLast": "View Last",
@ -651,7 +654,7 @@
"PE.Views.Statusbar.pageIndexText": "Slide {0} of {1}",
"PE.Views.Statusbar.tipAccessRights": "Manage document access rights",
"PE.Views.Statusbar.tipFitPage": "Fit Slide",
"PE.Views.Statusbar.tipFitWidth": "Fit Width",
"PE.Views.Statusbar.tipFitWidth": "Fit to Width",
"PE.Views.Statusbar.tipMoreUsers": "and %1 users.",
"PE.Views.Statusbar.tipPreview": "Start Slideshow",
"PE.Views.Statusbar.tipShowUsers": "To see all users click the icon below.",
@ -780,7 +783,7 @@
"PE.Views.Toolbar.textColumn": "Column Chart",
"PE.Views.Toolbar.textCompactView": "View Compact Toolbar",
"PE.Views.Toolbar.textFitPage": "Fit Slide",
"PE.Views.Toolbar.textFitWidth": "Fit Width",
"PE.Views.Toolbar.textFitWidth": "Fit to Width",
"PE.Views.Toolbar.textHideLines": "Hide Rulers",
"PE.Views.Toolbar.textHideStatusBar": "Hide Status Bar",
"PE.Views.Toolbar.textHideTitleBar": "Hide Title Bar",
@ -791,7 +794,7 @@
"PE.Views.Toolbar.textNewColor": "Custom Color",
"PE.Views.Toolbar.textOK": "OK",
"PE.Views.Toolbar.textPie": "Pie Chart",
"PE.Views.Toolbar.textPoint": "Point Chart",
"PE.Views.Toolbar.textPoint": "XY (Scatter) Chart",
"PE.Views.Toolbar.textShapeAlignBottom": "Align Bottom",
"PE.Views.Toolbar.textShapeAlignCenter": "Align Center",
"PE.Views.Toolbar.textShapeAlignLeft": "Align Left",

View file

@ -28,6 +28,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Reemplazar todo",
"Common.UI.SynchronizeTip.textDontShow": "No volver a mostrar este mensaje",
"Common.UI.SynchronizeTip.textSynchronize": "El documento ha sido cambiado por otro usuario.<br/>Por favor haga clic para guardar sus cambios y recargue las actualizaciones.",
"Common.UI.ThemeColorPalette.textStandartColors": "Colores estándar",
"Common.UI.ThemeColorPalette.textThemeColors": "Colores de tema",
"Common.UI.Window.cancelButtonText": "Cancelar",
"Common.UI.Window.closeButtonText": "Cerrar",
"Common.UI.Window.noButtonText": "No",
@ -91,12 +93,16 @@
"Common.Views.InsertTableDialog.txtMinText": "El valor mínimo para este campo es {0}.",
"Common.Views.InsertTableDialog.txtRows": "Número de filas",
"Common.Views.InsertTableDialog.txtTitle": "Tamaño de tabla",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"PE.Controllers.LeftMenu.newDocumentTitle": "Presentación sin nombre",
"PE.Controllers.LeftMenu.requestEditRightsText": "Solicitando derechos de edición...",
"PE.Controllers.LeftMenu.textNoTextFound": "No se puede encontrar los datos que usted busca. Por favor, ajuste los parámetros de búsqueda.",
"PE.Controllers.Main.applyChangesTextText": "Cargando datos...",
"PE.Controllers.Main.applyChangesTitleText": "Cargando datos",
"PE.Controllers.Main.convertationErrorText": "Conversión fallida.",
"PE.Controllers.Main.convertationErrorText": "Fallo de conversión.",
"PE.Controllers.Main.convertationTimeoutText": "Tiempo de conversión está superado.",
"PE.Controllers.Main.criticalErrorExtText": "Pulse \"OK\" para regresar a la lista de documentos.",
"PE.Controllers.Main.criticalErrorTitle": "Error",
@ -117,6 +123,7 @@
"PE.Controllers.Main.errorUpdateVersion": "Se ha cambiado la versión del archivo. La página será actualizada.",
"PE.Controllers.Main.errorUserDrop": "No se puede acceder al archivo ahora.",
"PE.Controllers.Main.errorUsersExceed": "El número de usuarios permitido según su plan de precios fue excedido",
"PE.Controllers.Main.errorViewerDisconnect": "Connection is lost. You can still view the document,<br>but will not be able to download until the connection is restored.",
"PE.Controllers.Main.leavePageText": "Hay cambios no guardados en esta presentación. Pulse \"Permanecer en esta página\", después \"Guardar\" para guardadarlos. Pulse \"Abandonar esta página\" para descartar todos los cambios no guardados.",
"PE.Controllers.Main.loadFontsTextText": "Cargando datos...",
"PE.Controllers.Main.loadFontsTitleText": "Cargando datos",
@ -131,6 +138,7 @@
"PE.Controllers.Main.loadThemeTextText": "Cargando tema...",
"PE.Controllers.Main.loadThemeTitleText": "Cargando tema",
"PE.Controllers.Main.notcriticalErrorTitle": "Aviso",
"PE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"PE.Controllers.Main.openTextText": "Abriendo presentación...",
"PE.Controllers.Main.openTitleText": "Abriendo presentación",
"PE.Controllers.Main.printTextText": "Imprimiendo presentación...",
@ -138,6 +146,7 @@
"PE.Controllers.Main.reloadButtonText": "Decargar página",
"PE.Controllers.Main.requestEditFailedMessageText": "Alguien está editando esta presentación ahora. Por favor inténtelo de nuevo más tarde.",
"PE.Controllers.Main.requestEditFailedTitleText": "Acceso negado",
"PE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"PE.Controllers.Main.savePreparingText": "Preparando para guardar",
"PE.Controllers.Main.savePreparingTitle": "Preparando para guardar. Espere por favor...",
"PE.Controllers.Main.saveTextText": "Guardando presentación...",
@ -154,6 +163,7 @@
"PE.Controllers.Main.textShape": "Forma",
"PE.Controllers.Main.textStrict": "Modo estricto",
"PE.Controllers.Main.textTryUndoRedo": "Las funciones Anular/Rehacer se desactivan para el modo co-edición rápido.<br>Haga Clic en el botón \"modo estricto\" para cambiar al modo de co-edición estricta para editar el archivo sin la interferencia de otros usuarios y enviar sus cambios sólo después de guardarlos. Se puede cambiar entre los modos de co-edición usando los ajustes avanzados de edición.",
"PE.Controllers.Main.titleLicenseExp": "License expired",
"PE.Controllers.Main.txtArt": "Su texto aquí",
"PE.Controllers.Main.txtBasicShapes": "Formas básicas",
"PE.Controllers.Main.txtButtons": "Botones",
@ -215,6 +225,7 @@
"PE.Controllers.Main.uploadImageTitleText": "Subiendo imagen",
"PE.Controllers.Main.warnBrowserIE9": "Este aplicación tiene baja capacidad en IE9. Utilice IE10 o superior",
"PE.Controllers.Main.warnBrowserZoom": "La configuración actual de zoom de su navegador no está soportada por completo. Por favor restablezca zoom predeterminado pulsando Ctrl+0.",
"PE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"PE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"PE.Controllers.Main.warnProcessRightsChange": "El derecho de edición del archivo es denegado.",
"PE.Controllers.Statusbar.zoomText": "Zoom {0}%",
@ -371,6 +382,7 @@
"PE.Views.FileMenuPanels.Settings.txtAll": "Ver todo",
"PE.Views.FileMenuPanels.Settings.txtCm": "Centímetro",
"PE.Views.FileMenuPanels.Settings.txtFitSlide": "Ajustar diapositiva",
"PE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit to Width",
"PE.Views.FileMenuPanels.Settings.txtInch": "Pulgada",
"PE.Views.FileMenuPanels.Settings.txtInput": "Entrada alternativa",
"PE.Views.FileMenuPanels.Settings.txtLast": "Ver últimos",
@ -397,6 +409,8 @@
"PE.Views.HyperlinkSettingsDialog.txtPrev": "Diapositiva anterior",
"PE.Views.HyperlinkSettingsDialog.txtSlide": "Diapositiva",
"PE.Views.ImageSettings.textAdvanced": "Mostrar ajustes avanzados",
"PE.Views.ImageSettings.textEdit": "Edit",
"PE.Views.ImageSettings.textEditObject": "Edit Object",
"PE.Views.ImageSettings.textFromFile": "De archivo",
"PE.Views.ImageSettings.textFromUrl": "De URL",
"PE.Views.ImageSettings.textHeight": "Altura",
@ -417,6 +431,7 @@
"PE.Views.LeftMenu.tipChat": "Chateo",
"PE.Views.LeftMenu.tipComments": "Comentarios",
"PE.Views.LeftMenu.tipFile": "Archivo",
"PE.Views.LeftMenu.tipPlugins": "Plugins",
"PE.Views.LeftMenu.tipSearch": "Buscar",
"PE.Views.LeftMenu.tipSlides": "Diapositivas",
"PE.Views.LeftMenu.tipSupport": "Feedback y Soporte",
@ -474,6 +489,7 @@
"PE.Views.ShapeSettings.strSize": "Tamaño",
"PE.Views.ShapeSettings.strStroke": "Trazo",
"PE.Views.ShapeSettings.strTransparency": "Opacidad ",
"PE.Views.ShapeSettings.strType": "Type",
"PE.Views.ShapeSettings.textAdvanced": "Mostrar ajustes avanzados",
"PE.Views.ShapeSettings.textBorderSizeErr": "El valor numérico es incorrecto.<br>Por favor, introduzca un valor de 0 a 1584 puntos.",
"PE.Views.ShapeSettings.textColor": "Color de relleno",
@ -490,11 +506,9 @@
"PE.Views.ShapeSettings.textPatternFill": "Patrón",
"PE.Views.ShapeSettings.textRadial": "Radial",
"PE.Views.ShapeSettings.textSelectTexture": "Seleccionar",
"PE.Views.ShapeSettings.textStandartColors": "Colores estándar",
"PE.Views.ShapeSettings.textStretch": "Estirar",
"PE.Views.ShapeSettings.textStyle": "Estilo",
"PE.Views.ShapeSettings.textTexture": "De textura",
"PE.Views.ShapeSettings.textThemeColors": "Colores de tema",
"PE.Views.ShapeSettings.textTile": "Mosaico",
"PE.Views.ShapeSettings.txtBrownPaper": "Papel marrón",
"PE.Views.ShapeSettings.txtCanvas": "Lienzo",
@ -580,11 +594,9 @@
"PE.Views.SlideSettings.textSelectTexture": "Seleccionar",
"PE.Views.SlideSettings.textSmoothly": "Suavemente",
"PE.Views.SlideSettings.textSplit": "Dividir",
"PE.Views.SlideSettings.textStandartColors": "Colores estándar",
"PE.Views.SlideSettings.textStretch": "Estirar",
"PE.Views.SlideSettings.textStyle": "Estilo",
"PE.Views.SlideSettings.textTexture": "De textura",
"PE.Views.SlideSettings.textThemeColors": "Colores de tema",
"PE.Views.SlideSettings.textTile": "Mosaico",
"PE.Views.SlideSettings.textTop": "Superior",
"PE.Views.SlideSettings.textTopLeft": "Superior izquierdo",
@ -609,9 +621,16 @@
"PE.Views.SlideSettings.txtLeather": "Piel",
"PE.Views.SlideSettings.txtPapyrus": "Papiro",
"PE.Views.SlideSettings.txtWood": "Madera",
"PE.Views.SlideshowSettings.cancelButtonText": "Cancel",
"PE.Views.SlideshowSettings.okButtonText": "Ok",
"PE.Views.SlideshowSettings.textLoop": "Loop continuously until 'Esc' is pressed",
"PE.Views.SlideshowSettings.textTitle": "Show Settings",
"PE.Views.SlideSizeSettings.cancelButtonText": "Cancelar",
"PE.Views.SlideSizeSettings.okButtonText": "Aceptar",
"PE.Views.SlideSizeSettings.strLandscape": "Landscape",
"PE.Views.SlideSizeSettings.strPortrait": "Portrait",
"PE.Views.SlideSizeSettings.textHeight": "Altura",
"PE.Views.SlideSizeSettings.textSlideOrientation": "Slide Orientation",
"PE.Views.SlideSizeSettings.textSlideSize": "Tamaño de diapositiva",
"PE.Views.SlideSizeSettings.textTitle": "Ajustes de tamaño de diapositiva",
"PE.Views.SlideSizeSettings.textWidth": "Ancho",
@ -671,9 +690,7 @@
"PE.Views.TableSettings.textNewColor": "Color personalizado",
"PE.Views.TableSettings.textRows": "Filas",
"PE.Views.TableSettings.textSelectBorders": "Seleccione bordes que usted desea cambiar aplicando estilo seleccionado",
"PE.Views.TableSettings.textStandartColors": "Colores estándar",
"PE.Views.TableSettings.textTemplate": "Seleccionar de plantilla",
"PE.Views.TableSettings.textThemeColors": "Colores de tema",
"PE.Views.TableSettings.textTotal": "Total",
"PE.Views.TableSettings.tipAll": "Fijar borde exterior y todas líneas interiores ",
"PE.Views.TableSettings.tipBottom": "Fijar sólo borde exterior inferior",
@ -705,6 +722,7 @@
"PE.Views.TextArtSettings.strSize": "Tamaño",
"PE.Views.TextArtSettings.strStroke": "Trazo",
"PE.Views.TextArtSettings.strTransparency": "Opacidad ",
"PE.Views.TextArtSettings.strType": "Type",
"PE.Views.TextArtSettings.textBorderSizeErr": "El valor numérico es incorrecto.<br>Por favor, introduzca un valor de 0 a 1584 puntos.",
"PE.Views.TextArtSettings.textColor": "Color de relleno",
"PE.Views.TextArtSettings.textDirection": "Dirección ",
@ -720,12 +738,10 @@
"PE.Views.TextArtSettings.textPatternFill": "Patrón",
"PE.Views.TextArtSettings.textRadial": "Radial",
"PE.Views.TextArtSettings.textSelectTexture": "Seleccionar",
"PE.Views.TextArtSettings.textStandartColors": "Colores estándar",
"PE.Views.TextArtSettings.textStretch": "Estirar",
"PE.Views.TextArtSettings.textStyle": "Estilo",
"PE.Views.TextArtSettings.textTemplate": "Plantilla",
"PE.Views.TextArtSettings.textTexture": "De textura",
"PE.Views.TextArtSettings.textThemeColors": "Colores de tema",
"PE.Views.TextArtSettings.textTile": "Mosaico",
"PE.Views.TextArtSettings.textTransform": "Transformar",
"PE.Views.TextArtSettings.txtBrownPaper": "Papel marrón",
@ -782,12 +798,13 @@
"PE.Views.Toolbar.textShapeAlignMiddle": "Alinear al medio",
"PE.Views.Toolbar.textShapeAlignRight": "Alinear a la derecha",
"PE.Views.Toolbar.textShapeAlignTop": "Alinear en la parte superior",
"PE.Views.Toolbar.textStandartColors": "Colores estándar",
"PE.Views.Toolbar.textShowBegin": "Show from Beginning",
"PE.Views.Toolbar.textShowCurrent": "Show from Current slide",
"PE.Views.Toolbar.textShowSettings": "Show Settings",
"PE.Views.Toolbar.textStock": "De cotizaciones",
"PE.Views.Toolbar.textStrikeout": "Tachado",
"PE.Views.Toolbar.textSubscript": "Subíndice",
"PE.Views.Toolbar.textSuperscript": "Sobreíndice",
"PE.Views.Toolbar.textThemeColors": "Colores de tema",
"PE.Views.Toolbar.textTitleError": "Error",
"PE.Views.Toolbar.textUnderline": "Subrayar",
"PE.Views.Toolbar.textZoom": "Zoom",

View file

@ -28,6 +28,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Remplacer tout",
"Common.UI.SynchronizeTip.textDontShow": "N'afficher plus ce message",
"Common.UI.SynchronizeTip.textSynchronize": "Le document a été modifié par un autre utilisateur.<br/>Cliquez pour enregistrer vos modifications et recharger les mises à jour.",
"Common.UI.ThemeColorPalette.textStandartColors": "Couleurs standard",
"Common.UI.ThemeColorPalette.textThemeColors": "Couleurs de thème",
"Common.UI.Window.cancelButtonText": "Annuler",
"Common.UI.Window.closeButtonText": "Fermer",
"Common.UI.Window.noButtonText": "Non",
@ -91,6 +93,10 @@
"Common.Views.InsertTableDialog.txtMinText": "La valeur minimale pour ce champ est {0}.",
"Common.Views.InsertTableDialog.txtRows": "Nombre de lignes",
"Common.Views.InsertTableDialog.txtTitle": "Taille du tableau",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Chargement",
"Common.Views.Plugins.textStart": "Lancer",
"PE.Controllers.LeftMenu.newDocumentTitle": "Présentation sans nom",
"PE.Controllers.LeftMenu.requestEditRightsText": "Demande des droits de modification...",
"PE.Controllers.LeftMenu.textNoTextFound": "Votre recherche n'a donné aucun résultat.S'il vous plaît, modifiez vos critères de recherche.",
@ -117,6 +123,7 @@
"PE.Controllers.Main.errorUpdateVersion": "La version du fichier a été changée. La page sera rechargée.",
"PE.Controllers.Main.errorUserDrop": "Impossible d'accéder au fichier",
"PE.Controllers.Main.errorUsersExceed": "Le nombre d'utilisateurs autorisés par le plan tarifaire a été dépassé",
"PE.Controllers.Main.errorViewerDisconnect": "Connection is lost. You can still view the document,<br>but will not be able to download until the connection is restored.",
"PE.Controllers.Main.leavePageText": "Vous avez des modifications non enregistrées dans cette présentation. Cliquez sur \"Rester sur cette page\", ensuite sur \"Enregistrer\" pour enregistrer les modifications. Cliquez sur \"Quitter cette page\" pour annuler toutes les modifications non enregistrées.",
"PE.Controllers.Main.loadFontsTextText": "Chargement des données...",
"PE.Controllers.Main.loadFontsTitleText": "Chargement des données",
@ -131,6 +138,7 @@
"PE.Controllers.Main.loadThemeTextText": "Chargement du thème en cours...",
"PE.Controllers.Main.loadThemeTitleText": "Chargement du thème",
"PE.Controllers.Main.notcriticalErrorTitle": "Avertissement",
"PE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"PE.Controllers.Main.openTextText": "Ouverture de la présentation...",
"PE.Controllers.Main.openTitleText": "Ouverture de la présentation",
"PE.Controllers.Main.printTextText": "Impression de la présentation...",
@ -138,6 +146,7 @@
"PE.Controllers.Main.reloadButtonText": "Recharger la page",
"PE.Controllers.Main.requestEditFailedMessageText": "Quelqu'un est en train de modifier cette présentation. Veuillez réessayer plus tard.",
"PE.Controllers.Main.requestEditFailedTitleText": "Accès refusé",
"PE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"PE.Controllers.Main.savePreparingText": "Préparation à l'enregistrement ",
"PE.Controllers.Main.savePreparingTitle": "Préparation à l'enregistrement en cours. Veuillez patienter...",
"PE.Controllers.Main.saveTextText": "Enregistrement de la présentation...",
@ -146,14 +155,15 @@
"PE.Controllers.Main.splitMaxColsErrorText": "Le nombre de colonnes doivent être inférieure à %1.",
"PE.Controllers.Main.splitMaxRowsErrorText": "Le nombre de lignes doit être inférieure à %1.",
"PE.Controllers.Main.textAnonymous": "Anonyme",
"PE.Controllers.Main.textBuyNow": "Visit website",
"PE.Controllers.Main.textBuyNow": "Visiter le site web",
"PE.Controllers.Main.textCloseTip": "Cliquez pour fermer la conseil",
"PE.Controllers.Main.textContactUs": "Contact sales",
"PE.Controllers.Main.textContactUs": "Contacter l'équipe de ventes",
"PE.Controllers.Main.textLoadingDocument": "Chargement de présentation",
"PE.Controllers.Main.textNoLicenseTitle": "ONLYOFFICE open source version",
"PE.Controllers.Main.textNoLicenseTitle": "La version open source de ONLYOFFICE",
"PE.Controllers.Main.textShape": "Forme",
"PE.Controllers.Main.textStrict": "Mode strict",
"PE.Controllers.Main.textTryUndoRedo": "Les fonctions annuler/rétablir sont désactivées pour le mode de co-édition rapide.<br>Cliquez sur le bouton \"Mode strict\" pour passer au mode de la co-édition stricte pour modifier le fichier sans interférence d'autres utilisateurs et envoyer vos modifications seulement après que vous les enregistrez. Vous pouvez basculer entre les modes de co-édition à l'aide de paramètres avancés d'éditeur.",
"PE.Controllers.Main.titleLicenseExp": "License expired",
"PE.Controllers.Main.txtArt": "Your text here",
"PE.Controllers.Main.txtBasicShapes": "Formes de base",
"PE.Controllers.Main.txtButtons": "Boutons",
@ -215,6 +225,7 @@
"PE.Controllers.Main.uploadImageTitleText": "Chargement d'une image",
"PE.Controllers.Main.warnBrowserIE9": "L'application est peu compatible avec IE9. Utilisez IE10 ou version plus récente",
"PE.Controllers.Main.warnBrowserZoom": "Le paramètre actuel de zoom de votre navigateur n'est pas accepté. Veuillez rétablir le niveau de zoom par défaut en appuyant sur Ctrl+0.",
"PE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"PE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"PE.Controllers.Main.warnProcessRightsChange": "Le droit d'édition du fichier vous a été refusé.",
"PE.Controllers.Statusbar.zoomText": "Zoom {0}%",
@ -371,6 +382,7 @@
"PE.Views.FileMenuPanels.Settings.txtAll": "Tout",
"PE.Views.FileMenuPanels.Settings.txtCm": "Centimètre",
"PE.Views.FileMenuPanels.Settings.txtFitSlide": "Ajuster la diapositive",
"PE.Views.FileMenuPanels.Settings.txtFitWidth": "Fit to Width",
"PE.Views.FileMenuPanels.Settings.txtInch": "Pouce",
"PE.Views.FileMenuPanels.Settings.txtInput": "Entrée alternative",
"PE.Views.FileMenuPanels.Settings.txtLast": "Derniers",
@ -397,6 +409,8 @@
"PE.Views.HyperlinkSettingsDialog.txtPrev": "Diapositive précédente",
"PE.Views.HyperlinkSettingsDialog.txtSlide": "Diapositive",
"PE.Views.ImageSettings.textAdvanced": "Afficher les paramètres avancés",
"PE.Views.ImageSettings.textEdit": "Modifier",
"PE.Views.ImageSettings.textEditObject": "Modifier l'objet",
"PE.Views.ImageSettings.textFromFile": "D'un fichier",
"PE.Views.ImageSettings.textFromUrl": "D'une URL",
"PE.Views.ImageSettings.textHeight": "Hauteur",
@ -417,6 +431,7 @@
"PE.Views.LeftMenu.tipChat": "Chat",
"PE.Views.LeftMenu.tipComments": "Commentaires",
"PE.Views.LeftMenu.tipFile": "Fichier",
"PE.Views.LeftMenu.tipPlugins": "Plugins",
"PE.Views.LeftMenu.tipSearch": "Recherche",
"PE.Views.LeftMenu.tipSlides": "Diapositives",
"PE.Views.LeftMenu.tipSupport": "Commentaires & assistance",
@ -474,6 +489,7 @@
"PE.Views.ShapeSettings.strSize": "Taille",
"PE.Views.ShapeSettings.strStroke": "Trait",
"PE.Views.ShapeSettings.strTransparency": "Opacité",
"PE.Views.ShapeSettings.strType": "Type",
"PE.Views.ShapeSettings.textAdvanced": "Afficher les paramètres avancés",
"PE.Views.ShapeSettings.textBorderSizeErr": "La valeur saisie est incorrecte. <br>Entrez une valeur de 0 à 1584 points.",
"PE.Views.ShapeSettings.textColor": "Couleur de remplissage",
@ -490,11 +506,9 @@
"PE.Views.ShapeSettings.textPatternFill": "Modèle",
"PE.Views.ShapeSettings.textRadial": "Radial",
"PE.Views.ShapeSettings.textSelectTexture": "Sélectionner",
"PE.Views.ShapeSettings.textStandartColors": "Couleurs standard",
"PE.Views.ShapeSettings.textStretch": "Étirement",
"PE.Views.ShapeSettings.textStyle": "Style",
"PE.Views.ShapeSettings.textTexture": "D'une texture",
"PE.Views.ShapeSettings.textThemeColors": "Couleurs de thème",
"PE.Views.ShapeSettings.textTile": "Mosaïque",
"PE.Views.ShapeSettings.txtBrownPaper": "Papier brun",
"PE.Views.ShapeSettings.txtCanvas": "Toile",
@ -580,11 +594,9 @@
"PE.Views.SlideSettings.textSelectTexture": "Sélectionner",
"PE.Views.SlideSettings.textSmoothly": "Transition douce",
"PE.Views.SlideSettings.textSplit": "Diviser",
"PE.Views.SlideSettings.textStandartColors": "Couleurs standard",
"PE.Views.SlideSettings.textStretch": "Étirement",
"PE.Views.SlideSettings.textStyle": "Style",
"PE.Views.SlideSettings.textTexture": "D'une texture",
"PE.Views.SlideSettings.textThemeColors": "Couleurs de thème",
"PE.Views.SlideSettings.textTile": "Mosaïque",
"PE.Views.SlideSettings.textTop": "En haut",
"PE.Views.SlideSettings.textTopLeft": "En haut à gauche",
@ -609,9 +621,16 @@
"PE.Views.SlideSettings.txtLeather": "Cuir",
"PE.Views.SlideSettings.txtPapyrus": "Papyrus",
"PE.Views.SlideSettings.txtWood": "Bois",
"PE.Views.SlideshowSettings.cancelButtonText": "Annuler",
"PE.Views.SlideshowSettings.okButtonText": "OK",
"PE.Views.SlideshowSettings.textLoop": "Boucle continue jusqu'à ce que le bouton «Esc» soit pressé",
"PE.Views.SlideshowSettings.textTitle": "Afficher les paramètres",
"PE.Views.SlideSizeSettings.cancelButtonText": "Annuler",
"PE.Views.SlideSizeSettings.okButtonText": "Ok",
"PE.Views.SlideSizeSettings.strLandscape": "Paysage",
"PE.Views.SlideSizeSettings.strPortrait": "Portrait",
"PE.Views.SlideSizeSettings.textHeight": "Hauteur",
"PE.Views.SlideSizeSettings.textSlideOrientation": "Orientation des diapositives",
"PE.Views.SlideSizeSettings.textSlideSize": "Taille de la diapositive",
"PE.Views.SlideSizeSettings.textTitle": "Paramètres de taille",
"PE.Views.SlideSizeSettings.textWidth": "Largeur",
@ -671,9 +690,7 @@
"PE.Views.TableSettings.textNewColor": "Couleur personnalisée",
"PE.Views.TableSettings.textRows": "Lignes",
"PE.Views.TableSettings.textSelectBorders": "Sélectionnez les bordures à modifier en appliquant le style choisi ci-dessus",
"PE.Views.TableSettings.textStandartColors": "Couleurs standard",
"PE.Views.TableSettings.textTemplate": "Sélectionner à partir d'un modèle",
"PE.Views.TableSettings.textThemeColors": "Couleurs de thème",
"PE.Views.TableSettings.textTotal": "Total",
"PE.Views.TableSettings.tipAll": "Bordure extérieure et la totalité des lignes intérieures",
"PE.Views.TableSettings.tipBottom": "Seulement bordure extérieure inférieure",
@ -705,6 +722,7 @@
"PE.Views.TextArtSettings.strSize": "Size",
"PE.Views.TextArtSettings.strStroke": "Stroke",
"PE.Views.TextArtSettings.strTransparency": "Opacité",
"PE.Views.TextArtSettings.strType": "Type",
"PE.Views.TextArtSettings.textBorderSizeErr": "The entered value is incorrect.<br>Please enter a value between 0 pt and 1584 pt.",
"PE.Views.TextArtSettings.textColor": "Couleur de remplissage",
"PE.Views.TextArtSettings.textDirection": "Direction",
@ -715,17 +733,15 @@
"PE.Views.TextArtSettings.textGradientFill": "Remplissage en dégradé",
"PE.Views.TextArtSettings.textImageTexture": "Image ou texture",
"PE.Views.TextArtSettings.textLinear": "Linéaire",
"PE.Views.TextArtSettings.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"PE.Views.TextArtSettings.textNewColor": "Couleur Personnalisée",
"PE.Views.TextArtSettings.textNoFill": "Pas de remplissage",
"PE.Views.TextArtSettings.textPatternFill": "Modèle",
"PE.Views.TextArtSettings.textRadial": "Radial",
"PE.Views.TextArtSettings.textSelectTexture": "Select",
"PE.Views.TextArtSettings.textStandartColors": "Standard Colors",
"PE.Views.TextArtSettings.textStretch": "Stretch",
"PE.Views.TextArtSettings.textStyle": "Style",
"PE.Views.TextArtSettings.textTemplate": "Template",
"PE.Views.TextArtSettings.textTexture": "From Texture",
"PE.Views.TextArtSettings.textThemeColors": "Theme Colors",
"PE.Views.TextArtSettings.textTile": "Tile",
"PE.Views.TextArtSettings.textTransform": "Transform",
"PE.Views.TextArtSettings.txtBrownPaper": "Papier brun",
@ -782,12 +798,13 @@
"PE.Views.Toolbar.textShapeAlignMiddle": "Aligner au milieu",
"PE.Views.Toolbar.textShapeAlignRight": "Aligner à droite",
"PE.Views.Toolbar.textShapeAlignTop": "Aligner en haut",
"PE.Views.Toolbar.textStandartColors": "Couleurs standard",
"PE.Views.Toolbar.textShowBegin": "Afficher dès le début",
"PE.Views.Toolbar.textShowCurrent": "Afficher de la diapositive actuelle",
"PE.Views.Toolbar.textShowSettings": "Afficher les paramètres",
"PE.Views.Toolbar.textStock": "Boursier",
"PE.Views.Toolbar.textStrikeout": "Barré",
"PE.Views.Toolbar.textSubscript": "Indice",
"PE.Views.Toolbar.textSuperscript": "Exposant",
"PE.Views.Toolbar.textThemeColors": "Couleurs de thème",
"PE.Views.Toolbar.textTitleError": "Erreur",
"PE.Views.Toolbar.textUnderline": "Souligné",
"PE.Views.Toolbar.textZoom": "Zoom",

View file

@ -79,6 +79,24 @@ Ext.define('PE.controller.toolbar.View', {
overlayContainer.element.on('touchend', this.onTouchEndDocument, this);
}
if (Ext.os.is.iOS) {
Ext.each(Ext.ComponentQuery.query('button'), function(button) {
button.element.dom.ontouchstart = Ext.emptyFn();
button.element.dom.ontouchmove = Ext.emptyFn();
button.element.dom.ontouchend = Ext.emptyFn();
}, this);
Ext.each(Ext.ComponentQuery.query('toolbar'), function(toolbar) {
var preventFn = function(e){
e.preventDefault();
};
toolbar.element.dom.ontouchstart = preventFn;
toolbar.element.dom.ontouchmove = preventFn;
toolbar.element.dom.ontouchend = preventFn;
}, this);
}
Common.Gateway.on('init', Ext.bind(this.loadConfig, this));
},

View file

@ -760,9 +760,10 @@ define([
this.appOptions.canChat = this.appOptions.canLicense && !this.appOptions.isOffline && !((typeof (this.editorConfig.customization) == 'object') && this.editorConfig.customization.chat===false);
this.appOptions.canBranding = params.asc_getCanBranding() && (typeof this.editorConfig.customization == 'object');
if (this.appOptions.canBranding) {
if (this.appOptions.canBranding)
this.headerView.setBranding(this.editorConfig.customization);
}
params.asc_getTrial() && this.headerView.setDeveloperMode(true);
}
this.appOptions.canRequestEditRights = this.editorConfig.canRequestEditRights;

View file

@ -25,6 +25,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Alle ersetzen",
"Common.UI.SynchronizeTip.textDontShow": "Diese Meldung nicht mehr anzeigen",
"Common.UI.SynchronizeTip.textSynchronize": "Das Dokument wurde von einem anderen Benutzer geändert.<br/>Bitte klicken hier, um Ihre Änderungen zu speichern und die Aktualisierungen neu zu laden.",
"Common.UI.ThemeColorPalette.textStandartColors": "Standardfarben",
"Common.UI.ThemeColorPalette.textThemeColors": "Designfarben",
"Common.UI.Window.cancelButtonText": "Abbrechen",
"Common.UI.Window.closeButtonText": "Schließen",
"Common.UI.Window.noButtonText": "Nein",
@ -84,7 +86,9 @@
"Common.Views.OpenDialog.txtSpace": "Leerzeichen",
"Common.Views.OpenDialog.txtTab": "Tabulator",
"Common.Views.OpenDialog.txtTitle": "%1-Optionen wählen",
"SSE.Controllers.DocumentHolder.errorInvalidLink": "The link reference does not exist. Please correct the link or delete it.",
"SSE.Controllers.DocumentHolder.guestText": "Gast",
"SSE.Controllers.DocumentHolder.notcriticalErrorTitle": "Warning",
"SSE.Controllers.DocumentHolder.textChangeColumnWidth": "Spaltenbreite {0} Symbole ({1} Pixel)",
"SSE.Controllers.DocumentHolder.textChangeRowHeight": "Zeilenhöhe {0} Punkte ({1} Pixel)",
"SSE.Controllers.DocumentHolder.textCtrlClick": "Drücken Sie die STRG-Taste und klicken Sie auf den Link",
@ -221,6 +225,7 @@
"SSE.Controllers.Main.uploadImageTitleText": "Bild wird hochgeladen",
"SSE.Controllers.Main.warnBrowserIE9": "Die Anwendung hat geringe Fähigkeiten in IE9. Nutzen Sie IE10 oder höher.",
"SSE.Controllers.Main.warnBrowserZoom": "Die aktuelle Zoom-Einstellung Ihres Webbrowsers wird nicht völlig unterstützt. Bitte stellen Sie die Standardeinstellung mithilfe der Tastenkombination STRG+0 wieder her.",
"SSE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"SSE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"SSE.Controllers.Main.warnProcessRightsChange": "Das Recht, die Datei zu bearbeiten, wurde Ihnen verweigert.",
"SSE.Controllers.Print.strAllSheets": "Alle Blätter",
@ -307,6 +312,7 @@
"SSE.Views.ChartSettingsDlg.textBar": "Balken",
"SSE.Views.ChartSettingsDlg.textBetweenTickMarks": "Zwischen den Teilstrichen",
"SSE.Views.ChartSettingsDlg.textBillions": "Milliarden",
"SSE.Views.ChartSettingsDlg.textBottom": "Bottom",
"SSE.Views.ChartSettingsDlg.textCategoryName": "Kategoriename",
"SSE.Views.ChartSettingsDlg.textCenter": "Zentriert",
"SSE.Views.ChartSettingsDlg.textChartElementsLegend": "Diagrammelemente und <br/> Diagrammlegende",
@ -320,6 +326,7 @@
"SSE.Views.ChartSettingsDlg.textDataRows": "in Zeilen",
"SSE.Views.ChartSettingsDlg.textDataSeries": "Datenreihe",
"SSE.Views.ChartSettingsDlg.textDisplayLegend": "Legende anzeigen",
"SSE.Views.ChartSettingsDlg.textFit": "Fit to Width",
"SSE.Views.ChartSettingsDlg.textFixed": "Fixiert",
"SSE.Views.ChartSettingsDlg.textGridLines": "Gitternetzlinien ",
"SSE.Views.ChartSettingsDlg.textHide": "Vergeben",
@ -340,6 +347,7 @@
"SSE.Views.ChartSettingsDlg.textLabelOptions": "Beschriftungsoptionen",
"SSE.Views.ChartSettingsDlg.textLabelPos": "Beschriftungsposition\t",
"SSE.Views.ChartSettingsDlg.textLayout": "Layout",
"SSE.Views.ChartSettingsDlg.textLeft": "Left",
"SSE.Views.ChartSettingsDlg.textLeftOverlay": "Überlagerung links",
"SSE.Views.ChartSettingsDlg.textLegendBottom": "Unten",
"SSE.Views.ChartSettingsDlg.textLegendLeft": "Links",
@ -370,6 +378,7 @@
"SSE.Views.ChartSettingsDlg.textPie": "Kreis",
"SSE.Views.ChartSettingsDlg.textPoint": "Punkt",
"SSE.Views.ChartSettingsDlg.textReverse": "Werte in umgekehrter Reihenfolge",
"SSE.Views.ChartSettingsDlg.textRight": "Right",
"SSE.Views.ChartSettingsDlg.textRightOverlay": "Überlagerung rechts",
"SSE.Views.ChartSettingsDlg.textRotated": "Gedreht",
"SSE.Views.ChartSettingsDlg.textSelectData": "Daten auswählen",
@ -389,6 +398,7 @@
"SSE.Views.ChartSettingsDlg.textThousands": "Tausende",
"SSE.Views.ChartSettingsDlg.textTickOptions": "Parameter der Teilstriche",
"SSE.Views.ChartSettingsDlg.textTitle": "Diagramm - Erweiterte Einstellungen",
"SSE.Views.ChartSettingsDlg.textTop": "Top",
"SSE.Views.ChartSettingsDlg.textTrillions": "Billionen",
"SSE.Views.ChartSettingsDlg.textType": "Typ",
"SSE.Views.ChartSettingsDlg.textTypeData": "Typ und Daten",
@ -454,6 +464,8 @@
"SSE.Views.DocumentHolder.txtAddNamedRange": "Namen definieren\t",
"SSE.Views.DocumentHolder.txtArrange": "Anordnen",
"SSE.Views.DocumentHolder.txtAscending": "Aufsteigend",
"SSE.Views.DocumentHolder.txtAutoColumnWidth": "Auto Fit Column Width",
"SSE.Views.DocumentHolder.txtAutoRowHeight": "Auto Fit Row Height",
"SSE.Views.DocumentHolder.txtClear": "Leeren",
"SSE.Views.DocumentHolder.txtClearAll": "Alle",
"SSE.Views.DocumentHolder.txtClearComments": "Kommentare",
@ -463,6 +475,8 @@
"SSE.Views.DocumentHolder.txtColumn": "Ganze Spalte",
"SSE.Views.DocumentHolder.txtColumnWidth": "Spaltenbreite",
"SSE.Views.DocumentHolder.txtCopy": "Kopieren",
"SSE.Views.DocumentHolder.txtCustomColumnWidth": "Custom Column Width",
"SSE.Views.DocumentHolder.txtCustomRowHeight": "Custom Row Height",
"SSE.Views.DocumentHolder.txtCut": "Ausschneiden",
"SSE.Views.DocumentHolder.txtDelete": "Löschen",
"SSE.Views.DocumentHolder.txtDescending": "Absteigend",
@ -613,6 +627,8 @@
"SSE.Views.HyperlinkSettingsDialog.textTitle": "Hyperlink-Einstellungen",
"SSE.Views.HyperlinkSettingsDialog.txtEmpty": "Dieses Feld ist erforderlich",
"SSE.Views.HyperlinkSettingsDialog.txtNotUrl": "Dieses Feld muss eine URL im Format \"http://www.example.com\" enthalten",
"SSE.Views.ImageSettings.textEdit": "Edit",
"SSE.Views.ImageSettings.textEditObject": "Edit Object",
"SSE.Views.ImageSettings.textFromFile": "Aus Datei",
"SSE.Views.ImageSettings.textFromUrl": "Aus URL",
"SSE.Views.ImageSettings.textHeight": "Höhe",
@ -625,6 +641,7 @@
"SSE.Views.LeftMenu.tipChat": "Chat",
"SSE.Views.LeftMenu.tipComments": "Kommentare",
"SSE.Views.LeftMenu.tipFile": "Datei",
"SSE.Views.LeftMenu.tipPlugins": "Plugins",
"SSE.Views.LeftMenu.tipSearch": "Suchen",
"SSE.Views.LeftMenu.tipSupport": "Feedback und Support",
"SSE.Views.MainSettingsPrint.okButtonText": "Speichern",
@ -773,6 +790,7 @@
"SSE.Views.ShapeSettings.strSize": "Größe",
"SSE.Views.ShapeSettings.strStroke": "Strich",
"SSE.Views.ShapeSettings.strTransparency": "Undurchsichtigkeit",
"SSE.Views.ShapeSettings.strType": "Type",
"SSE.Views.ShapeSettings.textAdvanced": "Erweiterte Einstellungen anzeigen",
"SSE.Views.ShapeSettings.textBorderSizeErr": "Der eingegebene Wert ist falsch.<br>Bitte geben Sie einen Wert zwischen 0 pt und 1584 pt ein.",
"SSE.Views.ShapeSettings.textColor": "Farbfüllung",
@ -790,11 +808,9 @@
"SSE.Views.ShapeSettings.textPatternFill": "Muster",
"SSE.Views.ShapeSettings.textRadial": "Radial",
"SSE.Views.ShapeSettings.textSelectTexture": "Wählen",
"SSE.Views.ShapeSettings.textStandartColors": "Standardfarben",
"SSE.Views.ShapeSettings.textStretch": "Ausdehnung",
"SSE.Views.ShapeSettings.textStyle": "Stil",
"SSE.Views.ShapeSettings.textTexture": "Aus Textur",
"SSE.Views.ShapeSettings.textThemeColors": "Designfarben",
"SSE.Views.ShapeSettings.textTile": "Kachel",
"SSE.Views.ShapeSettings.txtBrownPaper": "Kraftpapier",
"SSE.Views.ShapeSettings.txtCanvas": "Canvas",
@ -851,11 +867,9 @@
"SSE.Views.Statusbar.RenameDialog.labelSheetName": "Blattname",
"SSE.Views.Statusbar.textAverage": "MITTELWERT",
"SSE.Views.Statusbar.textCount": "ANZAHL",
"SSE.Views.Statusbar.textNewColor": "Neue benutzerdefinierte Farbpalette hinzufügen",
"SSE.Views.Statusbar.textNewColor": "Benutzerdefinierte Farbe",
"SSE.Views.Statusbar.textNoColor": "Ohne Farbe",
"SSE.Views.Statusbar.textStandartColors": "Standardfarben",
"SSE.Views.Statusbar.textSum": "SUMME",
"SSE.Views.Statusbar.textThemeColors": "Designfarben",
"SSE.Views.Statusbar.tipAccessRights": "Zugriffsrechte für das Dokument verwalten",
"SSE.Views.Statusbar.tipAddTab": "Arbeitsblatt hinzufügen",
"SSE.Views.Statusbar.tipFirst": "Bis zum ersten Blatt blättern",
@ -917,6 +931,7 @@
"SSE.Views.TextArtSettings.strSize": "Größe",
"SSE.Views.TextArtSettings.strStroke": "Strich",
"SSE.Views.TextArtSettings.strTransparency": "Undurchsichtigkeit",
"SSE.Views.TextArtSettings.strType": "Type",
"SSE.Views.TextArtSettings.textBorderSizeErr": "Der eingegebene Wert ist falsch.<br>Bitte geben Sie einen Wert zwischen 0 pt und 1584 pt ein.",
"SSE.Views.TextArtSettings.textColor": "Farbfüllung",
"SSE.Views.TextArtSettings.textDirection": "Richtung",
@ -927,17 +942,15 @@
"SSE.Views.TextArtSettings.textGradientFill": "Füllung mit Farbverlauf",
"SSE.Views.TextArtSettings.textImageTexture": "Bild oder Textur",
"SSE.Views.TextArtSettings.textLinear": "Linear",
"SSE.Views.TextArtSettings.textNewColor": "Neue benutzerdefinierte Farbpalette hinzufügen",
"SSE.Views.TextArtSettings.textNewColor": "Benutzerdefinierte Farbe",
"SSE.Views.TextArtSettings.textNoFill": "Ohne Füllung",
"SSE.Views.TextArtSettings.textPatternFill": "Muster",
"SSE.Views.TextArtSettings.textRadial": "Radial",
"SSE.Views.TextArtSettings.textSelectTexture": "Wählen",
"SSE.Views.TextArtSettings.textStandartColors": "Standardfarben",
"SSE.Views.TextArtSettings.textStretch": "Ausdehnung",
"SSE.Views.TextArtSettings.textStyle": "Stil",
"SSE.Views.TextArtSettings.textTemplate": "Vorlage",
"SSE.Views.TextArtSettings.textTexture": "Aus Textur",
"SSE.Views.TextArtSettings.textThemeColors": "Designfarben",
"SSE.Views.TextArtSettings.textTile": "Kachel",
"SSE.Views.TextArtSettings.textTransform": "Transformieren\t",
"SSE.Views.TextArtSettings.txtBrownPaper": "Kraftpapier",
@ -989,7 +1002,7 @@
"SSE.Views.Toolbar.textItalic": "Kursiv",
"SSE.Views.Toolbar.textLeftBorders": "Rahmenlinien links",
"SSE.Views.Toolbar.textMiddleBorders": "Innere horizontale Rahmenlinien",
"SSE.Views.Toolbar.textNewColor": "Neue benutzerdefinierte Farbpalette hinzufügen",
"SSE.Views.Toolbar.textNewColor": "Benutzerdefinierte Farbe",
"SSE.Views.Toolbar.textNoBorders": "Keine Rahmen",
"SSE.Views.Toolbar.textOutBorders": "Rahmenlinien außen",
"SSE.Views.Toolbar.textPrint": "Drucken",
@ -997,8 +1010,6 @@
"SSE.Views.Toolbar.textRightBorders": "Rahmenlinien rechts",
"SSE.Views.Toolbar.textRotateDown": "Text nach unten drehen",
"SSE.Views.Toolbar.textRotateUp": "Text nach oben drehen",
"SSE.Views.Toolbar.textStandartColors": "Standardfarben",
"SSE.Views.Toolbar.textThemeColors": "Designfarben",
"SSE.Views.Toolbar.textTopBorders": "Rahmenlinien oben",
"SSE.Views.Toolbar.textUnderline": "Unterstrichen",
"SSE.Views.Toolbar.textZoom": "Zoom",

View file

@ -74,6 +74,7 @@
"Common.Views.DocumentAccessDialog.textTitle": "Sharing Settings",
"Common.Views.Header.openNewTabText": "Open in New Tab",
"Common.Views.Header.textBack": "Go to Documents",
"Common.Views.Header.txtHeaderDeveloper": "DEVELOPER MODE",
"Common.Views.ImageFromUrlDialog.cancelButtonText": "Cancel",
"Common.Views.ImageFromUrlDialog.okButtonText": "OK",
"Common.Views.ImageFromUrlDialog.textUrl": "Paste an image URL:",
@ -83,15 +84,15 @@
"Common.Views.OpenDialog.okButtonText": "OK",
"Common.Views.OpenDialog.txtDelimiter": "Delimiter",
"Common.Views.OpenDialog.txtEncoding": "Encoding ",
"Common.Views.OpenDialog.txtPassword": "Password",
"Common.Views.OpenDialog.txtSpace": "Space",
"Common.Views.OpenDialog.txtTab": "Tab",
"Common.Views.OpenDialog.txtTitle": "Choose %1 options",
"Common.Views.OpenDialog.txtPassword": "Password",
"Common.Views.OpenDialog.txtTitleProtected": "Protected File",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"Common.Views.PluginDlg.textLoading": "Loading",
"SSE.Controllers.DocumentHolder.errorInvalidLink": "The link reference does not exist. Please correct the link or delete it.",
"SSE.Controllers.DocumentHolder.guestText": "Guest",
"SSE.Controllers.DocumentHolder.notcriticalErrorTitle": "Warning",
@ -183,6 +184,7 @@
"SSE.Controllers.Main.loadImageTitleText": "Loading Image",
"SSE.Controllers.Main.loadingDocumentTitleText": "Loading spreadsheet",
"SSE.Controllers.Main.notcriticalErrorTitle": "Warning",
"SSE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"SSE.Controllers.Main.openTextText": "Opening spreadsheet...",
"SSE.Controllers.Main.openTitleText": "Opening Spreadsheet",
"SSE.Controllers.Main.pastInMergeAreaError": "Cannot change part of a merged cell",
@ -191,6 +193,7 @@
"SSE.Controllers.Main.reloadButtonText": "Reload Page",
"SSE.Controllers.Main.requestEditFailedMessageText": "Someone is editing this document right now. Please try again later.",
"SSE.Controllers.Main.requestEditFailedTitleText": "Access denied",
"SSE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"SSE.Controllers.Main.savePreparingText": "Preparing to save",
"SSE.Controllers.Main.savePreparingTitle": "Preparing to save. Please wait...",
"SSE.Controllers.Main.saveTextText": "Saving spreadsheet...",
@ -209,6 +212,7 @@
"SSE.Controllers.Main.textStrict": "Strict mode",
"SSE.Controllers.Main.textTryUndoRedo": "The Undo/Redo functions are disabled for the Fast co-editing mode.<br>Click the 'Strict mode' button to switch to the Strict co-editing mode to edit the file without other users interference and send your changes only after you save them. You can switch between the co-editing modes using the editor Advanced settings.",
"SSE.Controllers.Main.textYes": "Yes",
"SSE.Controllers.Main.titleLicenseExp": "License expired",
"SSE.Controllers.Main.titleRecalcFormulas": "Calculating...",
"SSE.Controllers.Main.txtArt": "Your text here",
"SSE.Controllers.Main.txtBasicShapes": "Basic Shapes",
@ -234,10 +238,9 @@
"SSE.Controllers.Main.uploadImageTitleText": "Uploading Image",
"SSE.Controllers.Main.warnBrowserIE9": "The application has low capabilities on IE9. Use IE10 or higher",
"SSE.Controllers.Main.warnBrowserZoom": "Your browser current zoom setting is not fully supported. Please reset to the default zoom by pressing Ctrl+0.",
"SSE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"SSE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"SSE.Controllers.Main.warnProcessRightsChange": "You have been denied the right to edit the file.",
"SSE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"SSE.Controllers.Main.titleLicenseExp": "License expired",
"SSE.Controllers.Print.strAllSheets": "All Sheets",
"SSE.Controllers.Print.textWarning": "Warning",
"SSE.Controllers.Print.warnCheckMargings": "Margins are incorrect",
@ -305,7 +308,7 @@
"SSE.Views.ChartSettings.textKeepRatio": "Constant Proportions",
"SSE.Views.ChartSettings.textLine": "Line Chart",
"SSE.Views.ChartSettings.textPie": "Pie Chart",
"SSE.Views.ChartSettings.textPoint": "Point Chart",
"SSE.Views.ChartSettings.textPoint": "XY (Scatter) Chart",
"SSE.Views.ChartSettings.textSize": "Size",
"SSE.Views.ChartSettings.textStock": "Stock Chart",
"SSE.Views.ChartSettings.textStyle": "Style",
@ -322,6 +325,7 @@
"SSE.Views.ChartSettingsDlg.textBar": "Bar Chart",
"SSE.Views.ChartSettingsDlg.textBetweenTickMarks": "Between Tick Marks",
"SSE.Views.ChartSettingsDlg.textBillions": "Billions",
"SSE.Views.ChartSettingsDlg.textBottom": "Bottom",
"SSE.Views.ChartSettingsDlg.textCategoryName": "Category Name",
"SSE.Views.ChartSettingsDlg.textCenter": "Center",
"SSE.Views.ChartSettingsDlg.textChartElementsLegend": "Chart Elements &<br/>Chart Legend",
@ -335,6 +339,7 @@
"SSE.Views.ChartSettingsDlg.textDataRows": "in rows",
"SSE.Views.ChartSettingsDlg.textDataSeries": "Data series",
"SSE.Views.ChartSettingsDlg.textDisplayLegend": "Display Legend",
"SSE.Views.ChartSettingsDlg.textFit": "Fit to Width",
"SSE.Views.ChartSettingsDlg.textFixed": "Fixed",
"SSE.Views.ChartSettingsDlg.textGridLines": "Gridlines",
"SSE.Views.ChartSettingsDlg.textHide": "Hide",
@ -355,6 +360,7 @@
"SSE.Views.ChartSettingsDlg.textLabelOptions": "Label Options",
"SSE.Views.ChartSettingsDlg.textLabelPos": "Label Position",
"SSE.Views.ChartSettingsDlg.textLayout": "Layout",
"SSE.Views.ChartSettingsDlg.textLeft": "Left",
"SSE.Views.ChartSettingsDlg.textLeftOverlay": "Left Overlay",
"SSE.Views.ChartSettingsDlg.textLegendBottom": "Bottom",
"SSE.Views.ChartSettingsDlg.textLegendLeft": "Left",
@ -385,6 +391,7 @@
"SSE.Views.ChartSettingsDlg.textPie": "Pie Chart",
"SSE.Views.ChartSettingsDlg.textPoint": "Point Chart",
"SSE.Views.ChartSettingsDlg.textReverse": "Values in reverse order",
"SSE.Views.ChartSettingsDlg.textRight": "Right",
"SSE.Views.ChartSettingsDlg.textRightOverlay": "Right Overlay",
"SSE.Views.ChartSettingsDlg.textRotated": "Rotated",
"SSE.Views.ChartSettingsDlg.textSelectData": "Select Data",
@ -404,6 +411,7 @@
"SSE.Views.ChartSettingsDlg.textThousands": "Thousands",
"SSE.Views.ChartSettingsDlg.textTickOptions": "Tick Options",
"SSE.Views.ChartSettingsDlg.textTitle": "Chart - Advanced Settings",
"SSE.Views.ChartSettingsDlg.textTop": "Top",
"SSE.Views.ChartSettingsDlg.textTrillions": "Trillions",
"SSE.Views.ChartSettingsDlg.textType": "Type",
"SSE.Views.ChartSettingsDlg.textTypeData": "Type & Data",
@ -416,11 +424,6 @@
"SSE.Views.ChartSettingsDlg.textXAxisTitle": "X Axis Title",
"SSE.Views.ChartSettingsDlg.textYAxisTitle": "Y Axis Title",
"SSE.Views.ChartSettingsDlg.txtEmpty": "This field is required",
"SSE.Views.ChartSettingsDlg.textLeft": "Left",
"SSE.Views.ChartSettingsDlg.textRight": "Right",
"SSE.Views.ChartSettingsDlg.textTop": "Top",
"SSE.Views.ChartSettingsDlg.textBottom": "Bottom",
"SSE.Views.ChartSettingsDlg.textFit": "Fit Width",
"SSE.Views.DigitalFilterDialog.cancelButtonText": "Cancel",
"SSE.Views.DigitalFilterDialog.capAnd": "And",
"SSE.Views.DigitalFilterDialog.capCondition1": "equals",

View file

@ -25,6 +25,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Reemplazar todo",
"Common.UI.SynchronizeTip.textDontShow": "No volver a mostrar este mensaje",
"Common.UI.SynchronizeTip.textSynchronize": "El documento ha sido cambiado por otro usuario.<br/>Por favor haga clic para guardar sus cambios y recargue las actualizaciones.",
"Common.UI.ThemeColorPalette.textStandartColors": "Colores estándar",
"Common.UI.ThemeColorPalette.textThemeColors": "Colores de tema",
"Common.UI.Window.cancelButtonText": "Cancelar",
"Common.UI.Window.closeButtonText": "Cerrar",
"Common.UI.Window.noButtonText": "No",
@ -81,10 +83,18 @@
"Common.Views.OpenDialog.okButtonText": "OK",
"Common.Views.OpenDialog.txtDelimiter": "Delimitador",
"Common.Views.OpenDialog.txtEncoding": "Codificación ",
"Common.Views.OpenDialog.txtPassword": "Password",
"Common.Views.OpenDialog.txtSpace": "Espacio",
"Common.Views.OpenDialog.txtTab": "Pestaña",
"Common.Views.OpenDialog.txtTitle": "Elegir opciones de %1",
"Common.Views.OpenDialog.txtTitleProtected": "Protected File",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"SSE.Controllers.DocumentHolder.errorInvalidLink": "The link reference does not exist. Please correct the link or delete it.",
"SSE.Controllers.DocumentHolder.guestText": "Visitante",
"SSE.Controllers.DocumentHolder.notcriticalErrorTitle": "Warning",
"SSE.Controllers.DocumentHolder.textChangeColumnWidth": "Ancho de columna {0} símbolos ({1} píxeles)",
"SSE.Controllers.DocumentHolder.textChangeRowHeight": "Altura de fila {0} puntos ({1} píxeles)",
"SSE.Controllers.DocumentHolder.textCtrlClick": "Pulse CTRL y haga clic en el enlace",
@ -157,6 +167,7 @@
"SSE.Controllers.Main.errorUpdateVersion": "Se ha cambiado la versión del archivo. La página será actualizada.",
"SSE.Controllers.Main.errorUserDrop": "No se puede acceder al archivo ahora.",
"SSE.Controllers.Main.errorUsersExceed": "El número de usuarios permitido según su plan de precios fue excedido",
"SSE.Controllers.Main.errorViewerDisconnect": "Connection is lost. You can still view the document,<br>but will not be able to download until the connection is restored.",
"SSE.Controllers.Main.errorWrongBracketsCount": "Un error en la fórmula introducida.<br>Número incorrecto de corchetes es usado.",
"SSE.Controllers.Main.errorWrongOperator": "Un error en la fórmula introducida.Operador inválido es usado.<br>Por favor, corrija el error o utilice el botón Esc para cancelar la edición de fórmulas.",
"SSE.Controllers.Main.leavePageText": "Usted tiene cambios no guardados en esta hoja de cálculo. Haga clic en 'Permanecer en esta página', después 'Guardar' para guardarlos. Haga clic en 'Abandonar esta página' para descartar todos los cambios no guardados.",
@ -170,6 +181,7 @@
"SSE.Controllers.Main.loadImageTitleText": "Cargando imagen",
"SSE.Controllers.Main.loadingDocumentTitleText": "Cargando hoja de cálculo",
"SSE.Controllers.Main.notcriticalErrorTitle": "Aviso",
"SSE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"SSE.Controllers.Main.openTextText": "Abriendo hoja de cálculo...",
"SSE.Controllers.Main.openTitleText": "Abriendo hoja de cálculo",
"SSE.Controllers.Main.pastInMergeAreaError": "No se puede cambiar parte de una celda combinada",
@ -178,6 +190,7 @@
"SSE.Controllers.Main.reloadButtonText": "Recargar página",
"SSE.Controllers.Main.requestEditFailedMessageText": "Alguien está editando este documento en este momento. Por favor, inténtelo de nuevo más tarde.",
"SSE.Controllers.Main.requestEditFailedTitleText": "Acceso negado",
"SSE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"SSE.Controllers.Main.savePreparingText": "Preparando para guardar",
"SSE.Controllers.Main.savePreparingTitle": "Preparando para guardar.Espere por favor...",
"SSE.Controllers.Main.saveTextText": "Guardando hoja de cálculo...",
@ -196,6 +209,7 @@
"SSE.Controllers.Main.textStrict": "Modo estricto",
"SSE.Controllers.Main.textTryUndoRedo": "Las funciones Anular/Rehacer se desactivan para el modo co-edición rápido.<br>Haga Clic en el botón \"modo estricto\" para cambiar al modo de co-edición estricta para editar el archivo sin la interferencia de otros usuarios y enviar sus cambios sólo después de guardarlos. Se puede cambiar entre los modos de co-edición usando los ajustes avanzados de edición.",
"SSE.Controllers.Main.textYes": "Sí",
"SSE.Controllers.Main.titleLicenseExp": "License expired",
"SSE.Controllers.Main.titleRecalcFormulas": "Calculando...",
"SSE.Controllers.Main.txtArt": "Su texto aquí",
"SSE.Controllers.Main.txtBasicShapes": "Formas básicas",
@ -221,6 +235,7 @@
"SSE.Controllers.Main.uploadImageTitleText": "Subiendo imagen",
"SSE.Controllers.Main.warnBrowserIE9": "Este aplicación tiene baja capacidad en IE9. Utilice IE10 o superior",
"SSE.Controllers.Main.warnBrowserZoom": "La configuración actual de zoom de su navegador no está soportada por completo. Por favor restablezca zoom predeterminado pulsando Ctrl+0.",
"SSE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"SSE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"SSE.Controllers.Main.warnProcessRightsChange": "El derecho de edición del archivo es denegado.",
"SSE.Controllers.Print.strAllSheets": "Todas las hojas",
@ -307,6 +322,7 @@
"SSE.Views.ChartSettingsDlg.textBar": "Gráfico de barras",
"SSE.Views.ChartSettingsDlg.textBetweenTickMarks": "Entre marcas de graduación",
"SSE.Views.ChartSettingsDlg.textBillions": "Millardos",
"SSE.Views.ChartSettingsDlg.textBottom": "Bottom",
"SSE.Views.ChartSettingsDlg.textCategoryName": "Nombre de categoría",
"SSE.Views.ChartSettingsDlg.textCenter": "Al centro",
"SSE.Views.ChartSettingsDlg.textChartElementsLegend": "Elementos de gráfico y <br/>leyenda de gráfico",
@ -320,6 +336,7 @@
"SSE.Views.ChartSettingsDlg.textDataRows": "en filas",
"SSE.Views.ChartSettingsDlg.textDataSeries": "Serie de datos",
"SSE.Views.ChartSettingsDlg.textDisplayLegend": "Mostrar Leyenda",
"SSE.Views.ChartSettingsDlg.textFit": "Fit to Width",
"SSE.Views.ChartSettingsDlg.textFixed": "Corregido",
"SSE.Views.ChartSettingsDlg.textGridLines": "Líneas de cuadrícula",
"SSE.Views.ChartSettingsDlg.textHide": "Ocultar",
@ -340,6 +357,7 @@
"SSE.Views.ChartSettingsDlg.textLabelOptions": "Parámetros de etiqueta",
"SSE.Views.ChartSettingsDlg.textLabelPos": "Posición de etiqueta",
"SSE.Views.ChartSettingsDlg.textLayout": "Diseño",
"SSE.Views.ChartSettingsDlg.textLeft": "Left",
"SSE.Views.ChartSettingsDlg.textLeftOverlay": "Superposición a la izquierda",
"SSE.Views.ChartSettingsDlg.textLegendBottom": "Inferior",
"SSE.Views.ChartSettingsDlg.textLegendLeft": "Izquierdo",
@ -370,6 +388,7 @@
"SSE.Views.ChartSettingsDlg.textPie": "Gráfico circular",
"SSE.Views.ChartSettingsDlg.textPoint": "Gráfico de Punto",
"SSE.Views.ChartSettingsDlg.textReverse": "Valores en orden inverso",
"SSE.Views.ChartSettingsDlg.textRight": "Right",
"SSE.Views.ChartSettingsDlg.textRightOverlay": "Superposición a la derecha",
"SSE.Views.ChartSettingsDlg.textRotated": "Girado",
"SSE.Views.ChartSettingsDlg.textSelectData": "Selección de datos",
@ -389,6 +408,7 @@
"SSE.Views.ChartSettingsDlg.textThousands": "Miles",
"SSE.Views.ChartSettingsDlg.textTickOptions": "Parámetros de marcas de graduación",
"SSE.Views.ChartSettingsDlg.textTitle": "Gráfico- Ajustes avanzados",
"SSE.Views.ChartSettingsDlg.textTop": "Top",
"SSE.Views.ChartSettingsDlg.textTrillions": "Billones",
"SSE.Views.ChartSettingsDlg.textType": "Tipo",
"SSE.Views.ChartSettingsDlg.textTypeData": "Tipo y datos",
@ -454,6 +474,8 @@
"SSE.Views.DocumentHolder.txtAddNamedRange": "Definir Nombre",
"SSE.Views.DocumentHolder.txtArrange": "Arreglar",
"SSE.Views.DocumentHolder.txtAscending": "Ascendente",
"SSE.Views.DocumentHolder.txtAutoColumnWidth": "Auto Fit Column Width",
"SSE.Views.DocumentHolder.txtAutoRowHeight": "Auto Fit Row Height",
"SSE.Views.DocumentHolder.txtClear": "Limpiar",
"SSE.Views.DocumentHolder.txtClearAll": "Todo",
"SSE.Views.DocumentHolder.txtClearComments": "Comentarios",
@ -463,6 +485,8 @@
"SSE.Views.DocumentHolder.txtColumn": "Toda la columna",
"SSE.Views.DocumentHolder.txtColumnWidth": "Ancho de columna",
"SSE.Views.DocumentHolder.txtCopy": "Copiar",
"SSE.Views.DocumentHolder.txtCustomColumnWidth": "Custom Column Width",
"SSE.Views.DocumentHolder.txtCustomRowHeight": "Custom Row Height",
"SSE.Views.DocumentHolder.txtCut": "Cortar",
"SSE.Views.DocumentHolder.txtDelete": "Borrar",
"SSE.Views.DocumentHolder.txtDescending": "Descendente",
@ -613,6 +637,8 @@
"SSE.Views.HyperlinkSettingsDialog.textTitle": "Configuración de hiperenlace",
"SSE.Views.HyperlinkSettingsDialog.txtEmpty": "Este campo es obligatorio",
"SSE.Views.HyperlinkSettingsDialog.txtNotUrl": "El campo debe ser URL en el formato \"http://www.example.com\"",
"SSE.Views.ImageSettings.textEdit": "Edit",
"SSE.Views.ImageSettings.textEditObject": "Edit Object",
"SSE.Views.ImageSettings.textFromFile": "De archivo",
"SSE.Views.ImageSettings.textFromUrl": "De URL",
"SSE.Views.ImageSettings.textHeight": "Altura",
@ -625,6 +651,7 @@
"SSE.Views.LeftMenu.tipChat": "Chat",
"SSE.Views.LeftMenu.tipComments": "Comentarios",
"SSE.Views.LeftMenu.tipFile": "Archivo",
"SSE.Views.LeftMenu.tipPlugins": "Plugins",
"SSE.Views.LeftMenu.tipSearch": "Buscar",
"SSE.Views.LeftMenu.tipSupport": "Feedback y Soporte",
"SSE.Views.MainSettingsPrint.okButtonText": "Guardar",
@ -773,6 +800,7 @@
"SSE.Views.ShapeSettings.strSize": "Tamaño",
"SSE.Views.ShapeSettings.strStroke": "Trazo",
"SSE.Views.ShapeSettings.strTransparency": "Opacidad ",
"SSE.Views.ShapeSettings.strType": "Type",
"SSE.Views.ShapeSettings.textAdvanced": "Mostrar ajustes avanzados",
"SSE.Views.ShapeSettings.textBorderSizeErr": "El valor numérico es incorrecto.<br>Por favor, introduzca un valor de 0 a 1584 puntos.",
"SSE.Views.ShapeSettings.textColor": "Color de relleno",
@ -790,11 +818,9 @@
"SSE.Views.ShapeSettings.textPatternFill": "Patrón",
"SSE.Views.ShapeSettings.textRadial": "Radial",
"SSE.Views.ShapeSettings.textSelectTexture": "Seleccionar",
"SSE.Views.ShapeSettings.textStandartColors": "Colores estándar",
"SSE.Views.ShapeSettings.textStretch": "Estirar",
"SSE.Views.ShapeSettings.textStyle": "Estilo",
"SSE.Views.ShapeSettings.textTexture": "De textura",
"SSE.Views.ShapeSettings.textThemeColors": "Colores de tema",
"SSE.Views.ShapeSettings.textTile": "Mosaico",
"SSE.Views.ShapeSettings.txtBrownPaper": "Papel marrón",
"SSE.Views.ShapeSettings.txtCanvas": "Lienzo",
@ -853,9 +879,7 @@
"SSE.Views.Statusbar.textCount": "CANTIDAD",
"SSE.Views.Statusbar.textNewColor": "Añadir Color Personalizado Nuevo",
"SSE.Views.Statusbar.textNoColor": "Sin color",
"SSE.Views.Statusbar.textStandartColors": "Colores estándar",
"SSE.Views.Statusbar.textSum": "SUMA",
"SSE.Views.Statusbar.textThemeColors": "Colores de tema",
"SSE.Views.Statusbar.tipAccessRights": "Administrar los derechos de acceso de documentos",
"SSE.Views.Statusbar.tipAddTab": "Añadir hoja de cálculo",
"SSE.Views.Statusbar.tipFirst": "Desplazar hasta la primera hoja",
@ -917,6 +941,7 @@
"SSE.Views.TextArtSettings.strSize": "Tamaño",
"SSE.Views.TextArtSettings.strStroke": "Trazo",
"SSE.Views.TextArtSettings.strTransparency": "Opacidad ",
"SSE.Views.TextArtSettings.strType": "Type",
"SSE.Views.TextArtSettings.textBorderSizeErr": "El valor numérico es incorrecto.<br>Por favor, introduzca un valor de 0 a 1584 puntos.",
"SSE.Views.TextArtSettings.textColor": "Color de relleno",
"SSE.Views.TextArtSettings.textDirection": "Direction",
@ -932,12 +957,10 @@
"SSE.Views.TextArtSettings.textPatternFill": "Patrón",
"SSE.Views.TextArtSettings.textRadial": "Radial",
"SSE.Views.TextArtSettings.textSelectTexture": "Select",
"SSE.Views.TextArtSettings.textStandartColors": "Colores estándar",
"SSE.Views.TextArtSettings.textStretch": "Estirar",
"SSE.Views.TextArtSettings.textStyle": "Estilo",
"SSE.Views.TextArtSettings.textTemplate": "Plantilla",
"SSE.Views.TextArtSettings.textTexture": "De textura",
"SSE.Views.TextArtSettings.textThemeColors": "Colores de tema",
"SSE.Views.TextArtSettings.textTile": "Mosaico",
"SSE.Views.TextArtSettings.textTransform": "Transformar",
"SSE.Views.TextArtSettings.txtBrownPaper": "Papel marrón",
@ -997,8 +1020,6 @@
"SSE.Views.Toolbar.textRightBorders": "Bordes derechos",
"SSE.Views.Toolbar.textRotateDown": "Girar texto hacia abajo",
"SSE.Views.Toolbar.textRotateUp": "Girar texto hacia arriba",
"SSE.Views.Toolbar.textStandartColors": "Colores estándar",
"SSE.Views.Toolbar.textThemeColors": "Colores de tema",
"SSE.Views.Toolbar.textTopBorders": "Bordes superiores",
"SSE.Views.Toolbar.textUnderline": "Subrayar",
"SSE.Views.Toolbar.textZoom": "Zoom",

View file

@ -25,6 +25,8 @@
"Common.UI.SearchDialog.txtBtnReplaceAll": "Remplacer tout",
"Common.UI.SynchronizeTip.textDontShow": "N'afficher plus ce message",
"Common.UI.SynchronizeTip.textSynchronize": "Le document a été modifié par un autre utilisateur.<br/>Cliquez pour enregistrer vos modifications et recharger les mises à jour.",
"Common.UI.ThemeColorPalette.textStandartColors": "Couleurs standard",
"Common.UI.ThemeColorPalette.textThemeColors": "Couleurs de thème",
"Common.UI.Window.cancelButtonText": "Annuler",
"Common.UI.Window.closeButtonText": "Fermer",
"Common.UI.Window.noButtonText": "Non",
@ -81,10 +83,18 @@
"Common.Views.OpenDialog.okButtonText": "OK",
"Common.Views.OpenDialog.txtDelimiter": "Délimiteur",
"Common.Views.OpenDialog.txtEncoding": "Encodage",
"Common.Views.OpenDialog.txtPassword": "Password",
"Common.Views.OpenDialog.txtSpace": "Espace",
"Common.Views.OpenDialog.txtTab": "Onglet",
"Common.Views.OpenDialog.txtTitle": "Choisir %1 des options ",
"Common.Views.OpenDialog.txtTitleProtected": "Protected File",
"Common.Views.PluginDlg.textLoading": "Loading",
"Common.Views.Plugins.strPlugins": "Plugins",
"Common.Views.Plugins.textLoading": "Loading",
"Common.Views.Plugins.textStart": "Start",
"SSE.Controllers.DocumentHolder.errorInvalidLink": "The link reference does not exist. Please correct the link or delete it.",
"SSE.Controllers.DocumentHolder.guestText": "Invité",
"SSE.Controllers.DocumentHolder.notcriticalErrorTitle": "Warning",
"SSE.Controllers.DocumentHolder.textChangeColumnWidth": "Largeur de colonne {0} symboles ({1} pixels)",
"SSE.Controllers.DocumentHolder.textChangeRowHeight": "Hauteur de ligne {0} points ({1} pixels)",
"SSE.Controllers.DocumentHolder.textCtrlClick": "Appuyez sur Ctrl et cliquez sur le lien",
@ -157,6 +167,7 @@
"SSE.Controllers.Main.errorUpdateVersion": "La version du fichier a été changée. La page sera rechargée.",
"SSE.Controllers.Main.errorUserDrop": "Impossible d'accéder au fichier",
"SSE.Controllers.Main.errorUsersExceed": "Le nombre d'utilisateurs autorisés par le plan tarifaire a été dépassé",
"SSE.Controllers.Main.errorViewerDisconnect": "Connection is lost. You can still view the document,<br>but will not be able to download until the connection is restored.",
"SSE.Controllers.Main.errorWrongBracketsCount": "Une erreur dans la formule entrée.<br>Nombre utilisé entre parenthèses est incorrect.",
"SSE.Controllers.Main.errorWrongOperator": "Une erreur dans la formule entrée.<br>Opérateur utilisé est incorrect.<br>Veuillez corriger l'erreur ou utilisez le bouton Esc pour annuler l'édition de formule.",
"SSE.Controllers.Main.leavePageText": "Vous avez des modifications non enregistrées dans cette feuille de calcul. Cliquez sur 'Rester sur cette page ' ensuite 'Enregistrer' pour les enregistrer. Cliquez sur 'Quitter cette page' pour annuler toutes les modifications non enregistrées.",
@ -170,6 +181,7 @@
"SSE.Controllers.Main.loadImageTitleText": "Chargement d'une image",
"SSE.Controllers.Main.loadingDocumentTitleText": "Chargement feuille de calcul",
"SSE.Controllers.Main.notcriticalErrorTitle": "Avertissement",
"SSE.Controllers.Main.openErrorText": "An error has occurred while opening the file",
"SSE.Controllers.Main.openTextText": "Ouverture de la feuille de calcul en cours...",
"SSE.Controllers.Main.openTitleText": "Ouverture de la feuille de calcul",
"SSE.Controllers.Main.pastInMergeAreaError": "Impossible de modifier une partie d'une cellule fusionnée",
@ -178,6 +190,7 @@
"SSE.Controllers.Main.reloadButtonText": "Recharger la page",
"SSE.Controllers.Main.requestEditFailedMessageText": "Quelqu'un est en train de modifier ce document. Veuillez réessayer plus tard.",
"SSE.Controllers.Main.requestEditFailedTitleText": "Accès refusé",
"SSE.Controllers.Main.saveErrorText": "An error has occurred while saving the file",
"SSE.Controllers.Main.savePreparingText": "Préparation à l'enregistrement ",
"SSE.Controllers.Main.savePreparingTitle": "Préparation à l'enregistrement en cours. Veuillez patienter...",
"SSE.Controllers.Main.saveTextText": "Enregistrement de la feuille de calcul en cours ...",
@ -196,6 +209,7 @@
"SSE.Controllers.Main.textStrict": "Mode strict",
"SSE.Controllers.Main.textTryUndoRedo": "Les fonctions annuler/rétablir sont désactivées pour le mode de co-édition rapide.<br>Cliquez sur le bouton \"Mode strict\" pour passer au mode de la co-édition stricte pour modifier le fichier sans interférence d'autres utilisateurs et envoyer vos modifications seulement après que vous les enregistrez. Vous pouvez basculer entre les modes de co-édition à l'aide de paramètres avancés d'éditeur.",
"SSE.Controllers.Main.textYes": "Oui",
"SSE.Controllers.Main.titleLicenseExp": "License expired",
"SSE.Controllers.Main.titleRecalcFormulas": "Calcul en cours...",
"SSE.Controllers.Main.txtArt": "Votre texte ici",
"SSE.Controllers.Main.txtBasicShapes": "Formes de base",
@ -221,6 +235,7 @@
"SSE.Controllers.Main.uploadImageTitleText": "Chargement d'une image",
"SSE.Controllers.Main.warnBrowserIE9": "L'application est peu compatible avec IE9. Utilisez IE10 ou version plus récente",
"SSE.Controllers.Main.warnBrowserZoom": "Le paramètre actuel de zoom de votre navigateur n'est pas accepté. Veuillez rétablir le niveau de zoom par défaut en appuyant sur Ctrl+0.",
"SSE.Controllers.Main.warnLicenseExp": "Your license has expired.<br>Please update your license and refresh the page.",
"SSE.Controllers.Main.warnNoLicense": "You are using an open source version of ONLYOFFICE. The version has limitations for concurrent connections to the document server (20 connections at a time).<br>If you need more please consider purchasing a commercial license.",
"SSE.Controllers.Main.warnProcessRightsChange": "Le droit d'édition du fichier vous a été refusé.",
"SSE.Controllers.Print.strAllSheets": "Toutes les feuilles",
@ -307,6 +322,7 @@
"SSE.Views.ChartSettingsDlg.textBar": "Diagramme à barres",
"SSE.Views.ChartSettingsDlg.textBetweenTickMarks": "Entre graduations",
"SSE.Views.ChartSettingsDlg.textBillions": "Milliards",
"SSE.Views.ChartSettingsDlg.textBottom": "Bottom",
"SSE.Views.ChartSettingsDlg.textCategoryName": "Nom de la catégorie",
"SSE.Views.ChartSettingsDlg.textCenter": "Au centre",
"SSE.Views.ChartSettingsDlg.textChartElementsLegend": "Éléments de graphique,<br/>légende de graphique",
@ -320,6 +336,7 @@
"SSE.Views.ChartSettingsDlg.textDataRows": "en lignes",
"SSE.Views.ChartSettingsDlg.textDataSeries": "Série de données",
"SSE.Views.ChartSettingsDlg.textDisplayLegend": "Afficher une légende",
"SSE.Views.ChartSettingsDlg.textFit": "Fit to Width",
"SSE.Views.ChartSettingsDlg.textFixed": "Corrigé",
"SSE.Views.ChartSettingsDlg.textGridLines": "Quadrillage",
"SSE.Views.ChartSettingsDlg.textHide": "Masquer",
@ -340,6 +357,7 @@
"SSE.Views.ChartSettingsDlg.textLabelOptions": "Options d'étiquettes",
"SSE.Views.ChartSettingsDlg.textLabelPos": "Position de l'étiquette",
"SSE.Views.ChartSettingsDlg.textLayout": "Disposition",
"SSE.Views.ChartSettingsDlg.textLeft": "Left",
"SSE.Views.ChartSettingsDlg.textLeftOverlay": "Superposition à gauche",
"SSE.Views.ChartSettingsDlg.textLegendBottom": "En bas",
"SSE.Views.ChartSettingsDlg.textLegendLeft": "A gauche",
@ -370,6 +388,7 @@
"SSE.Views.ChartSettingsDlg.textPie": "Graphiques à secteurs",
"SSE.Views.ChartSettingsDlg.textPoint": "Diagramme de dispersion",
"SSE.Views.ChartSettingsDlg.textReverse": "Valeurs en ordre inverse",
"SSE.Views.ChartSettingsDlg.textRight": "Right",
"SSE.Views.ChartSettingsDlg.textRightOverlay": "Superposition à droite",
"SSE.Views.ChartSettingsDlg.textRotated": "Incliné",
"SSE.Views.ChartSettingsDlg.textSelectData": "Sélectionner des données",
@ -389,6 +408,7 @@
"SSE.Views.ChartSettingsDlg.textThousands": "Milliers",
"SSE.Views.ChartSettingsDlg.textTickOptions": "Cochez les options",
"SSE.Views.ChartSettingsDlg.textTitle": "Graphique - Paramètres avancés",
"SSE.Views.ChartSettingsDlg.textTop": "Top",
"SSE.Views.ChartSettingsDlg.textTrillions": "Trillions",
"SSE.Views.ChartSettingsDlg.textType": "Type",
"SSE.Views.ChartSettingsDlg.textTypeData": "Type et données",
@ -454,6 +474,8 @@
"SSE.Views.DocumentHolder.txtAddNamedRange": "Définir un nom",
"SSE.Views.DocumentHolder.txtArrange": "Organiser",
"SSE.Views.DocumentHolder.txtAscending": "Croissant",
"SSE.Views.DocumentHolder.txtAutoColumnWidth": "Auto Fit Column Width",
"SSE.Views.DocumentHolder.txtAutoRowHeight": "Auto Fit Row Height",
"SSE.Views.DocumentHolder.txtClear": "Effacer",
"SSE.Views.DocumentHolder.txtClearAll": "Tout",
"SSE.Views.DocumentHolder.txtClearComments": "Commentaires",
@ -463,6 +485,8 @@
"SSE.Views.DocumentHolder.txtColumn": "Colonne entière",
"SSE.Views.DocumentHolder.txtColumnWidth": "Largeur de colonne",
"SSE.Views.DocumentHolder.txtCopy": "Copier",
"SSE.Views.DocumentHolder.txtCustomColumnWidth": "Custom Column Width",
"SSE.Views.DocumentHolder.txtCustomRowHeight": "Custom Row Height",
"SSE.Views.DocumentHolder.txtCut": "Couper",
"SSE.Views.DocumentHolder.txtDelete": "Supprimer",
"SSE.Views.DocumentHolder.txtDescending": "Décroissant",
@ -613,6 +637,8 @@
"SSE.Views.HyperlinkSettingsDialog.textTitle": "Paramètres du lien hypertexte",
"SSE.Views.HyperlinkSettingsDialog.txtEmpty": "Ce champ est obligatoire",
"SSE.Views.HyperlinkSettingsDialog.txtNotUrl": "Ce champ doit contenir une URL au format \"http://www.example.com\"",
"SSE.Views.ImageSettings.textEdit": "Edit",
"SSE.Views.ImageSettings.textEditObject": "Edit Object",
"SSE.Views.ImageSettings.textFromFile": "D'un fichier",
"SSE.Views.ImageSettings.textFromUrl": "D'une URL",
"SSE.Views.ImageSettings.textHeight": "Hauteur",
@ -625,6 +651,7 @@
"SSE.Views.LeftMenu.tipChat": "Chat",
"SSE.Views.LeftMenu.tipComments": "Commentaires",
"SSE.Views.LeftMenu.tipFile": "Fichier",
"SSE.Views.LeftMenu.tipPlugins": "Plugins",
"SSE.Views.LeftMenu.tipSearch": "Rechercher",
"SSE.Views.LeftMenu.tipSupport": "Commentaires & assistance",
"SSE.Views.MainSettingsPrint.okButtonText": "Enregistrer",
@ -773,6 +800,7 @@
"SSE.Views.ShapeSettings.strSize": "Taille",
"SSE.Views.ShapeSettings.strStroke": "Trait",
"SSE.Views.ShapeSettings.strTransparency": "Opacité",
"SSE.Views.ShapeSettings.strType": "Type",
"SSE.Views.ShapeSettings.textAdvanced": "Afficher les paramètres avancés",
"SSE.Views.ShapeSettings.textBorderSizeErr": "La valeur saisie est incorrecte. <br>Entrez une valeur de 0 à 1584 points.",
"SSE.Views.ShapeSettings.textColor": "Couleur de remplissage",
@ -790,11 +818,9 @@
"SSE.Views.ShapeSettings.textPatternFill": "Modèle",
"SSE.Views.ShapeSettings.textRadial": "Radial",
"SSE.Views.ShapeSettings.textSelectTexture": "Sélectionner",
"SSE.Views.ShapeSettings.textStandartColors": "Couleurs standard",
"SSE.Views.ShapeSettings.textStretch": "Prolonger",
"SSE.Views.ShapeSettings.textStyle": "Style",
"SSE.Views.ShapeSettings.textTexture": "D'une texture",
"SSE.Views.ShapeSettings.textThemeColors": "Couleurs de thème",
"SSE.Views.ShapeSettings.textTile": "Tuile",
"SSE.Views.ShapeSettings.txtBrownPaper": "Papier brun",
"SSE.Views.ShapeSettings.txtCanvas": "Toile",
@ -851,11 +877,9 @@
"SSE.Views.Statusbar.RenameDialog.labelSheetName": "Nom de la feuille",
"SSE.Views.Statusbar.textAverage": "MOYENNE",
"SSE.Views.Statusbar.textCount": "COMPTE",
"SSE.Views.Statusbar.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"SSE.Views.Statusbar.textNewColor": "Couleur Personnalisée",
"SSE.Views.Statusbar.textNoColor": "Pas de couleur",
"SSE.Views.Statusbar.textStandartColors": "Couleurs standard",
"SSE.Views.Statusbar.textSum": "SOMME",
"SSE.Views.Statusbar.textThemeColors": "Couleurs de thème",
"SSE.Views.Statusbar.tipAccessRights": "Gérez des droits d'accès aux documents ",
"SSE.Views.Statusbar.tipAddTab": "Ajouter feuille de calcul",
"SSE.Views.Statusbar.tipFirst": "Faire défiler vers la première feuille de calcul",
@ -917,6 +941,7 @@
"SSE.Views.TextArtSettings.strSize": "Taille",
"SSE.Views.TextArtSettings.strStroke": "Stroke",
"SSE.Views.TextArtSettings.strTransparency": "Opacité",
"SSE.Views.TextArtSettings.strType": "Type",
"SSE.Views.TextArtSettings.textBorderSizeErr": "La valeur saisie est incorrecte. <br>Entrez une valeur de 0 à 1584 points.",
"SSE.Views.TextArtSettings.textColor": "Couleur de remplissage",
"SSE.Views.TextArtSettings.textDirection": "Direction",
@ -927,17 +952,15 @@
"SSE.Views.TextArtSettings.textGradientFill": "Remplissage en dégradé",
"SSE.Views.TextArtSettings.textImageTexture": "Image ou texture",
"SSE.Views.TextArtSettings.textLinear": "Linéaire",
"SSE.Views.TextArtSettings.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"SSE.Views.TextArtSettings.textNewColor": "Couleur Personnalisée",
"SSE.Views.TextArtSettings.textNoFill": "Pas de remplissage",
"SSE.Views.TextArtSettings.textPatternFill": "Modèle",
"SSE.Views.TextArtSettings.textRadial": "Radial",
"SSE.Views.TextArtSettings.textSelectTexture": "Sélectionner",
"SSE.Views.TextArtSettings.textStandartColors": "Couleurs standard",
"SSE.Views.TextArtSettings.textStretch": "Prolonger",
"SSE.Views.TextArtSettings.textStyle": "Style",
"SSE.Views.TextArtSettings.textTemplate": "Modèle",
"SSE.Views.TextArtSettings.textTexture": "D'une texture",
"SSE.Views.TextArtSettings.textThemeColors": "Couleurs de thème",
"SSE.Views.TextArtSettings.textTile": "Tuile",
"SSE.Views.TextArtSettings.textTransform": "Transformer",
"SSE.Views.TextArtSettings.txtBrownPaper": "Papier brun",
@ -989,7 +1012,7 @@
"SSE.Views.Toolbar.textItalic": "Italique",
"SSE.Views.Toolbar.textLeftBorders": "Bordures gauches",
"SSE.Views.Toolbar.textMiddleBorders": "Bordures intérieures horizontales",
"SSE.Views.Toolbar.textNewColor": "Ajouter Nouvelle Couleur Personnalisée",
"SSE.Views.Toolbar.textNewColor": "Couleur Personnalisée",
"SSE.Views.Toolbar.textNoBorders": "Pas de bordures",
"SSE.Views.Toolbar.textOutBorders": "Bordures extérieures",
"SSE.Views.Toolbar.textPrint": "Imprimer",
@ -997,8 +1020,6 @@
"SSE.Views.Toolbar.textRightBorders": "Bordures droites",
"SSE.Views.Toolbar.textRotateDown": "Rotation du texte vers le bas",
"SSE.Views.Toolbar.textRotateUp": "Rotation du texte vers le haut",
"SSE.Views.Toolbar.textStandartColors": "Couleurs standard",
"SSE.Views.Toolbar.textThemeColors": "Couleurs de thème",
"SSE.Views.Toolbar.textTopBorders": "Bordures supérieures",
"SSE.Views.Toolbar.textUnderline": "Souligné",
"SSE.Views.Toolbar.textZoom": "Zoom",

View file

@ -73,6 +73,24 @@
launch: function() {
this.callParent(arguments);
if (Ext.os.is.iOS) {
Ext.each(Ext.ComponentQuery.query('button'), function(button) {
button.element.dom.ontouchstart = Ext.emptyFn();
button.element.dom.ontouchmove = Ext.emptyFn();
button.element.dom.ontouchend = Ext.emptyFn();
}, this);
Ext.each(Ext.ComponentQuery.query('toolbar'), function(toolbar) {
var preventFn = function(e){
e.preventDefault();
};
toolbar.element.dom.ontouchstart = preventFn;
toolbar.element.dom.ontouchmove = preventFn;
toolbar.element.dom.ontouchend = preventFn;
}, this);
}
Common.Gateway.on('init', Ext.bind(this.loadConfig, this));
},

View file

@ -1,4 +1,4 @@
Sencha Touch - JavaScript Library
Sencha Touch & Sencha Touch Charts - JavaScript Libraries
Copyright (c) 2010-2015, Sencha, Inc.
All rights reserved.
licensing@sencha.com
@ -6,23 +6,43 @@ licensing@sencha.com
http://www.sencha.com/products/touch/license.php
Commercial License
Open Source License
------------------------------------------------------------------------------------------
This version of Sencha Touch is licensed commercially.
This version of Sencha Touch and Sencha Touch Charts is licensed under the terms of the Open
Source GPL 3.0 license.
http://www.gnu.org/licenses/gpl.html
There are several FLOSS exceptions available for use with this release for
open source applications that are distributed under a license other than the GPL.
* Open Source License Exception for Applications
http://www.sencha.com/products/floss-exception.php
* Open Source License Exception for Development
http://www.sencha.com/products/ux-exception.php
Alternate Licensing for Sencha Touch
------------------------------------------------------------------------------------------
Commercial and OEM Licenses are available for an alternate download of Sencha Touch.
This is the appropriate option if you are creating proprietary applications and you are
not prepared to distribute and share the source code of your application under the
GPL v3 license. Please visit http://www.sencha.com/store/touch/license.php for more details.
OEM / Reseller License
Alternate Licensing for Sencha Touch Charts
------------------------------------------------------------------------------------------
For more details, please visit: http://www.sencha.com/products/touch/license.php
Commercial and OEM Licenses are available for an alternate download of Sencha Touch Charts.
This is the appropriate option if you are creating proprietary applications and you are
not prepared to distribute and share the source code of your application under the
GPL v3 license.
Open Source Licensing
------------------------------------------------------------------------------------------
Open Source Licensing is available for an alternate download of Sencha Touch.
For more details, please visit http://www.sencha.com/store/touch/license.php for more details.
Sencha Touch Charts is available commercially only as a part of Sencha Complete or Sencha
Complete Team. Please visit http://www.sencha.com/products/complete/license or
http://www.sencha.com/products/complete-team/license for more details.
Third Party Content

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -5,10 +5,13 @@ Copyright (c) 2011-2015 Sencha Inc
Contact: http://www.sencha.com/contact
Commercial Usage
Licensees holding valid commercial licenses may use this file in accordance with the Commercial
Software License Agreement provided with the Software or, alternatively, in accordance with the
terms contained in a written agreement between you and Sencha.
GNU General Public License Usage
This file may be used under the terms of the GNU General Public License version 3.0 as
published by the Free Software Foundation and appearing in the file LICENSE included in the
packaging of this file.
Please review the following information to ensure the GNU General Public License version 3.0
requirements will be met: http://www.gnu.org/copyleft/gpl.html.
If you are unsure which license is appropriate for your use, please contact the sales department
at http://www.sencha.com/contact.
@ -9290,6 +9293,11 @@ Ext.apply(Ext, {
elementSize: {
xclass: 'Ext.event.publisher.ElementSize'
}
//<feature charts>
,seriesItemEvents: {
xclass: 'Ext.chart.series.ItemPublisher'
}
//</feature>
},
//<feature logger>
@ -15168,6 +15176,68 @@ Ext.ClassManager.addNameAlternateMappings({
],
"Ext.carousel.Infinite": [],
"Ext.carousel.Item": [],
"Ext.chart.AbstractChart": [],
"Ext.chart.CartesianChart": [
"Ext.chart.Chart"
],
"Ext.chart.Legend": [],
"Ext.chart.MarkerHolder": [],
"Ext.chart.Markers": [],
"Ext.chart.PolarChart": [],
"Ext.chart.SpaceFillingChart": [],
"Ext.chart.axis.Axis": [],
"Ext.chart.axis.Category": [],
"Ext.chart.axis.Numeric": [],
"Ext.chart.axis.Time": [],
"Ext.chart.axis.layout.CombineDuplicate": [],
"Ext.chart.axis.layout.Continuous": [],
"Ext.chart.axis.layout.Discrete": [],
"Ext.chart.axis.layout.Layout": [],
"Ext.chart.axis.segmenter.Names": [],
"Ext.chart.axis.segmenter.Numeric": [],
"Ext.chart.axis.segmenter.Segmenter": [],
"Ext.chart.axis.segmenter.Time": [],
"Ext.chart.axis.sprite.Axis": [],
"Ext.chart.grid.CircularGrid": [],
"Ext.chart.grid.HorizontalGrid": [],
"Ext.chart.grid.RadialGrid": [],
"Ext.chart.grid.VerticalGrid": [],
"Ext.chart.interactions.Abstract": [],
"Ext.chart.interactions.CrossZoom": [],
"Ext.chart.interactions.Crosshair": [],
"Ext.chart.interactions.ItemHighlight": [],
"Ext.chart.interactions.ItemInfo": [],
"Ext.chart.interactions.PanZoom": [],
"Ext.chart.interactions.Rotate": [],
"Ext.chart.interactions.RotatePie3D": [],
"Ext.chart.label.Callout": [],
"Ext.chart.label.Label": [],
"Ext.chart.series.Area": [],
"Ext.chart.series.Bar": [],
"Ext.chart.series.CandleStick": [],
"Ext.chart.series.Cartesian": [],
"Ext.chart.series.Gauge": [],
"Ext.chart.series.ItemPublisher": [],
"Ext.chart.series.Line": [],
"Ext.chart.series.Pie": [],
"Ext.chart.series.Pie3D": [],
"Ext.chart.series.Polar": [],
"Ext.chart.series.Radar": [],
"Ext.chart.series.Scatter": [],
"Ext.chart.series.Series": [],
"Ext.chart.series.StackedCartesian": [],
"Ext.chart.series.sprite.Aggregative": [],
"Ext.chart.series.sprite.Area": [],
"Ext.chart.series.sprite.Bar": [],
"Ext.chart.series.sprite.CandleStick": [],
"Ext.chart.series.sprite.Cartesian": [],
"Ext.chart.series.sprite.Line": [],
"Ext.chart.series.sprite.Pie3DPart": [],
"Ext.chart.series.sprite.PieSlice": [],
"Ext.chart.series.sprite.Polar": [],
"Ext.chart.series.sprite.Radar": [],
"Ext.chart.series.sprite.Scatter": [],
"Ext.chart.series.sprite.StackedCartesian": [],
"Ext.data.ArrayStore": [],
"Ext.data.Batch": [],
"Ext.data.Connection": [],
@ -15445,6 +15515,47 @@ Ext.ClassManager.addNameAlternateMappings({
"Ext.dom.CompositeElement": [
"Ext.CompositeElement"
],
"Ext.draw.Animator": [],
"Ext.draw.Color": [],
"Ext.draw.Component": [],
"Ext.draw.Draw": [],
"Ext.draw.LimitedCache": [],
"Ext.draw.Matrix": [],
"Ext.draw.Path": [],
"Ext.draw.SegmentTree": [],
"Ext.draw.Solver": [],
"Ext.draw.Surface": [],
"Ext.draw.TextMeasurer": [],
"Ext.draw.TimingFunctions": [],
"Ext.draw.engine.Canvas": [],
"Ext.draw.engine.Svg": [],
"Ext.draw.engine.SvgContext": [],
"Ext.draw.engine.SvgContext.Gradient": [],
"Ext.draw.engine.SvgExporter": [],
"Ext.draw.gradient.Gradient": [],
"Ext.draw.gradient.GradientDefinition": [],
"Ext.draw.gradient.Linear": [],
"Ext.draw.gradient.Radial": [],
"Ext.draw.modifier.Animation": [],
"Ext.draw.modifier.Highlight": [],
"Ext.draw.modifier.Modifier": [],
"Ext.draw.modifier.Target": [],
"Ext.draw.sprite.AnimationParser": [],
"Ext.draw.sprite.Arc": [],
"Ext.draw.sprite.AttributeDefinition": [],
"Ext.draw.sprite.AttributeParser": [],
"Ext.draw.sprite.Circle": [],
"Ext.draw.sprite.Composite": [],
"Ext.draw.sprite.Ellipse": [],
"Ext.draw.sprite.EllipticalArc": [],
"Ext.draw.sprite.Image": [],
"Ext.draw.sprite.Instancing": [],
"Ext.draw.sprite.Line": [],
"Ext.draw.sprite.Path": [],
"Ext.draw.sprite.Rect": [],
"Ext.draw.sprite.Sector": [],
"Ext.draw.sprite.Sprite": [],
"Ext.draw.sprite.Text": [],
"Ext.event.Controller": [],
"Ext.event.Dispatcher": [],
"Ext.event.Dom": [],
@ -15835,6 +15946,153 @@ Ext.ClassManager.addNameAliasMappings({
],
"Ext.carousel.Infinite": [],
"Ext.carousel.Item": [],
"Ext.chart.AbstractChart": [],
"Ext.chart.CartesianChart": [
"Ext.chart.Chart",
"widget.chart"
],
"Ext.chart.Legend": [
"widget.legend"
],
"Ext.chart.MarkerHolder": [],
"Ext.chart.Markers": [],
"Ext.chart.PolarChart": [
"widget.polar"
],
"Ext.chart.SpaceFillingChart": [
"widget.spacefilling"
],
"Ext.chart.axis.Axis": [
"widget.axis"
],
"Ext.chart.axis.Category": [
"axis.category"
],
"Ext.chart.axis.Numeric": [
"axis.numeric"
],
"Ext.chart.axis.Time": [
"axis.time"
],
"Ext.chart.axis.layout.CombineDuplicate": [
"axisLayout.combineDuplicate"
],
"Ext.chart.axis.layout.Continuous": [
"axisLayout.continuous"
],
"Ext.chart.axis.layout.Discrete": [
"axisLayout.discrete"
],
"Ext.chart.axis.layout.Layout": [],
"Ext.chart.axis.segmenter.Names": [
"segmenter.names"
],
"Ext.chart.axis.segmenter.Numeric": [
"segmenter.numeric"
],
"Ext.chart.axis.segmenter.Segmenter": [],
"Ext.chart.axis.segmenter.Time": [
"segmenter.time"
],
"Ext.chart.axis.sprite.Axis": [],
"Ext.chart.grid.CircularGrid": [
"grid.circular"
],
"Ext.chart.grid.HorizontalGrid": [
"grid.horizontal"
],
"Ext.chart.grid.RadialGrid": [
"grid.radial"
],
"Ext.chart.grid.VerticalGrid": [
"grid.vertical"
],
"Ext.chart.interactions.Abstract": [
"widget.interaction"
],
"Ext.chart.interactions.CrossZoom": [
"interaction.crosszoom"
],
"Ext.chart.interactions.Crosshair": [
"interaction.crosshair"
],
"Ext.chart.interactions.ItemHighlight": [
"interaction.itemhighlight"
],
"Ext.chart.interactions.ItemInfo": [
"interaction.iteminfo"
],
"Ext.chart.interactions.PanZoom": [
"interaction.panzoom"
],
"Ext.chart.interactions.Rotate": [
"interaction.rotate"
],
"Ext.chart.interactions.RotatePie3D": [
"interaction.rotatePie3d"
],
"Ext.chart.label.Callout": [],
"Ext.chart.label.Label": [],
"Ext.chart.series.Area": [
"series.area"
],
"Ext.chart.series.Bar": [
"series.bar"
],
"Ext.chart.series.CandleStick": [
"series.candlestick"
],
"Ext.chart.series.Cartesian": [],
"Ext.chart.series.Gauge": [
"series.gauge"
],
"Ext.chart.series.ItemPublisher": [],
"Ext.chart.series.Line": [
"series.line"
],
"Ext.chart.series.Pie": [
"series.pie"
],
"Ext.chart.series.Pie3D": [
"series.pie3d"
],
"Ext.chart.series.Polar": [],
"Ext.chart.series.Radar": [
"series.radar"
],
"Ext.chart.series.Scatter": [
"series.scatter"
],
"Ext.chart.series.Series": [],
"Ext.chart.series.StackedCartesian": [],
"Ext.chart.series.sprite.Aggregative": [],
"Ext.chart.series.sprite.Area": [
"sprite.areaSeries"
],
"Ext.chart.series.sprite.Bar": [
"sprite.barSeries"
],
"Ext.chart.series.sprite.CandleStick": [
"sprite.candlestickSeries"
],
"Ext.chart.series.sprite.Cartesian": [],
"Ext.chart.series.sprite.Line": [
"sprite.lineSeries"
],
"Ext.chart.series.sprite.Pie3DPart": [
"sprite.pie3dPart"
],
"Ext.chart.series.sprite.PieSlice": [
"sprite.pieslice"
],
"Ext.chart.series.sprite.Polar": [],
"Ext.chart.series.sprite.Radar": [
"sprite.radar"
],
"Ext.chart.series.sprite.Scatter": [
"sprite.scatterSeries"
],
"Ext.chart.series.sprite.StackedCartesian": [],
"Ext.data.ArrayStore": [
"store.array"
],
@ -16094,6 +16352,83 @@ Ext.ClassManager.addNameAliasMappings({
"direct.transaction"
],
"Ext.dom.CompositeElement": [],
"Ext.draw.Animator": [],
"Ext.draw.Color": [],
"Ext.draw.Component": [
"widget.draw"
],
"Ext.draw.Draw": [],
"Ext.draw.LimitedCache": [],
"Ext.draw.Matrix": [],
"Ext.draw.Path": [],
"Ext.draw.SegmentTree": [],
"Ext.draw.Solver": [],
"Ext.draw.Surface": [
"widget.surface"
],
"Ext.draw.TextMeasurer": [],
"Ext.draw.TimingFunctions": [],
"Ext.draw.engine.Canvas": [],
"Ext.draw.engine.Svg": [],
"Ext.draw.engine.SvgContext": [],
"Ext.draw.engine.SvgContext.Gradient": [],
"Ext.draw.engine.SvgExporter": [],
"Ext.draw.gradient.Gradient": [],
"Ext.draw.gradient.GradientDefinition": [],
"Ext.draw.gradient.Linear": [],
"Ext.draw.gradient.Radial": [],
"Ext.draw.modifier.Animation": [
"modifier.animation"
],
"Ext.draw.modifier.Highlight": [
"modifier.highlight"
],
"Ext.draw.modifier.Modifier": [],
"Ext.draw.modifier.Target": [
"modifier.target"
],
"Ext.draw.sprite.AnimationParser": [],
"Ext.draw.sprite.Arc": [
"sprite.arc"
],
"Ext.draw.sprite.AttributeDefinition": [],
"Ext.draw.sprite.AttributeParser": [],
"Ext.draw.sprite.Circle": [
"sprite.circle"
],
"Ext.draw.sprite.Composite": [
"sprite.composite"
],
"Ext.draw.sprite.Ellipse": [
"sprite.ellipse"
],
"Ext.draw.sprite.EllipticalArc": [
"sprite.ellipticalArc"
],
"Ext.draw.sprite.Image": [
"sprite.image"
],
"Ext.draw.sprite.Instancing": [
"sprite.instancing"
],
"Ext.draw.sprite.Line": [
"sprite.line"
],
"Ext.draw.sprite.Path": [
"sprite.path"
],
"Ext.draw.sprite.Rect": [
"sprite.rect"
],
"Ext.draw.sprite.Sector": [
"sprite.sector"
],
"Ext.draw.sprite.Sprite": [
"sprite.sprite"
],
"Ext.draw.sprite.Text": [
"sprite.text"
],
"Ext.event.Controller": [],
"Ext.event.Dispatcher": [],
"Ext.event.Dom": [],

File diff suppressed because one or more lines are too long

1313
vendor/touch/src/chart/AbstractChart.js vendored Normal file

File diff suppressed because it is too large Load diff

304
vendor/touch/src/chart/CartesianChart.js vendored Normal file
View file

@ -0,0 +1,304 @@
/**
* @class Ext.chart.CartesianChart
* @extends Ext.chart.AbstractChart
*
* Represents a chart that uses cartesian coordinates.
* A cartesian chart have two directions, X direction and Y direction.
* The series and axes are coordinated along these directions.
* By default the x direction is horizontal and y direction is vertical,
* You can swap the by setting {@link #flipXY} config to `true`.
*
* Cartesian series often treats x direction an y direction differently.
* In most cases, data on x direction are assumed to be monotonically increasing.
* Based on this property, cartesian series can be trimmed and summarized properly
* to gain a better performance.
*
* @xtype chart
*/
Ext.define('Ext.chart.CartesianChart', {
extend: 'Ext.chart.AbstractChart',
alternateClassName: 'Ext.chart.Chart',
requires: ['Ext.chart.grid.HorizontalGrid', 'Ext.chart.grid.VerticalGrid'],
config: {
/**
* @cfg {Boolean} flipXY Flip the direction of X and Y axis.
* If flipXY is true, the X axes will be vertical and Y axes will be horizontal.
*/
flipXY: false,
innerRegion: [0, 0, 1, 1]
},
xtype: 'chart',
alias: 'Ext.chart.Chart',
getDirectionForAxis: function (position) {
var flipXY = this.getFlipXY();
if (position === 'left' || position === 'right') {
if (flipXY) {
return 'X';
} else {
return 'Y';
}
} else {
if (flipXY) {
return 'Y';
} else {
return 'X';
}
}
},
/**
* Layout the axes and series.
*/
performLayout: function () {
try {
this.resizing++;
this.callSuper();
this.suspendThicknessChanged();
var me = this,
axes = me.getAxes(), axis,
seriesList = me.getSeries(), series,
axisSurface, thickness,
size = me.element.getSize(),
width = size.width,
height = size.height,
insetPadding = me.getInsetPadding(),
innerPadding = me.getInnerPadding(),
surface,
shrinkBox = {
top: insetPadding.top,
left: insetPadding.left,
right: insetPadding.right,
bottom: insetPadding.bottom
},
gridSurface,
mainRegion, innerWidth, innerHeight,
elements, floating, matrix, i, ln,
flipXY = me.getFlipXY();
if (width <= 0 || height <= 0) {
return;
}
for (i = 0; i < axes.length; i++) {
axis = axes[i];
axisSurface = axis.getSurface();
floating = axis.getStyle && axis.getStyle() && axis.getStyle().floating;
thickness = axis.getThickness();
switch (axis.getPosition()) {
case 'top':
axisSurface.setRegion([0, shrinkBox.top, width, thickness]);
break;
case 'bottom':
axisSurface.setRegion([0, height - (shrinkBox.bottom + thickness), width, thickness]);
break;
case 'left':
axisSurface.setRegion([shrinkBox.left, 0, thickness, height]);
break;
case 'right':
axisSurface.setRegion([width - (shrinkBox.right + thickness), 0, thickness, height]);
break;
}
if (!floating) {
shrinkBox[axis.getPosition()] += thickness;
}
}
width -= shrinkBox.left + shrinkBox.right;
height -= shrinkBox.top + shrinkBox.bottom;
mainRegion = [shrinkBox.left, shrinkBox.top, width, height];
shrinkBox.left += innerPadding.left;
shrinkBox.top += innerPadding.top;
shrinkBox.right += innerPadding.right;
shrinkBox.bottom += innerPadding.bottom;
innerWidth = width - innerPadding.left - innerPadding.right;
innerHeight = height - innerPadding.top - innerPadding.bottom;
me.setInnerRegion([shrinkBox.left, shrinkBox.top, innerWidth, innerHeight]);
if (innerWidth <= 0 || innerHeight <= 0) {
return;
}
me.setMainRegion(mainRegion);
me.getSurface('main').setRegion(mainRegion);
for (i = 0, ln = me.surfaceMap.grid && me.surfaceMap.grid.length; i < ln; i++) {
gridSurface = me.surfaceMap.grid[i];
gridSurface.setRegion(mainRegion);
gridSurface.matrix.set(1, 0, 0, 1, innerPadding.left, innerPadding.top);
gridSurface.matrix.inverse(gridSurface.inverseMatrix);
}
for (i = 0; i < axes.length; i++) {
axis = axes[i];
axisSurface = axis.getSurface();
matrix = axisSurface.matrix;
elements = matrix.elements;
switch (axis.getPosition()) {
case 'top':
case 'bottom':
elements[4] = shrinkBox.left;
axis.setLength(innerWidth);
break;
case 'left':
case 'right':
elements[5] = shrinkBox.top;
axis.setLength(innerHeight);
break;
}
axis.updateTitleSprite();
matrix.inverse(axisSurface.inverseMatrix);
}
for (i = 0, ln = seriesList.length; i < ln; i++) {
series = seriesList[i];
surface = series.getSurface();
surface.setRegion(mainRegion);
if (flipXY) {
surface.matrix.set(0, -1, 1, 0, innerPadding.left, innerHeight + innerPadding.top);
} else {
surface.matrix.set(1, 0, 0, -1, innerPadding.left, innerHeight + innerPadding.top);
}
surface.matrix.inverse(surface.inverseMatrix);
series.getOverlaySurface().setRegion(mainRegion);
}
me.redraw();
me.onPlaceWatermark();
} finally {
this.resizing--;
this.resumeThicknessChanged();
}
},
redraw: function () {
var me = this,
series = me.getSeries(),
axes = me.getAxes(),
region = me.getMainRegion(),
innerWidth, innerHeight,
innerPadding = me.getInnerPadding(),
left, right, top, bottom, i, j,
sprites, xRange, yRange, isSide, attr,
axisX, axisY, range, visibleRange,
flipXY = me.getFlipXY(),
sprite, zIndex, zBase = 1000,
markers, markerCount, markerIndex, markerSprite, markerZIndex;
if (!region) {
return;
}
innerWidth = region[2] - innerPadding.left - innerPadding.right;
innerHeight = region[3] - innerPadding.top - innerPadding.bottom;
for (i = 0; i < series.length; i++) {
if ((axisX = series[i].getXAxis())) {
visibleRange = axisX.getVisibleRange();
xRange = axisX.getRange();
xRange = [xRange[0] + (xRange[1] - xRange[0]) * visibleRange[0], xRange[0] + (xRange[1] - xRange[0]) * visibleRange[1]];
} else {
xRange = series[i].getXRange();
}
if ((axisY = series[i].getYAxis())) {
visibleRange = axisY.getVisibleRange();
yRange = axisY.getRange();
yRange = [yRange[0] + (yRange[1] - yRange[0]) * visibleRange[0], yRange[0] + (yRange[1] - yRange[0]) * visibleRange[1]];
} else {
yRange = series[i].getYRange();
}
left = xRange[0];
right = xRange[1];
top = yRange[0];
bottom = yRange[1];
attr = {
visibleMinX: xRange[0],
visibleMaxX: xRange[1],
visibleMinY: yRange[0],
visibleMaxY: yRange[1],
innerWidth: innerWidth,
innerHeight: innerHeight,
flipXY: flipXY
};
sprites = series[i].getSprites();
for (j = 0; j < sprites.length; j++) {
// All the series now share the same surface, so we must assign
// the sprites a zIndex that depends on the index of their series.
sprite = sprites[j];
zIndex = (sprite.attr.zIndex || 0);
if (zIndex < zBase) {
// Set the sprite's zIndex
zIndex += (i+1) * 100 + zBase;
sprite.attr.zIndex = zIndex;
// Iterate through its marker sprites to do the same.
markers = sprite.boundMarkers;
if (markers) {
markerCount = (markers.items ? markers.items.length : 0);
if (markerCount) {
for (markerIndex = 0; markerIndex < markerCount; markerIndex++) {
markerSprite = markers.items[markerIndex];
markerZIndex = (markerSprite.attr.zIndex || 0);
if (markerZIndex == Number.MAX_VALUE) {
markerSprite.attr.zIndex = zIndex;
} else {
if (markerZIndex < zBase) {
markerSprite.attr.zIndex = zIndex + markerZIndex;
}
}
}
}
}
}
sprite.setAttributes(attr, true);
}
}
for (i = 0; i < axes.length; i++) {
isSide = axes[i].isSide();
sprites = axes[i].getSprites();
range = axes[i].getRange();
visibleRange = axes[i].getVisibleRange();
attr = {
dataMin: range[0],
dataMax: range[1],
visibleMin: visibleRange[0],
visibleMax: visibleRange[1]
};
if (isSide) {
attr.length = innerHeight;
attr.startGap = innerPadding.bottom;
attr.endGap = innerPadding.top;
} else {
attr.length = innerWidth;
attr.startGap = innerPadding.left;
attr.endGap = innerPadding.right;
}
for (j = 0; j < sprites.length; j++) {
sprites[j].setAttributes(attr, true);
}
}
me.renderFrame();
me.callSuper(arguments);
},
onPlaceWatermark: function () {
var region0 = this.element.getBox(),
region = this.getSurface ? this.getSurface('main').getRegion() : this.getItems().get(0).getRegion();
if (region) {
this.watermarkElement.setStyle({
right: Math.round(region0.width - (region[2] + region[0])) + 'px',
bottom: Math.round(region0.height - (region[3] + region[1])) + 'px'
});
}
}
});

147
vendor/touch/src/chart/Legend.js vendored Normal file
View file

@ -0,0 +1,147 @@
/**
* @class Ext.chart.Legend
* @extends Ext.dataview.DataView
*
* A default legend for charts.
*
* @example preview
* var chart = new Ext.chart.Chart({
* animate: true,
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* legend: {
* position: 'bottom'
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['data1'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* grid: true,
* minimum: 0
* }, {
* type: 'category',
* position: 'bottom',
* fields: ['name'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* }
* }],
* series: [{
* type: 'area',
* title: ['Data1', 'Data2', 'Data3'],
* subStyle: {
* fill: ['blue', 'green', 'red']
* },
* xField: 'name',
* yField: ['data1', 'data2', 'data3']
*
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*/
Ext.define("Ext.chart.Legend", {
xtype: 'legend',
extend: "Ext.dataview.DataView",
config: {
itemTpl: [
"<span class=\"x-legend-item-marker {[values.disabled?\'x-legend-inactive\':\'\']}\" style=\"background:{mark};\"></span>{name}"
],
baseCls: 'x-legend',
padding: 5,
disableSelection: true,
inline: true,
/**
* @cfg {String} position
* @deprecated Use `docked` instead.
* Delegates to `docked`
*/
position: null,
/**
* @cfg {Boolean} toggleable 'true' if the series items in the legend can be toggled on and off.
*/
toggleable: true,
docked: 'top',
horizontalHeight: 48,
verticalWidth: 150
},
constructor: function () {
this.callSuper(arguments);
var scroller = this.getScrollable().getScroller(),
onDrag = scroller.onDrag;
scroller.onDrag = function (e) {
e.stopPropagation();
onDrag.call(this, e);
};
},
doSetDocked: function (docked) {
this.callSuper(arguments);
if (docked === 'top' || docked === 'bottom') {
this.setLayout({type: 'hbox', pack: 'center'});
this.setInline(true);
// TODO: Remove this when possible
this.setWidth(null);
this.setHeight(this.getHorizontalHeight());
if (this.getScrollable()) {
this.setScrollable({direction: 'horizontal'});
}
} else {
this.setLayout({pack: 'center'});
this.setInline(false);
// TODO: Remove this when possible
this.setWidth(this.getVerticalWidth());
this.setHeight(null);
if (this.getScrollable()) {
this.setScrollable({direction: 'vertical'});
}
}
},
setScrollable: function (scrollable) {
this.callSuper(arguments);
if (scrollable === true) {
if (this.getDocked() === 'top' || this.getDocked() === 'bottom') {
this.setScrollable({direction: 'horizontal'});
} else if (this.getDocked() === 'left' || this.getDocked() === 'right') {
this.setScrollable({direction: 'vertical'});
}
}
},
setPosition: function (position) {
this.setDocked(position);
},
getPosition: function () {
return this.getDocked();
},
onItemTap: function (container, target, index, e) {
this.callSuper(arguments);
if(this.getToggleable()) {
var me = this,
store = me.getStore(),
record = store && store.getAt(index);
record.beginEdit();
record.set('disabled', !record.get('disabled'));
record.commit();
}
}
});

109
vendor/touch/src/chart/MarkerHolder.js vendored Normal file
View file

@ -0,0 +1,109 @@
/**
* @class Ext.chart.MarkerHolder
* @extends Ext.mixin.Mixin
*
* Mixin that provides the functionality to place markers.
*/
Ext.define('Ext.chart.MarkerHolder', {
extend: 'Ext.mixin.Mixin',
mixinConfig: {
id: 'markerHolder',
hooks: {
constructor: 'constructor',
preRender: 'preRender'
}
},
isMarkerHolder: true,
constructor: function () {
this.boundMarkers = {};
this.cleanRedraw = false;
},
/**
*
* @param {String} name
* @param {Ext.chart.Markers} marker
*/
bindMarker: function (name, marker) {
if (marker) {
if (!this.boundMarkers[name]) {
this.boundMarkers[name] = [];
}
Ext.Array.include(this.boundMarkers[name], marker);
}
},
getBoundMarker: function (name) {
return this.boundMarkers[name];
},
preRender: function () {
var boundMarkers = this.boundMarkers, boundMarkersItem,
name, i, ln, id = this.getId(),
parent = this.getParent(),
matrix = this.surfaceMatrix ? this.surfaceMatrix.set(1, 0, 0, 1, 0, 0) : (this.surfaceMatrix = new Ext.draw.Matrix());
this.cleanRedraw = !this.attr.dirty;
if (!this.cleanRedraw) {
for (name in this.boundMarkers) {
if (boundMarkers[name]) {
for (boundMarkersItem = boundMarkers[name], i = 0, ln = boundMarkersItem.length; i < ln; i++) {
boundMarkersItem[i].clear(id);
}
}
}
}
while (parent && parent.attr && parent.attr.matrix) {
matrix.prependMatrix(parent.attr.matrix);
parent = parent.getParent();
}
matrix.prependMatrix(parent.matrix);
this.surfaceMatrix = matrix;
this.inverseSurfaceMatrix = matrix.inverse(this.inverseSurfaceMatrix);
},
putMarker: function (name, markerAttr, index, canonical, keepRevision) {
var boundMarkersItem, i, ln, id = this.getId();
if (this.boundMarkers[name]) {
for (boundMarkersItem = this.boundMarkers[name], i = 0, ln = boundMarkersItem.length; i < ln; i++) {
boundMarkersItem[i].putMarkerFor(id, markerAttr, index, canonical);
}
}
},
getMarkerBBox: function (name, index, isWithoutTransform) {
var id = this.getId(),
left = Infinity,
right = -Infinity,
top = Infinity,
bottom = -Infinity,
bbox, boundMarker, i, ln;
if (this.boundMarkers[name]) {
for (boundMarker = this.boundMarkers[name], i = 0, ln = boundMarker.length; i < ln; i++) {
bbox = boundMarker[i].getMarkerBBoxFor(id, index, isWithoutTransform);
if (left > bbox.x) {
left = bbox.x;
}
if (right < bbox.x + bbox.width) {
right = bbox.x + bbox.width;
}
if (top > bbox.y) {
top = bbox.y;
}
if (bottom < bbox.y + bbox.height) {
bottom = bbox.y + bbox.height;
}
}
}
return {
x: left,
y: top,
width: right - left,
height: bottom - top
};
}
});

103
vendor/touch/src/chart/Markers.js vendored Normal file
View file

@ -0,0 +1,103 @@
/**
* @class Ext.chart.Markers
* @extends Ext.draw.sprite.Instancing
*
* Marker sprite. A specialized version of instancing sprite that groups instances.
* Putting a marker is grouped by its category id. Clearing removes that category.
*/
Ext.define('Ext.chart.Markers', {
extend: 'Ext.draw.sprite.Instancing',
revisions: 0,
constructor: function () {
this.callSuper(arguments);
this.map = {};
this.revisions = {};
},
/**
* Clear the markers in the category
* @param {String} category
*/
clear: function (category) {
category = category || 'default';
if (!(category in this.revisions)) {
this.revisions[category] = 1;
} else {
this.revisions[category]++;
}
},
/**
* Put a marker in the category with additional
* attributes.
* @param {String} category
* @param {Object} markerAttr
* @param {String|Number} index
* @param {Boolean} [canonical]
* @param {Boolean} [keepRevision]
*/
putMarkerFor: function (category, markerAttr, index, canonical, keepRevision) {
category = category || 'default';
var me = this,
map = me.map[category] || (me.map[category] = {});
if (index in map) {
me.setAttributesFor(map[index], markerAttr, canonical);
} else {
map[index] = me.instances.length;
me.createInstance(markerAttr, null, canonical);
}
me.instances[map[index]].category = category;
if (!keepRevision) {
me.instances[map[index]].revision = me.revisions[category] || (me.revisions[category] = 1);
}
},
/**
*
* @param {String} category
* @param {Mixed} index
* @param {Boolean} [isWithoutTransform]
*/
getMarkerBBoxFor: function (category, index, isWithoutTransform) {
if (category in this.map) {
if (index in this.map[category]) {
return this.getBBoxFor(this.map[category][index], isWithoutTransform);
}
}
return {
x: Infinity,
y: Infinity,
width: -Infinity,
height: -Infinity
};
},
getBBox: function () { return null; },
render: function (surface, ctx, clipRegion) {
var me = this,
revisions = me.revisions,
mat = me.attr.matrix,
template = me.getTemplate(),
originalAttr = template.attr,
instances = me.instances,
i, ln = me.instances.length;
mat.toContext(ctx);
template.preRender(surface, ctx, clipRegion);
template.useAttributes(ctx);
for (i = 0; i < ln; i++) {
if (instances[i].hidden || instances[i].revision !== revisions[instances[i].category]) {
continue;
}
ctx.save();
template.attr = instances[i];
template.applyTransformations();
template.useAttributes(ctx);
template.render(surface, ctx, clipRegion);
ctx.restore();
}
template.attr = originalAttr;
}
});

164
vendor/touch/src/chart/PolarChart.js vendored Normal file
View file

@ -0,0 +1,164 @@
/**
* @class Ext.chart.PolarChart
* @extends Ext.chart.AbstractChart
*
* Creates a chart that uses polar coordinates.
*/
Ext.define('Ext.chart.PolarChart', {
requires: [
'Ext.chart.grid.CircularGrid',
'Ext.chart.grid.RadialGrid'
],
extend: 'Ext.chart.AbstractChart',
xtype: 'polar',
config: {
/**
* @cfg {Array} center Determines the center of the polar chart.
* Updated when the chart performs layout.
*/
center: [0, 0],
/**
* @cfg {Number} radius Determines the radius of the polar chart.
* Updated when the chart performs layout.
*/
radius: 0
},
getDirectionForAxis: function (position) {
if (position === 'radial') {
return 'Y';
} else {
return 'X';
}
},
applyCenter: function (center, oldCenter) {
if (oldCenter && center[0] === oldCenter[0] && center[1] === oldCenter[1]) {
return;
}
return [+center[0], +center[1]];
},
updateCenter: function (center) {
var me = this,
axes = me.getAxes(), axis,
series = me.getSeries(), seriesItem,
i, ln;
for (i = 0, ln = axes.length; i < ln; i++) {
axis = axes[i];
axis.setCenter(center);
}
for (i = 0, ln = series.length; i < ln; i++) {
seriesItem = series[i];
seriesItem.setCenter(center);
}
},
updateRadius: function (radius) {
var me = this,
axes = me.getAxes(), axis,
series = me.getSeries(), seriesItem,
i, ln;
for (i = 0, ln = axes.length; i < ln; i++) {
axis = axes[i];
axis.setMinimum(0);
axis.setLength(radius);
axis.getSprites();
}
for (i = 0, ln = series.length; i < ln; i++) {
seriesItem = series[i];
seriesItem.setRadius(radius);
}
},
doSetSurfaceRegion: function (surface, region) {
var mainRegion = this.getMainRegion();
surface.setRegion(region);
surface.matrix.set(1, 0, 0, 1, mainRegion[0] - region[0], mainRegion[1] - region[1]);
surface.inverseMatrix.set(1, 0, 0, 1, region[0] - mainRegion[0], region[1] - mainRegion[1]);
},
performLayout: function () {
try {
this.resizing++;
this.callSuper();
var me = this,
size = me.element.getSize(),
fullRegion = [0, 0, size.width, size.height],
inset = me.getInsetPadding(),
inner = me.getInnerPadding(),
left = inset.left,
top = inset.top,
width = size.width - left - inset.right,
height = size.height - top - inset.bottom,
region = [inset.left, inset.top, width, height],
innerWidth = width - inner.left - inner.right,
innerHeight = height - inner.top - inner.bottom,
center = [innerWidth * 0.5 + inner.left, innerHeight * 0.5 + inner.top],
radius = Math.min(innerWidth, innerHeight) * 0.5,
axes = me.getAxes(), axis,
series = me.getSeries(), seriesItem,
i, ln;
me.setMainRegion(region);
for (i = 0, ln = series.length; i < ln; i++) {
seriesItem = series[i];
me.doSetSurfaceRegion(seriesItem.getSurface(), region);
me.doSetSurfaceRegion(seriesItem.getOverlaySurface(), fullRegion);
}
me.doSetSurfaceRegion(me.getSurface(), fullRegion);
for (i = 0, ln = me.surfaceMap.grid && me.surfaceMap.grid.length; i < ln; i++) {
me.doSetSurfaceRegion(me.surfaceMap.grid[i], fullRegion);
}
for (i = 0, ln = axes.length; i < ln; i++) {
axis = axes[i];
me.doSetSurfaceRegion(axis.getSurface(), fullRegion);
}
me.setRadius(radius);
me.setCenter(center);
me.redraw();
} finally {
this.resizing--;
}
},
getEventXY: function (e) {
e = (e.changedTouches && e.changedTouches[0]) || e.event || e.browserEvent || e;
var me = this,
xy = me.element.getXY(),
padding = me.getInsetPadding();
return [e.pageX - xy[0] - padding.left, e.pageY - xy[1] - padding.top];
},
redraw: function () {
var me = this,
axes = me.getAxes(), axis,
series = me.getSeries(), seriesItem,
i, ln;
for (i = 0, ln = axes.length; i < ln; i++) {
axis = axes[i];
axis.getSprites();
}
for (i = 0, ln = series.length; i < ln; i++) {
seriesItem = series[i];
seriesItem.getSprites();
}
me.renderFrame();
me.callSuper(arguments);
}
});

View file

@ -0,0 +1,58 @@
/**
* @class Ext.chart.SpaceFillingChart
* @extends Ext.chart.AbstractChart
*
* Creates a chart that fills the entire area of the chart.
* e.g. Gauge Charts
*/
Ext.define('Ext.chart.SpaceFillingChart', {
extend: 'Ext.chart.AbstractChart',
xtype: 'spacefilling',
config: {
},
performLayout: function () {
try {
this.resizing++;
this.callSuper();
var me = this,
size = me.element.getSize(),
series = me.getSeries(), seriesItem,
padding = me.getInsetPadding(),
width = size.width - padding.left - padding.right,
height = size.height - padding.top - padding.bottom,
region = [padding.left, padding.top, width, height],
fullRegion = [0, 0, size.width, size.height],
i, ln;
me.getSurface().setRegion(region);
me.setMainRegion(region);
for (i = 0, ln = series.length; i < ln; i++) {
seriesItem = series[i];
seriesItem.getSurface().setRegion(region);
seriesItem.setRegion(region);
seriesItem.getOverlaySurface().setRegion(fullRegion);
}
me.redraw();
} finally {
this.resizing--;
}
},
redraw: function () {
var me = this,
series = me.getSeries(), seriesItem,
i, ln;
for (i = 0, ln = series.length; i < ln; i++) {
seriesItem = series[i];
seriesItem.getSprites();
}
me.renderFrame();
me.callSuper(arguments);
}
});

890
vendor/touch/src/chart/axis/Axis.js vendored Normal file
View file

@ -0,0 +1,890 @@
/**
* @class Ext.chart.axis.Axis
*
* Defines axis for charts.
*
* Using the current model, the type of axis can be easily extended. By default, Sencha Touch provides three different
* types of axis:
*
* * **numeric** - the data attached with this axes are considered to be numeric and continuous.
* * **time** - the data attached with this axes are considered (or get converted into) date/time and they are continuous.
* * **category** - the data attached with this axes conforms a finite set. They will be evenly placed on the axis and displayed in the same form they were provided.
*
* The behavior of an axis can be easily changed by setting different types of axis layout and axis segmenter to the axis.
*
* Axis layout defines how the data points are placed. Using continuous layout, the data points will be distributed by
* the numeric value. Using discrete layout the data points will be spaced evenly. Furthermore, if you want to combine
* the data points with the duplicate values in a discrete layout, you should use combineDuplicate layout.
*
* Segmenter defines the way to segment data range. For example, if you have a Date-type data range from Jan 1, 1997 to
* Jan 1, 2017, the segmenter will segement the data range into years, months or days based on the current zooming
* level.
*
* It is possible to write custom axis layouts and segmenters to extends this behavior by simply implementing interfaces
* {@link Ext.chart.axis.layout.Layout} and {@link Ext.chart.axis.segmenter.Segmenter}.
*
* Here's an example for the axes part of a chart definition:
* An example of axis for a series (in this case for an area chart that has multiple layers of yFields) could be:
*
* axes: [{
* type: 'numeric',
* position: 'left',
* title: 'Number of Hits',
* grid: {
* odd: {
* opacity: 1,
* fill: '#ddd',
* stroke: '#bbb',
* lineWidth: 1
* }
* },
* minimum: 0
* }, {
* type: 'category',
* position: 'bottom',
* title: 'Month of the Year',
* grid: true,
* label: {
* rotate: {
* degrees: 315
* }
* }
* }]
*
* In this case we use a `numeric` axis for displaying the values of the Area series and a `category` axis for displaying the names of
* the store elements. The numeric axis is placed on the left of the screen, while the category axis is placed at the bottom of the chart.
* Both the category and numeric axes have `grid` set, which means that horizontal and vertical lines will cover the chart background. In the
* category axis the labels will be rotated so they can fit the space better.
*/
Ext.define('Ext.chart.axis.Axis', {
xtype: 'axis',
mixins: {
observable: 'Ext.mixin.Observable'
},
requires: [
'Ext.chart.axis.sprite.Axis',
'Ext.chart.axis.segmenter.*',
'Ext.chart.axis.layout.*'
],
config: {
/**
* @cfg {String} position
* Where to set the axis. Available options are `left`, `bottom`, `right`, `top`, `radial` and `angular`.
*/
position: 'bottom',
/**
* @cfg {Array} fields
* An array containing the names of the record fields which should be mapped along the axis.
* This is optional if the binding between series and fields is clear.
*/
fields: [],
/**
* @cfg {Object} label
*
* The label configuration object for the Axis. This object may include style attributes
* like `spacing`, `padding`, `font` that receives a string or number and
* returns a new string with the modified values.
*
* For more supported values, see the configurations for {@link Ext.chart.label.Label}.
*/
label: { x: 0, y: 0, textBaseline: 'middle', textAlign: 'center', fontSize: 12, fontFamily: 'Helvetica' },
/**
* @cfg {Object} grid
* The grid configuration object for the Axis style. Can contain `stroke` or `fill` attributes.
* Also may contain an `odd` or `even` property in which you only style things on odd or even rows.
* For example:
*
*
* grid {
* odd: {
* stroke: '#555'
* },
* even: {
* stroke: '#ccc'
* }
* }
*/
grid: false,
/**
* @cfg {Function} renderer Allows direct customisation of rendered axis sprites.
* @param {String} label The label.
* @param {Object|Ext.chart.axis.layout.Layout} layout The layout configuration used by the axis.
* @param {String} lastLabel The last label.
* @return {String} The label to display.
*/
renderer: null,
/**
* @protected
* @cfg {Ext.chart.AbstractChart} chart The Chart that the Axis is bound.
*/
chart: null,
/**
* @cfg {Object} style
* The style for the axis line and ticks.
* Refer to the {@link Ext.chart.axis.sprite.Axis}
*/
style: null,
/**
* @cfg {Number} titleMargin
* The margin around the axis title. Unlike CSS where the margin is added on all 4
* sides of an element, the `titleMargin` is the total space that is added horizontally
* for a vertical title and vertically for an horizontal title, with half the `titleMargin`
* being added on either side.
*/
titleMargin: 4,
/**
* @cfg {Object} background
* The background config for the axis surface.
*/
background: null,
/**
* @cfg {Number} minimum
* The minimum value drawn by the axis. If not set explicitly, the axis
* minimum will be calculated automatically.
*/
minimum: NaN,
/**
* @cfg {Number} maximum
* The maximum value drawn by the axis. If not set explicitly, the axis
* maximum will be calculated automatically.
*/
maximum: NaN,
/**
* @cfg {Number} minZoom
* The minimum zooming level for axis.
*/
minZoom: 1,
/**
* @cfg {Number} maxZoom
* The maximum zooming level for axis
*/
maxZoom: 10000,
/**
* @cfg {Object|Ext.chart.axis.layout.Layout} layout
* The axis layout config. See {@link Ext.chart.axis.layout.Layout}
*/
layout: 'continuous',
/**
* @cfg {Object|Ext.chart.axis.segmenter.Segmenter} segmenter
* The segmenter config. See {@link Ext.chart.axis.segmenter.Segmenter}
*/
segmenter: 'numeric',
/**
* @cfg {Boolean} hidden
* Indicate whether to hide the axis.
* If the axis is hidden, one of the axis line, ticks, labels or the title will be shown and
* no margin will be taken.
* The coordination mechanism works fine no matter if the axis is hidden.
*/
hidden: false,
/**
* @cfg {Number} majorTickSteps
* If `minimum` and `maximum` are specified it forces the number of major ticks to the specified value.
*/
majorTickSteps: false,
/**
* @cfg {Number} [minorTickSteps=0]
* The number of small ticks between two major ticks.
*/
minorTickSteps: false,
/**
* @private
* @cfg {Boolean} adjustMaximumByMajorUnit
* Will be supported soon.
*/
adjustMaximumByMajorUnit: false,
/**
* @private
* @cfg {Boolean} adjustMinimumByMajorUnit
* Will be supported soon.
*
*/
adjustMinimumByMajorUnit: false,
/**
* @cfg {String|Object} title
* The title for the Axis.
* If given a String, the text style of the title sprite will be set,
* otherwise the style will be set.
*/
title: { fontSize: 18, fontFamily: 'Helvetica'},
/**
* @cfg {Number} increment
* Given a minimum and maximum bound for the series to be rendered (that can be obtained
* automatically or by manually setting `minimum` and `maximum`) tick marks will be added
* on each `increment` from the minimum value to the maximum one.
*/
increment: 0.5,
/**
* @private
* @cfg {Number} length
* Length of the axis position. Equals to the size of inner region on the docking side of this axis.
* WARNING: Meant to be set automatically by chart. Do not set it manually.
*/
length: 0,
/**
* @private
* @cfg {Array} center
* Center of the polar axis.
* WARNING: Meant to be set automatically by chart. Do not set it manually.
*/
center: null,
/**
* @private
* @cfg {Number} radius
* Radius of the polar axis.
* WARNING: Meant to be set automatically by chart. Do not set it manually.
*/
radius: null,
/**
* @private
* @cfg {Number} rotation
* Rotation of the polar axis.
* WARNING: Meant to be set automatically by chart. Do not set it manually.
*/
rotation: null,
/**
* @cfg {Boolean} [labelInSpan]
* Draws the labels in the middle of the spans.
*/
labelInSpan: null,
/**
* @cfg {Array} visibleRange
* Specify the proportion of the axis to be rendered. The series bound to
* this axis will be synchronized and transformed.
*/
visibleRange: [0, 1],
/**
* @cfg {Boolean} needHighPrecision
* Indicates that the axis needs high precision surface implementation.
* See {@link Ext.draw.engine.Canvas#highPrecision}
*/
needHighPrecision: false
},
observableType: 'component',
titleOffset: 0,
animating: 0,
prevMin: 0,
prevMax: 1,
boundSeries: [],
sprites: null,
/**
* @private
* @property {Array} The full data range of the axis. Should not be set directly, clear it to `null` and use
* `getRange` to update.
*/
range: null,
xValues: [],
yValues: [],
applyRotation: function (rotation) {
var twoPie = Math.PI * 2;
return (rotation % twoPie + Math.PI) % twoPie - Math.PI;
},
updateRotation: function (rotation) {
var sprites = this.getSprites(),
position = this.getPosition();
if (!this.getHidden() && position === 'angular' && sprites[0]) {
sprites[0].setAttributes({
baseRotation: rotation
});
}
},
applyTitle: function (title, oldTitle) {
var surface;
if (Ext.isString(title)) {
title = { text: title };
}
if (!oldTitle) {
oldTitle = Ext.create('sprite.text', title);
if ((surface = this.getSurface())) {
surface.add(oldTitle);
}
} else {
oldTitle.setAttributes(title);
}
return oldTitle;
},
constructor: function (config) {
var me = this;
me.sprites = [];
this.labels = [];
this.initConfig(config);
me.getId();
me.mixins.observable.constructor.apply(me, arguments);
Ext.ComponentManager.register(me);
},
/**
* @private
* @return {String}
*/
getAlignment: function () {
switch (this.getPosition()) {
case 'left':
case 'right':
return 'vertical';
case 'top':
case 'bottom':
return 'horizontal';
case 'radial':
return 'radial';
case 'angular':
return 'angular';
}
},
/**
* @private
* @return {String}
*/
getGridAlignment: function () {
switch (this.getPosition()) {
case 'left':
case 'right':
return 'horizontal';
case 'top':
case 'bottom':
return 'vertical';
case 'radial':
return 'circular';
case 'angular':
return "radial";
}
},
/**
* @private
* Get the surface for drawing the series sprites
*/
getSurface: function () {
if (!this.surface) {
var chart = this.getChart();
if (!chart) {
return null;
}
var surface = this.surface = chart.getSurface(this.getId(), 'axis'),
gridSurface = this.gridSurface = chart.getSurface('main'),
sprites = this.getSprites(),
sprite = sprites[0],
grid = this.getGrid(),
gridAlignment = this.getGridAlignment(),
gridSprite;
if (grid) {
gridSprite = this.gridSpriteEven = new Ext.chart.Markers();
gridSprite.setTemplate({xclass: 'grid.' + gridAlignment});
if (Ext.isObject(grid)) {
gridSprite.getTemplate().setAttributes(grid);
if (Ext.isObject(grid.even)) {
gridSprite.getTemplate().setAttributes(grid.even);
}
}
gridSurface.add(gridSprite);
sprite.bindMarker(gridAlignment + '-even', gridSprite);
gridSprite = this.gridSpriteOdd = new Ext.chart.Markers();
gridSprite.setTemplate({xclass: 'grid.' + gridAlignment});
if (Ext.isObject(grid)) {
gridSprite.getTemplate().setAttributes(grid);
if (Ext.isObject(grid.odd)) {
gridSprite.getTemplate().setAttributes(grid.odd);
}
}
gridSurface.add(gridSprite);
sprite.bindMarker(gridAlignment + '-odd', gridSprite);
gridSurface.waitFor(surface);
}
}
return this.surface;
},
/**
*
* Mapping data value into coordinate.
*
* @param {*} value
* @param {String} field
* @param {Number} [idx]
* @param {Ext.util.MixedCollection} [items]
* @return {Number}
*/
getCoordFor: function (value, field, idx, items) {
return this.getLayout().getCoordFor(value, field, idx, items);
},
applyPosition: function (pos) {
return pos.toLowerCase();
},
applyLabel: function (newText, oldText) {
if (!oldText) {
oldText = new Ext.draw.sprite.Text({});
}
oldText.setAttributes(newText);
return oldText;
},
applyLayout: function (layout, oldLayout) {
// TODO: finish this
layout = Ext.factory(layout, null, oldLayout, 'axisLayout');
layout.setAxis(this);
return layout;
},
applySegmenter: function (segmenter, oldSegmenter) {
// TODO: finish this
segmenter = Ext.factory(segmenter, null, oldSegmenter, 'segmenter');
segmenter.setAxis(this);
return segmenter;
},
updateMinimum: function () {
this.range = null;
},
updateMaximum: function () {
this.range = null;
},
hideLabels: function () {
this.getSprites()[0].setDirty(true);
this.setLabel({hidden: true});
},
showLabels: function () {
this.getSprites()[0].setDirty(true);
this.setLabel({hidden: false});
},
/**
* Invokes renderFrame on this axis's surface(s)
*/
renderFrame: function () {
this.getSurface().renderFrame();
},
updateChart: function (newChart, oldChart) {
var me = this, surface;
if (oldChart) {
oldChart.un('serieschanged', me.onSeriesChanged, me);
}
if (newChart) {
newChart.on('serieschanged', me.onSeriesChanged, me);
if (newChart.getSeries()) {
me.onSeriesChanged(newChart);
}
me.surface = null;
surface = me.getSurface();
surface.add(me.getSprites());
surface.add(me.getTitle());
}
},
applyBackground: function (background) {
var rect = Ext.ClassManager.getByAlias('sprite.rect');
return rect.def.normalize(background);
},
/**
* @protected
* Invoked when data has changed.
*/
processData: function () {
this.getLayout().processData();
this.range = null;
},
getDirection: function () {
return this.getChart().getDirectionForAxis(this.getPosition());
},
isSide: function () {
var position = this.getPosition();
return position === 'left' || position === 'right';
},
applyFields: function (fields) {
return [].concat(fields);
},
updateFields: function (fields) {
this.fieldsMap = {};
for (var i = 0; i < fields.length; i++) {
this.fieldsMap[fields[i]] = true;
}
},
applyVisibleRange: function (visibleRange, oldVisibleRange) {
// If it is in reversed order swap them
if (visibleRange[0] > visibleRange[1]) {
var temp = visibleRange[0];
visibleRange[0] = visibleRange[1];
visibleRange[0] = temp;
}
if (visibleRange[1] === visibleRange[0]) {
visibleRange[1] += 1 / this.getMaxZoom();
}
if (visibleRange[1] > visibleRange[0] + 1) {
visibleRange[0] = 0;
visibleRange[1] = 1;
} else if (visibleRange[0] < 0) {
visibleRange[1] -= visibleRange[0];
visibleRange[0] = 0;
} else if (visibleRange[1] > 1) {
visibleRange[0] -= visibleRange[1] - 1;
visibleRange[1] = 1;
}
if (oldVisibleRange && visibleRange[0] === oldVisibleRange[0] && visibleRange[1] === oldVisibleRange[1]) {
return undefined;
}
return visibleRange;
},
updateVisibleRange: function (visibleRange) {
this.fireEvent('transformed', this, visibleRange);
},
onSeriesChanged: function (chart) {
var me = this,
series = chart.getSeries(),
getAxisMethod = 'get' + me.getDirection() + 'Axis',
boundSeries = [], i, ln = series.length;
for (i = 0; i < ln; i++) {
if (this === series[i][getAxisMethod]()) {
boundSeries.push(series[i]);
}
}
me.boundSeries = boundSeries;
me.getLayout().processData();
},
applyRange: function (newRange) {
if (!newRange) {
return this.dataRange.slice(0);
} else {
return [
newRange[0] === null ? this.dataRange[0] : newRange[0],
newRange[1] === null ? this.dataRange[1] : newRange[1]
];
}
},
/**
* Get the range derived from all the bound series.
* @return {Array}
*/
getRange: function () {
var me = this,
getRangeMethod = 'get' + me.getDirection() + 'Range';
if (me.range) {
return me.range;
}
if (!isNaN(me.getMinimum()) && !isNaN(me.getMaximum())) {
return this.range = [me.getMinimum(), me.getMaximum()];
}
var min = Infinity,
max = -Infinity,
boundSeries = me.boundSeries,
series, i, ln;
// For each series bound to this axis, ask the series for its min/max values
// and use them to find the overall min/max.
for (i = 0, ln = boundSeries.length; i < ln; i++) {
series = boundSeries[i];
var minMax = series[getRangeMethod]();
if (minMax) {
if (minMax[0] < min) {
min = minMax[0];
}
if (minMax[1] > max) {
max = minMax[1];
}
}
}
if (!isFinite(max)) {
max = me.prevMax;
}
if (!isFinite(min)) {
min = me.prevMin;
}
if (this.getLabelInSpan() || min === max) {
max += this.getIncrement();
min -= this.getIncrement();
}
if (!isNaN(me.getMinimum())) {
min = me.getMinimum();
} else {
me.prevMin = min;
}
if (!isNaN(me.getMaximum())) {
max = me.getMaximum();
} else {
me.prevMax = max;
}
return this.range = [min, max];
},
applyStyle: function (style, oldStyle) {
var cls = Ext.ClassManager.getByAlias('sprite.' + this.seriesType);
if (cls && cls.def) {
style = cls.def.normalize(style);
}
oldStyle = Ext.apply(oldStyle || {}, style);
return oldStyle;
},
updateCenter: function (center) {
var sprites = this.getSprites(),
axisSprite = sprites[0],
centerX = center[0],
centerY = center[1];
if (axisSprite) {
axisSprite.setAttributes({
centerX: centerX,
centerY: centerY
});
}
if (this.gridSpriteEven) {
this.gridSpriteEven.getTemplate().setAttributes({
translationX: centerX,
translationY: centerY,
rotationCenterX: centerX,
rotationCenterY: centerY
});
}
if (this.gridSpriteOdd) {
this.gridSpriteOdd.getTemplate().setAttributes({
translationX: centerX,
translationY: centerY,
rotationCenterX: centerX,
rotationCenterY: centerY
});
}
},
getSprites: function () {
if (!this.getChart()) {
return;
}
var me = this,
range = me.getRange(),
position = me.getPosition(),
chart = me.getChart(),
animation = chart.getAnimate(),
baseSprite, style,
length = me.getLength();
// If animation is false, then stop animation.
if (animation === false) {
animation = {
duration: 0
};
}
if (range) {
style = Ext.applyIf({
position: position,
axis: me,
min: range[0],
max: range[1],
length: length,
grid: me.getGrid(),
hidden: me.getHidden(),
titleOffset: me.titleOffset,
layout: me.getLayout(),
segmenter: me.getSegmenter(),
label: me.getLabel()
}, me.getStyle());
// If the sprites are not created.
if (!me.sprites.length) {
baseSprite = new Ext.chart.axis.sprite.Axis(style);
baseSprite.fx.setCustomDuration({
baseRotation: 0
});
baseSprite.fx.on("animationstart", "onAnimationStart", me);
baseSprite.fx.on("animationend", "onAnimationEnd", me);
me.sprites.push(baseSprite);
me.updateTitleSprite();
} else {
baseSprite = me.sprites[0];
baseSprite.fx.setConfig(animation);
baseSprite.setAttributes(style);
baseSprite.setLayout(me.getLayout());
baseSprite.setSegmenter(me.getSegmenter());
baseSprite.setLabel(me.getLabel());
}
if (me.getRenderer()) {
baseSprite.setRenderer(me.getRenderer());
}
}
return me.sprites;
},
updateTitleSprite: function () {
if (!this.sprites[0]) {
return;
}
var me = this,
thickness = this.sprites[0].thickness,
surface = me.getSurface(),
title = this.getTitle(),
position = me.getPosition(),
titleMargin = me.getTitleMargin(),
length = me.getLength(),
anchor = surface.roundPixel(length / 2);
if (title) {
switch (position) {
case 'top':
title.setAttributes({
x: anchor,
y: titleMargin / 2,
textBaseline: 'top',
textAlign: 'center'
}, true, true);
title.applyTransformations();
me.titleOffset = title.getBBox().height + titleMargin;
break;
case 'bottom':
title.setAttributes({
x: anchor,
y: thickness + titleMargin / 2,
textBaseline: 'top',
textAlign: 'center'
}, true, true);
title.applyTransformations();
me.titleOffset = title.getBBox().height + titleMargin;
break;
case 'left':
title.setAttributes({
x: titleMargin / 2,
y: anchor,
textBaseline: 'top',
textAlign: 'center',
rotationCenterX: titleMargin / 2,
rotationCenterY: anchor,
rotationRads: -Math.PI / 2
}, true, true);
title.applyTransformations();
me.titleOffset = title.getBBox().width + titleMargin;
break;
case 'right':
title.setAttributes({
x: thickness + titleMargin / 2,
y: anchor,
textBaseline: 'bottom',
textAlign: 'center',
rotationCenterX: thickness + titleMargin / 2,
rotationCenterY: anchor,
rotationRads: Math.PI / 2
}, true, true);
title.applyTransformations();
me.titleOffset = title.getBBox().width + titleMargin;
break;
}
}
},
onThicknessChanged: function () {
var me = this;
me.getChart().onThicknessChanged();
},
getThickness: function () {
if (this.getHidden()) {
return 0;
}
return (this.sprites[0] && this.sprites[0].thickness || 1) + this.titleOffset;
},
onAnimationStart: function () {
this.animating++;
if (this.animating === 1) {
this.fireEvent("animationstart");
}
},
onAnimationEnd: function () {
this.animating--;
if (this.animating === 0) {
this.fireEvent("animationend");
}
},
// Methods used in ComponentQuery and controller
getItemId: function () {
return this.getId();
},
getAncestorIds: function () {
return [this.getChart().getId()];
},
isXType: function (xtype) {
return xtype === 'axis';
},
destroy: function () {
Ext.ComponentManager.unregister(this);
this.callSuper();
}
});

69
vendor/touch/src/chart/axis/Category.js vendored Normal file
View file

@ -0,0 +1,69 @@
/**
* @class Ext.chart.axis.Category
* @extends Ext.chart.axis.Axis
*
* A type of axis that displays items in categories. This axis is generally used to
* display categorical information like names of items, month names, quarters, etc.
* but no quantitative values. For that other type of information {@link Ext.chart.axis.Numeric Numeric}
* axis are more suitable.
*
* As with other axis you can set the position of the axis and its title. For example:
*
* @example preview
* var chart = new Ext.chart.CartesianChart({
* animate: true,
* innerPadding: {
* left: 40,
* right: 40
* },
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* axes: [{
* type: 'category',
* position: 'bottom',
* fields: ['name'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* }
* }],
* series: [{
* type: 'area',
* subStyle: {
* fill: ['blue', 'green', 'red']
* },
* xField: 'name',
* yField: ['data1', 'data2', 'data3']
*
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*
* In this example with set the category axis to the bottom of the surface, bound the axis to
* the `name` property and set as title "Sample Values".
*/
Ext.define('Ext.chart.axis.Category', {
requires: [
'Ext.chart.axis.layout.CombineDuplicate',
'Ext.chart.axis.segmenter.Names'
],
extend: 'Ext.chart.axis.Axis',
alias: 'axis.category',
type: 'category',
config: {
layout: 'combineDuplicate',
segmenter: 'names'
}
});

72
vendor/touch/src/chart/axis/Numeric.js vendored Normal file
View file

@ -0,0 +1,72 @@
/**
* @class Ext.chart.axis.Numeric
* @extends Ext.chart.axis.Axis
*
* An axis to handle numeric values. This axis is used for quantitative data as
* opposed to the category axis. You can set minimum and maximum values to the
* axis so that the values are bound to that. If no values are set, then the
* scale will auto-adjust to the values.
*
* @example preview
* var chart = new Ext.chart.CartesianChart({
* animate: true,
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':1, 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':2, 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':3, 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':4, 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':5, 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['data1', 'data2', 'data3', 'data4', 'data5'],
* title: 'Sample Values',
* grid: {
* odd: {
* opacity: 1,
* fill: '#ddd',
* stroke: '#bbb',
* 'lineWidth': 1
* }
* },
* minimum: 0,
* adjustMinimumByMajorUnit: 0
* }],
* series: [{
* type: 'area',
* subStyle: {
* fill: ['blue', 'green', 'red']
* },
* xField: 'name',
* yField: ['data1', 'data2', 'data3']
*
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
* In this example we create an axis of Numeric type. We set a minimum value so that
* even if all series have values greater than zero, the grid starts at zero. We bind
* the axis onto the left part of the surface by setting _position_ to _left_.
* We bind three different store fields to this axis by setting _fields_ to an array.
* We set the title of the axis to _Number of Hits_ by using the _title_ property.
* We use a _grid_ configuration to set odd background rows to a certain style and even rows
* to be transparent/ignored.
*
*/
Ext.define('Ext.chart.axis.Numeric', {
extend: 'Ext.chart.axis.Axis',
alias: 'axis.numeric',
type: 'numeric',
requires: ['Ext.chart.axis.layout.Continuous', 'Ext.chart.axis.segmenter.Numeric'],
config: {
layout: 'continuous',
segmenter: 'numeric',
aggregator: 'double'
}
});

140
vendor/touch/src/chart/axis/Time.js vendored Normal file
View file

@ -0,0 +1,140 @@
/**
* @class Ext.chart.axis.Time
* @extends Ext.chart.axis.Numeric
*
* A type of axis whose units are measured in time values. Use this axis
* for listing dates that you will want to group or dynamically change.
* If you just want to display dates as categories then use the
* Category class for axis instead.
*
* @example preview
* var chart = new Ext.chart.CartesianChart({
* animate: true,
* store: {
* fields: ['time', 'open', 'high', 'low', 'close'],
* data: [
* {'time':new Date('Jan 1 2010').getTime(), 'open':600, 'high':614, 'low':578, 'close':590},
* {'time':new Date('Jan 2 2010').getTime(), 'open':590, 'high':609, 'low':580, 'close':580},
* {'time':new Date('Jan 3 2010').getTime(), 'open':580, 'high':602, 'low':578, 'close':602},
* {'time':new Date('Jan 4 2010').getTime(), 'open':602, 'high':614, 'low':586, 'close':586},
* {'time':new Date('Jan 5 2010').getTime(), 'open':586, 'high':602, 'low':565, 'close':565}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['open', 'high', 'low', 'close'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* grid: true,
* minimum: 560,
* maximum: 640
* }, {
* type: 'time',
* position: 'bottom',
* fields: ['time'],
* fromDate: new Date('Dec 31 2009'),
* toDate: new Date('Jan 6 2010'),
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* style: {
* axisLine: false
* }
* }],
* series: [{
* type: 'candlestick',
* xField: 'time',
* openField: 'open',
* highField: 'high',
* lowField: 'low',
* closeField: 'close',
* style: {
* ohlcType: 'ohlc',
* dropStyle: {
* fill: 'rgb(237, 123, 43)',
* stroke: 'rgb(237, 123, 43)'
* },
* raiseStyle: {
* fill: 'rgb(55, 153, 19)',
* stroke: 'rgb(55, 153, 19)'
* }
* },
* aggregator: {
* strategy: 'time'
* }
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*/
Ext.define('Ext.chart.axis.Time', {
extend: 'Ext.chart.axis.Numeric',
alias: 'axis.time',
type: 'time',
requires: ['Ext.chart.axis.layout.Continuous', 'Ext.chart.axis.segmenter.Time', 'Ext.DateExtras'],
config: {
/**
* @cfg {Boolean} calculateByLabelSize
* The minimum value drawn by the axis. If not set explicitly, the axis
* minimum will be calculated automatically.
*/
calculateByLabelSize: true,
/**
* @cfg {String/Boolean} dateFormat
* Indicates the format the date will be rendered on.
* For example: 'M d' will render the dates as 'Jan 30', etc.
*/
dateFormat: null,
/**
* @cfg {Date} fromDate The starting date for the time axis.
*/
fromDate: null,
/**
* @cfg {Date} toDate The ending date for the time axis.
*/
toDate: null,
/**
* @cfg {Array} [step=[Ext.Date.DAY, 1]] An array with two components:
*
* - The unit of the step (Ext.Date.DAY, Ext.Date.MONTH, etc).
* - The number of units for the step (1, 2, etc).
*
*/
step: [Ext.Date.DAY, 1],
layout: 'continuous',
segmenter: 'time',
aggregator: 'time'
},
updateDateFormat: function (format) {
this.setRenderer(function (date) {
return Ext.Date.format(new Date(date), format);
});
},
updateFromDate: function (date) {
this.setMinimum(+date);
},
updateToDate: function (date) {
this.setMaximum(+date);
},
getCoordFor: function (value) {
if (Ext.isString(value)) {
value = new Date(value);
}
return +value;
}
});

View file

@ -0,0 +1,20 @@
/**
* @class Ext.chart.axis.layout.CombineDuplicate
* @extends Ext.chart.axis.layout.Discrete
*
* Discrete processor that combines duplicate data points.
*/
Ext.define("Ext.chart.axis.layout.CombineDuplicate", {
extend: 'Ext.chart.axis.layout.Discrete',
alias: 'axisLayout.combineDuplicate',
getCoordFor: function (value, field, idx, items) {
if (!(value in this.labelMap)) {
var result = this.labelMap[value] = this.labels.length;
this.labels.push(value);
return result;
}
return this.labelMap[value];
}
});

View file

@ -0,0 +1,76 @@
/**
* @class Ext.chart.axis.layout.Continuous
* @extends Ext.chart.axis.layout.Layout
*
* Processor for axis data that can be interpolated.
*/
Ext.define('Ext.chart.axis.layout.Continuous', {
extend: 'Ext.chart.axis.layout.Layout',
alias: 'axisLayout.continuous',
config: {
adjustMinimumByMajorUnit: false,
adjustMaximumByMajorUnit: false
},
getCoordFor: function (value, field, idx, items) {
return +value;
},
//@inheritdoc
snapEnds: function (context, min, max, estStepSize) {
var segmenter = context.segmenter,
axis = this.getAxis(),
minimum = axis.getMinimum(),
maximum = axis.getMaximum(),
majorTickSteps = axis.getMajorTickSteps(),
out = majorTickSteps && Ext.isNumber(minimum) && Ext.isNumber(maximum) && segmenter.exactStep ?
segmenter.exactStep(min, (max - min) / majorTickSteps) :
segmenter.preferredStep(min, estStepSize),
unit = out.unit,
step = out.step,
from = segmenter.align(min, step, unit),
steps = segmenter.diff(min, max, unit) + 1;
return {
min: segmenter.from(min),
max: segmenter.from(max),
from: from,
to: segmenter.add(from, steps * step, unit),
step: step,
steps: steps,
unit: unit,
get: function (current) {
return segmenter.add(this.from, this.step * current, unit);
}
};
},
snapMinorEnds: function (context) {
var majorTicks = context.majorTicks,
minorTickSteps = this.getAxis().getMinorTickSteps(),
segmenter = context.segmenter,
min = majorTicks.min,
max = majorTicks.max,
from = majorTicks.from,
unit = majorTicks.unit,
step = majorTicks.step / minorTickSteps,
scaledStep = step * unit.scale,
fromMargin = from - min,
offset = Math.floor(fromMargin / scaledStep),
extraSteps = offset + Math.floor((max - majorTicks.to) / scaledStep) + 1,
steps = majorTicks.steps * minorTickSteps + extraSteps;
return {
min: min,
max: max,
from: min + fromMargin % scaledStep,
to: segmenter.add(from, steps * step, unit),
step: step,
steps: steps,
unit: unit,
get: function (current) {
return (current % minorTickSteps + offset + 1 !== 0) ? // don't render minor tick in major tick position
segmenter.add(this.from, this.step * current, unit) :
null;
}
}
}
});

View file

@ -0,0 +1,127 @@
/**
* @class Ext.chart.axis.layout.Discrete
* @extends Ext.chart.axis.layout.Layout
*
* Simple processor for data that cannot be interpolated.
*/
Ext.define('Ext.chart.axis.layout.Discrete', {
extend: 'Ext.chart.axis.layout.Layout',
alias: 'axisLayout.discrete',
processData: function () {
var me = this,
axis = me.getAxis(),
boundSeries = axis.boundSeries,
direction = axis.getDirection(),
i, ln, item;
this.labels = [];
this.labelMap = {};
for (i = 0, ln = boundSeries.length; i < ln; i++) {
item = boundSeries[i];
if (item['get' + direction + 'Axis']() === axis) {
item['coordinate' + direction]();
}
}
// About the labels on Category axes (aka. axes with a Discrete layout)...
//
// When the data set from the store changes, series.processData() is called, which does its thing
// at the series level and then calls series.updateLabelData() to update the labels in the sprites
// that belong to the series. At the same time, series.processData() calls axis.processData(), which
// also does its thing but at the axis level, and also needs to update the labels for the sprite(s)
// that belong to the axis. This is not that simple, however. So how are the axis labels rendered?
// First, axis.sprite.Axis.render() calls renderLabels() which obtains the majorTicks from the
// axis.layout and iterate() through them. The majorTicks are an object returned by snapEnds() below
// which provides a getLabel() function that returns the label from the axis.layoutContext.data array.
// So now the question is: how are the labels transferred from the axis.layout to the axis.layoutContext?
// The easy response is: it's in calculateLayout() below. The issue is to call calculateLayout() because
// it takes in an axis.layoutContext that can only be created in axis.sprite.Axis.doLayout(), which is
// a private "updater" function that is called by all the sprite's "dirtyTriggers". Of course, we don't
// want to call doLayout() directly from here, so instead we update the sprite's data attribute, which
// sets the dirtyTrigger which calls doLayout() which calls calculateLayout() etc...
// Note that the sprite's data attribute could be set to any value and it would still result in the
// dirtyTrigger we need. For consistency, however, it is set to the labels.
axis.getSprites()[0].setAttributes({data:this.labels});
},
// @inheritdoc
calculateLayout: function (context) {
context.data = this.labels;
this.callSuper([context]);
},
//@inheritdoc
calculateMajorTicks: function (context) {
var me = this,
attr = context.attr,
data = context.data,
range = attr.max - attr.min,
zoom = range / Math.max(1, attr.length) * (attr.visibleMax - attr.visibleMin),
viewMin = attr.min + range * attr.visibleMin,
viewMax = attr.min + range * attr.visibleMax,
estStepSize = attr.estStepSize * zoom;
var out = me.snapEnds(context, Math.max(0, attr.min), Math.min(attr.max, data.length - 1), estStepSize);
if (out) {
me.trimByRange(context, out, viewMin, viewMax);
context.majorTicks = out;
}
},
// @inheritdoc
snapEnds: function (context, min, max, estStepSize) {
estStepSize = Math.ceil(estStepSize);
var steps = Math.floor((max - min) / estStepSize),
data = context.data;
return {
min: min,
max: max,
from: min,
to: steps * estStepSize + min,
step: estStepSize,
steps: steps,
unit: 1,
getLabel: function (current) {
return data[this.from + this.step * current];
},
get: function (current) {
return this.from + this.step * current;
}
};
},
// @inheritdoc
trimByRange: function (context, out, trimMin, trimMax) {
var unit = out.unit,
beginIdx = Math.ceil((trimMin - out.from) / unit) * unit,
endIdx = Math.floor((trimMax - out.from) / unit) * unit,
begin = Math.max(0, Math.ceil(beginIdx / out.step)),
end = Math.min(out.steps, Math.floor(endIdx / out.step));
if (end < out.steps) {
out.to = end;
}
if (out.max > trimMax) {
out.max = out.to;
}
if (out.from < trimMin && out.step > 0) {
out.from = out.from + begin * out.step * unit;
while (out.from < trimMin) {
begin++;
out.from += out.step * unit;
}
}
if (out.min < trimMin) {
out.min = out.from;
}
out.steps = end - begin;
},
getCoordFor: function (value, field, idx, items) {
this.labels.push(value);
return this.labels.length - 1;
}
});

View file

@ -0,0 +1,139 @@
/**
* @abstract
* @class Ext.chart.axis.layout.Layout
*
* Interface used by Axis to process its data into a meaningful layout.
*/
Ext.define("Ext.chart.axis.layout.Layout", {
config: {
/**
* @cfg {Ext.chart.axis.Axis} axis The axis that the Layout is bound.
*/
axis: null
},
constructor: function (config) {
this.initConfig();
},
/**
* Processes the data of the series bound to the axis.
* @param {Ext.chart.series.Series} series The bound series.
*/
processData: function (series) {
var me = this,
axis = me.getAxis(),
direction = axis.getDirection(),
boundSeries = axis.boundSeries,
i, ln, item;
if (series) {
series['coordinate' + direction]();
} else {
for (i = 0, ln = boundSeries.length; i < ln; i++) {
item = boundSeries[i];
if (item['get' + direction + 'Axis']() === axis) {
item['coordinate' + direction]();
}
}
}
},
/**
* Calculates the position of major ticks for the axis.
* @param {Object} context
*/
calculateMajorTicks: function (context) {
var me = this,
attr = context.attr,
range = attr.max - attr.min,
zoom = range / Math.max(1, attr.length) * (attr.visibleMax - attr.visibleMin),
viewMin = attr.min + range * attr.visibleMin,
viewMax = attr.min + range * attr.visibleMax,
estStepSize = attr.estStepSize * zoom,
out = me.snapEnds(context, attr.min, attr.max, estStepSize);
if (out) {
me.trimByRange(context, out, viewMin, viewMax);
context.majorTicks = out;
}
},
/**
* Calculates the position of sub ticks for the axis.
* @param {Object} context
*/
calculateMinorTicks: function (context) {
var attr = context.attr;
if (this.snapMinorEnds) {
context.minorTicks = this.snapMinorEnds(context);
}
},
/**
* Calculates the position of tick marks for the axis.
* @param {Object} context
* @return {*}
*/
calculateLayout: function (context) {
var me = this,
attr = context.attr,
majorTicks = attr.majorTicks,
minorTicks = attr.minorTicks;
if (attr.length === 0) {
return null;
}
if (majorTicks) {
this.calculateMajorTicks(context);
if (minorTicks) {
this.calculateMinorTicks(context);
}
}
},
/**
* Snaps the data bound to the axis to meaningful tick marks.
* @param {Object} context
* @param {Number} min
* @param {Number} max
* @param {Number} estStepSize
*/
snapEnds: Ext.emptyFn,
/**
* Trims the layout of the axis by the defined minimum and maximum.
* @param {Object} context
* @param {Object} out
* @param {Number} trimMin
* @param {Number} trimMax
*/
trimByRange: function (context, out, trimMin, trimMax) {
var segmenter = context.segmenter,
unit = out.unit,
beginIdx = segmenter.diff(out.from, trimMin, unit),
endIdx = segmenter.diff(out.from, trimMax, unit),
begin = Math.max(0, Math.ceil(beginIdx / out.step)),
end = Math.min(out.steps, Math.floor(endIdx / out.step));
if (end < out.steps) {
out.to = segmenter.add(out.from, end * out.step, unit);
}
if (out.max > trimMax) {
out.max = out.to;
}
if (out.from < trimMin) {
out.from = segmenter.add(out.from, begin * out.step, unit);
while (out.from < trimMin) {
begin++;
out.from = segmenter.add(out.from, out.step, unit);
}
}
if (out.min < trimMin) {
out.min = out.from;
}
out.steps = end - begin;
}
});

View file

@ -0,0 +1,36 @@
/**
* @class Ext.chart.axis.segmenter.Names
* @extends Ext.chart.axis.segmenter.Segmenter
*
* Names data type. Names will be calculated as their indices in the methods in this class.
* The `preferredStep` always return `{ unit: 1, step: 1 }` to indicate "show every item".
*
*/
Ext.define("Ext.chart.axis.segmenter.Names", {
extend: 'Ext.chart.axis.segmenter.Segmenter',
alias: 'segmenter.names',
renderer: function (value, context) {
return value;
},
diff: function (min, max, unit) {
return Math.floor(max - min);
},
align: function (value, step, unit) {
return Math.floor(value);
},
add: function (value, step, unit) {
return value + step;
},
preferredStep: function (min, estStepSize, minIdx, data) {
return {
unit: 1,
step: 1
};
}
});

View file

@ -0,0 +1,72 @@
/**
* @class Ext.chart.axis.segmenter.Numeric
* @extends Ext.chart.axis.segmenter.Segmenter
*
* Numeric data type.
*/
Ext.define('Ext.chart.axis.segmenter.Numeric', {
extend: 'Ext.chart.axis.segmenter.Segmenter',
alias: 'segmenter.numeric',
renderer: function (value, context) {
return value.toFixed(Math.max(0, context.majorTicks.unit.fixes));
},
diff: function (min, max, unit) {
return Math.floor((max - min) / unit.scale);
},
align: function (value, step, unit) {
return Math.floor(value / (unit.scale * step)) * unit.scale * step;
},
add: function (value, step, unit) {
return value + step * unit.scale;
},
preferredStep: function (min, estStepSize) {
var logs = Math.floor(Math.log(estStepSize) * Math.LOG10E), // common logarithm of estStepSize
scale = Math.pow(10, logs);
estStepSize /= scale;
if (estStepSize < 2) {
estStepSize = 2;
} else if (estStepSize < 5) {
estStepSize = 5;
} else if (estStepSize < 10) {
estStepSize = 10;
logs++;
}
return {
unit: {
// when estStepSize < 1, rounded down log10(estStepSize) is equal to -number_of_leading_zeros in estStepSize
fixes: -logs, // number of fractional digits
scale: scale
},
step: estStepSize
};
},
/**
* Wraps the provided estimated step size of a range without altering it into a step size object.
*
* @param {*} min The start point of range.
* @param {*} estStepSize The estimated step size.
* @return {Object} Return the step size by an object of step x unit.
* @return {Number} return.step The step count of units.
* @return {Object} return.unit The unit.
*/
exactStep: function (min, estStepSize) {
var logs = Math.floor(Math.log(estStepSize) * Math.LOG10E),
scale = Math.pow(10, logs);
return {
unit: {
// add one decimal point if estStepSize is not a multiple of scale
fixes: -logs + (estStepSize % scale === 0 ? 0 : 1),
scale: 1
},
step: estStepSize
}
}
});

View file

@ -0,0 +1,84 @@
/**
* @abstract
* @class Ext.chart.axis.segmenter.Segmenter
*
* Interface for a segmenter in an Axis. A segmenter defines the operations you can do to a specific
* data type.
*
* See {@link Ext.chart.axis.Axis}.
*
*/
Ext.define('Ext.chart.axis.segmenter.Segmenter', {
config: {
/**
* @cfg {Ext.chart.axis.Axis} axis The axis that the Segmenter is bound.
*/
axis: null
},
constructor: function (config) {
this.initConfig(config);
},
/**
* This method formats the value.
*
* @param {*} value The value to format.
* @param {Object} context Axis layout context.
* @return {String}
*/
renderer: function (value, context) {
return String(value);
},
/**
* Convert from any data into the target type.
* @param {*} value The value to convert from
* @return {*} The converted value.
*/
from: function (value) {
return value;
},
/**
* Returns the difference between the min and max value based on the given unit scale.
*
* @param {*} min The smaller value.
* @param {*} max The larger value.
* @param {*} unit The unit scale. Unit can be any type.
* @return {Number} The number of `unit`s between min and max. It is the minimum n that min + n * unit >= max.
*/
diff: Ext.emptyFn,
/**
* Align value with step of units.
* For example, for the date segmenter, if the unit is "Month" and step is 3, the value will be aligned by
* seasons.
*
* @param {*} value The value to be aligned.
* @param {Number} step The step of units.
* @param {*} unit The unit.
* @return {*} Aligned value.
*/
align: Ext.emptyFn,
/**
* Add `step` `unit`s to the value.
* @param {*} value The value to be added.
* @param {Number} step The step of units. Negative value are allowed.
* @param {*} unit The unit.
*/
add: Ext.emptyFn,
/**
* Given a start point and estimated step size of a range, determine the preferred step size.
*
* @param {*} start The start point of range.
* @param {*} estStepSize The estimated step size.
* @return {Object} Return the step size by an object of step x unit.
* @return {Number} return.step The step count of units.
* @return {Number|Object} return.unit The unit.
*/
preferredStep: Ext.emptyFn
});

View file

@ -0,0 +1,107 @@
/**
* @class Ext.chart.axis.segmenter.Time
* @extends Ext.chart.axis.segmenter.Segmenter
*
* Time data type.
*/
Ext.define('Ext.chart.axis.segmenter.Time', {
extend: 'Ext.chart.axis.segmenter.Segmenter',
alias: 'segmenter.time',
config: {
/**
* @cfg {Object} step
* If specified, the will override the result of {@link #preferredStep}.
*/
step: null
},
renderer: function (value, context) {
var ExtDate = Ext.Date;
switch (context.majorTicks.unit) {
case 'y':
return ExtDate.format(value, 'Y');
case 'mo':
return ExtDate.format(value, 'Y-m');
case 'd':
return ExtDate.format(value, 'Y-m-d');
}
return ExtDate.format(value, 'Y-m-d\nH:i:s');
},
from: function (value) {
return new Date(value);
},
diff: function (min, max, unit) {
var ExtDate = Ext.Date;
if (isFinite(min)) {
min = new Date(min);
}
if (isFinite(max)) {
max = new Date(max);
}
return ExtDate.diff(min, max, unit);
},
align: function (date, step, unit) {
if (unit === 'd' && step >= 7) {
date = Ext.Date.align(date, 'd', step);
date.setDate(date.getDate() - date.getDay() + 1);
return date;
} else {
return Ext.Date.align(date, unit, step);
}
},
add: function (value, step, unit) {
return Ext.Date.add(new Date(value), unit, step);
},
preferredStep: function (min, estStepSize) {
if (this.getStep()) {
return this.getStep();
}
var from = new Date(+min),
to = new Date(+min + Math.ceil(estStepSize)),
ExtDate = Ext.Date,
units = [
[ExtDate.YEAR, 1, 2, 5, 10, 20, 50, 100, 200, 500],
[ExtDate.MONTH, 1, 3, 6],
[ExtDate.DAY, 1, 7, 14],
[ExtDate.HOUR, 1, 6, 12],
[ExtDate.MINUTE, 1, 5, 15, 30],
[ExtDate.SECOND, 1, 5, 15, 30],
[ExtDate.MILLI, 1, 2, 5, 10, 20, 50, 100, 200, 500]
],
result;
for (var i = 0; i < units.length; i++) {
var unit = units[i][0],
diff = this.diff(from, to, unit);
if (diff > 0) {
for (var j = 1; j < units[i].length; j++) {
if (diff <= units[i][j]) {
result = {
unit: unit,
step: units[i][j]
};
break;
}
}
if (!result) {
i--;
result = {
unit: units[i][0],
step: 1
};
}
break;
}
}
if (!result) {
result = {unit: ExtDate.DAY, step: 1}; // Default step is one Day.
}
return result;
}
});

View file

@ -0,0 +1,715 @@
/**
* @private
* @class Ext.chart.axis.sprite.Axis
* @extends Ext.draw.sprite.Sprite
*
* The axis sprite. Currently all types of the axis will be rendered with this sprite.
* TODO(touch-2.2): Split different types of axis into different sprite classes.
*/
Ext.define('Ext.chart.axis.sprite.Axis', {
extend: 'Ext.draw.sprite.Sprite',
mixins: {
markerHolder: 'Ext.chart.MarkerHolder'
},
requires: ['Ext.draw.sprite.Text'],
inheritableStatics: {
def: {
processors: {
/**
* @cfg {Boolean} grid 'true' if the axis has a grid.
*/
grid: 'bool',
/**
* @cfg {Boolean} axisLine 'true' if the main line of the axis is drawn.
*/
axisLine: 'bool',
/**
* @cfg {Boolean} minorTricks 'true' if the axis has sub ticks.
*/
minorTicks: 'bool',
/**
* @cfg {Number} minorTickSize The length of the minor ticks.
*/
minorTickSize: 'number',
/**
* @cfg {Boolean} majorTicks 'true' if the axis has major ticks.
*/
majorTicks: 'bool',
/**
* @cfg {Number} majorTickSize The length of the major ticks.
*/
majorTickSize: 'number',
/**
* @cfg {Number} length The total length of the axis.
*/
length: 'number',
/**
* @private
* @cfg {Number} startGap Axis start determined by the chart inset padding.
*/
startGap: 'number',
/**
* @private
* @cfg {Number} endGap Axis end determined by the chart inset padding.
*/
endGap: 'number',
/**
* @cfg {Number} dataMin The minimum value of the axis data.
*/
dataMin: 'number',
/**
* @cfg {Number} dataMax The maximum value of the axis data.
*/
dataMax: 'number',
/**
* @cfg {Number} visibleMin The minimum value that is displayed.
*/
visibleMin: 'number',
/**
* @cfg {Number} visibleMax The maximum value that is displayed.
*/
visibleMax: 'number',
/**
* @cfg {String} position The position of the axis on the chart.
*/
position: 'enums(left,right,top,bottom,angular,radial)',
/**
* @cfg {Number} minStepSize The minimum step size between ticks.
*/
minStepSize: 'number',
/**
* @private
* @cfg {Number} estStepSize The estimated step size between ticks.
*/
estStepSize: 'number',
/**
* @private
* Unused.
*/
titleOffset: 'number',
/**
* @cfg {Number} textPadding The padding around axis labels to determine collision.
*/
textPadding: 'number',
/**
* @cfg {Number} min The minimum value of the axis.
*/
min: 'number',
/**
* @cfg {Number} max The maximum value of the axis.
*/
max: 'number',
/**
* @cfg {Number} centerX The central point of the angular axis on the x-axis.
*/
centerX: 'number',
/**
* @cfg {Number} centerY The central point of the angular axis on the y-axis.
*/
centerY: 'number',
/**
* @private
* @cfg {Number} radius
* Unused.
*/
radius: 'number',
/**
* @cfg {Number} The starting rotation of the angular axis.
*/
baseRotation: 'number',
/**
* @private
* Unused.
*/
data: 'default',
/**
* @cfg {Boolean} 'true' if the estimated step size is adjusted by text size.
*/
enlargeEstStepSizeByText: 'bool'
},
defaults: {
grid: false,
axisLine: true,
minorTicks: false,
minorTickSize: 3,
majorTicks: true,
majorTickSize: 5,
length: 0,
startGap: 0,
endGap: 0,
visibleMin: 0,
visibleMax: 1,
dataMin: 0,
dataMax: 1,
position: '',
minStepSize: 0,
estStepSize: 20,
min: 0,
max: 1,
centerX: 0,
centerY: 0,
radius: 1,
baseRotation: 0,
data: null,
titleOffset: 0,
textPadding: 5,
scalingCenterY: 0,
scalingCenterX: 0,
// Override default
strokeStyle: 'black',
enlargeEstStepSizeByText: false
},
dirtyTriggers: {
minorTickSize: 'bbox',
majorTickSize: 'bbox',
position: 'bbox,layout',
axisLine: 'bbox,layout',
min: 'layout',
max: 'layout',
length: 'layout',
minStepSize: 'layout',
estStepSize: 'layout',
data: 'layout',
dataMin: 'layout',
dataMax: 'layout',
visibleMin: 'layout',
visibleMax: 'layout',
enlargeEstStepSizeByText: 'layout'
},
updaters: {
'layout': function () {
this.doLayout();
}
}
}
},
config: {
/**
* @cfg {Object} label
*
* The label configuration object for the Axis. This object may include style attributes
* like `spacing`, `padding`, `font` that receives a string or number and
* returns a new string with the modified values.
*/
label: null,
/**
* @cfg {Object|Ext.chart.axis.layout.Layout} layout The layout configuration used by the axis.
*/
layout: null,
/**
* @cfg {Object|Ext.chart.axis.segmenter.Segmenter} segmenter The method of segmenter used by the axis.
*/
segmenter: null,
/**
* @cfg {Function} renderer Allows direct customisation of rendered axis sprites.
*/
renderer: null,
/**
* @private
* @cfg {Object} layoutContext Stores the context after calculating layout.
*/
layoutContext: null,
/**
* @cfg {Ext.chart.axis.Axis} axis The axis represented by the this sprite.
*/
axis: null
},
thickness: 0,
stepSize: 0,
getBBox: function () { return null; },
doLayout: function () {
var me = this,
attr = me.attr,
layout = me.getLayout(),
min = attr.dataMin + (attr.dataMax - attr.dataMin) * attr.visibleMin,
max = attr.dataMin + (attr.dataMax - attr.dataMin) * attr.visibleMax,
context = {
attr: attr,
segmenter: me.getSegmenter()
};
if (attr.position === 'left' || attr.position === 'right') {
attr.translationX = 0;
attr.translationY = max * attr.length / (max - min);
attr.scalingX = 1;
attr.scalingY = -attr.length / (max - min);
attr.scalingCenterY = 0;
attr.scalingCenterX = 0;
me.applyTransformations(true);
} else if (attr.position === 'top' || attr.position === 'bottom') {
attr.translationX = -min * attr.length / (max - min);
attr.translationY = 0;
attr.scalingX = attr.length / (max - min);
attr.scalingY = 1;
attr.scalingCenterY = 0;
attr.scalingCenterX = 0;
me.applyTransformations(true);
}
if (layout) {
layout.calculateLayout(context);
me.setLayoutContext(context);
}
},
iterate: function (snaps, fn) {
var i, position;
if (snaps.getLabel) {
if (snaps.min < snaps.from) {
fn.call(this, snaps.min, snaps.getLabel(snaps.min), -1, snaps);
}
for (i = 0; i <= snaps.steps; i++) {
fn.call(this, snaps.get(i), snaps.getLabel(i), i, snaps);
}
if (snaps.max > snaps.to) {
fn.call(this, snaps.max, snaps.getLabel(snaps.max), snaps.steps + 1, snaps);
}
} else {
if (snaps.min < snaps.from) {
fn.call(this, snaps.min, snaps.min, -1, snaps);
}
for (i = 0; i <= snaps.steps; i++) {
position = snaps.get(i);
fn.call(this, position, position, i, snaps);
}
if (snaps.max > snaps.to) {
fn.call(this, snaps.max, snaps.max, snaps.steps + 1, snaps);
}
}
},
renderTicks: function (surface, ctx, layout, clipRegion) {
var me = this,
attr = me.attr,
docked = attr.position,
matrix = attr.matrix,
halfLineWidth = 0.5 * attr.lineWidth,
xx = matrix.getXX(),
dx = matrix.getDX(),
yy = matrix.getYY(),
dy = matrix.getDY(),
majorTicks = layout.majorTicks,
majorTickSize = attr.majorTickSize,
minorTicks = layout.minorTicks,
minorTickSize = attr.minorTickSize;
if (majorTicks) {
switch (docked) {
case 'right':
function getRightTickFn(size) {
return function (position, labelText, i) {
position = surface.roundPixel(position * yy + dy) + halfLineWidth;
ctx.moveTo(0, position);
ctx.lineTo(size, position);
};
}
me.iterate(majorTicks, getRightTickFn(majorTickSize));
minorTicks && me.iterate(minorTicks, getRightTickFn(minorTickSize));
break;
case 'left':
function getLeftTickFn(size) {
return function (position, labelText, i) {
position = surface.roundPixel(position * yy + dy) + halfLineWidth;
ctx.moveTo(clipRegion[2] - size, position);
ctx.lineTo(clipRegion[2], position);
};
}
me.iterate(majorTicks, getLeftTickFn(majorTickSize));
minorTicks && me.iterate(minorTicks, getLeftTickFn(minorTickSize));
break;
case 'bottom':
function getBottomTickFn(size) {
return function (position, labelText, i) {
position = surface.roundPixel(position * xx + dx) - halfLineWidth;
ctx.moveTo(position, 0);
ctx.lineTo(position, size);
};
}
me.iterate(majorTicks, getBottomTickFn(majorTickSize));
minorTicks && me.iterate(minorTicks, getBottomTickFn(minorTickSize));
break;
case 'top':
function getTopTickFn(size) {
return function (position, labelText, i) {
position = surface.roundPixel(position * xx + dx) - halfLineWidth;
ctx.moveTo(position, clipRegion[3]);
ctx.lineTo(position, clipRegion[3] - size);
};
}
me.iterate(majorTicks, getTopTickFn(majorTickSize));
minorTicks && me.iterate(minorTicks, getTopTickFn(minorTickSize));
break;
case 'angular':
me.iterate(majorTicks, function (position, labelText, i) {
position = position / (attr.max + 1) * Math.PI * 2 + attr.baseRotation;
ctx.moveTo(
attr.centerX + (attr.length) * Math.cos(position),
attr.centerY + (attr.length) * Math.sin(position)
);
ctx.lineTo(
attr.centerX + (attr.length + majorTickSize) * Math.cos(position),
attr.centerY + (attr.length + majorTickSize) * Math.sin(position)
);
});
break;
}
}
},
renderLabels: function (surface, ctx, layout, clipRegion) {
var me = this,
attr = me.attr,
halfLineWidth = 0.5 * attr.lineWidth,
docked = attr.position,
matrix = attr.matrix,
textPadding = attr.textPadding,
xx = matrix.getXX(),
dx = matrix.getDX(),
yy = matrix.getYY(),
dy = matrix.getDY(),
thickness = 0,
majorTicks = layout.majorTicks,
padding = Math.max(attr.majorTickSize, attr.minorTickSize) + attr.lineWidth,
label = this.getLabel(), font,
lastLabelText = null,
textSize = 0, textCount = 0,
segmenter = layout.segmenter,
renderer = this.getRenderer(),
labelInverseMatrix, lastBBox = null, bbox, fly, text;
if (majorTicks && label && !label.attr.hidden) {
font = label.attr.font;
if (ctx.font !== font) {
ctx.font = font;
} // This can profoundly improve performance.
label.setAttributes({translationX: 0, translationY: 0}, true, true);
label.applyTransformations();
labelInverseMatrix = label.attr.inverseMatrix.elements.slice(0);
switch (docked) {
case 'left':
label.setAttributes({
translationX: surface.roundPixel(clipRegion[2] - padding + dx) - halfLineWidth - me.thickness / 2
}, true, true);
break;
case 'right':
label.setAttributes({
translationX: surface.roundPixel(padding + dx) - halfLineWidth + me.thickness / 2
}, true, true);
break;
case 'top':
label.setAttributes({
translationY: surface.roundPixel(clipRegion[3] - padding) - halfLineWidth - me.thickness / 2
}, true, true);
break;
case 'bottom':
label.setAttributes({
translationY: surface.roundPixel(padding) - halfLineWidth + me.thickness / 2
}, true, true);
break;
case 'radial' :
label.setAttributes({
translationX: attr.centerX
}, true, true);
break;
case 'angular':
label.setAttributes({
translationY: attr.centerY
}, true, true);
break;
}
// TODO: there are better ways to detect collision.
if (docked === 'left' || docked === 'right') {
me.iterate(majorTicks, function (position, labelText, i) {
if (labelText === undefined) {
return;
}
text = renderer ? renderer.call(this, labelText, layout, lastLabelText) : segmenter.renderer(labelText, layout, lastLabelText);
lastLabelText = labelText;
label.setAttributes({
text: String(text),
translationY: surface.roundPixel(position * yy + dy)
}, true, true);
label.applyTransformations();
thickness = Math.max(thickness, label.getBBox().width + padding);
if (thickness <= me.thickness) {
fly = Ext.draw.Matrix.fly(label.attr.matrix.elements.slice(0));
bbox = fly.prepend.apply(fly, labelInverseMatrix).transformBBox(label.getBBox(true));
if (lastBBox && !Ext.draw.Draw.isBBoxIntersect(bbox, lastBBox, textPadding)) {
return;
}
surface.renderSprite(label);
lastBBox = bbox;
textSize += bbox.height;
textCount++;
}
});
} else if (docked === 'top' || docked === 'bottom') {
me.iterate(majorTicks, function (position, labelText, i) {
if (labelText === undefined) {
return;
}
text = renderer ? renderer.call(this, labelText, layout, lastLabelText) : segmenter.renderer(labelText, layout, lastLabelText);
lastLabelText = labelText;
label.setAttributes({
text: String(text),
translationX: surface.roundPixel(position * xx + dx)
}, true, true);
label.applyTransformations();
thickness = Math.max(thickness, label.getBBox().height + padding);
if (thickness <= me.thickness) {
fly = Ext.draw.Matrix.fly(label.attr.matrix.elements.slice(0));
bbox = fly.prepend.apply(fly, labelInverseMatrix).transformBBox(label.getBBox(true));
if (lastBBox && !Ext.draw.Draw.isBBoxIntersect(bbox, lastBBox, textPadding)) {
return;
}
surface.renderSprite(label);
lastBBox = bbox;
textSize += bbox.width;
textCount++;
}
});
} else if (docked === 'radial') {
me.iterate(majorTicks, function (position, labelText, i) {
if (labelText === undefined) {
return;
}
text = renderer ? renderer.call(this, labelText, layout, lastLabelText) : segmenter.renderer(labelText, layout, lastLabelText);
lastLabelText = labelText;
if (typeof text !== 'undefined') {
label.setAttributes({
text: String(text),
translationY: attr.centerY - surface.roundPixel(position) / attr.max * attr.length
}, true, true);
label.applyTransformations();
bbox = label.attr.matrix.transformBBox(label.getBBox(true));
if (lastBBox && !Ext.draw.Draw.isBBoxIntersect(bbox, lastBBox)) {
return;
}
surface.renderSprite(label);
lastBBox = bbox;
textSize += bbox.width;
textCount++;
}
});
} else if (docked === 'angular') {
me.iterate(majorTicks, function (position, labelText, i) {
if (labelText === undefined) {
return;
}
text = renderer ? renderer.call(this, labelText, layout, lastLabelText) : segmenter.renderer(labelText, layout, lastLabelText);
lastLabelText = labelText;
if (typeof text !== 'undefined') {
var angle = position / (attr.max + 1) * Math.PI * 2 + attr.baseRotation;
label.setAttributes({
text: String(text),
translationX: attr.centerX + (attr.length + 10) * Math.cos(angle),
translationY: attr.centerY + (attr.length + 10) * Math.sin(angle)
}, true, true);
label.applyTransformations();
bbox = label.attr.matrix.transformBBox(label.getBBox(true));
if (lastBBox && !Ext.draw.Draw.isBBoxIntersect(bbox, lastBBox)) {
return;
}
surface.renderSprite(label);
lastBBox = bbox;
textSize += bbox.width;
textCount++;
}
});
}
if (attr.enlargeEstStepSizeByText && textCount) {
textSize /= textCount;
textSize += padding;
textSize *= 2;
if (attr.estStepSize < textSize) {
attr.estStepSize = textSize;
}
}
if (Math.abs(me.thickness - (thickness)) > 1) {
me.thickness = thickness;
attr.bbox.plain.dirty = true;
attr.bbox.transform.dirty = true;
me.doThicknessChanged();
return false;
}
}
},
renderAxisLine: function (surface, ctx, layout, clipRegion) {
var me = this,
attr = me.attr,
halfLineWidth = attr.lineWidth * 0.5,
docked = attr.position,
position;
if (attr.axisLine) {
switch (docked) {
case 'left':
position = surface.roundPixel(clipRegion[2]) - halfLineWidth;
ctx.moveTo(position, -attr.endGap);
ctx.lineTo(position, attr.length + attr.startGap);
break;
case 'right':
ctx.moveTo(halfLineWidth, -attr.endGap);
ctx.lineTo(halfLineWidth, attr.length + attr.startGap);
break;
case 'bottom':
ctx.moveTo(-attr.startGap, halfLineWidth);
ctx.lineTo(attr.length + attr.endGap, halfLineWidth);
break;
case 'top':
position = surface.roundPixel(clipRegion[3]) - halfLineWidth;
ctx.moveTo(-attr.startGap, position);
ctx.lineTo(attr.length + attr.endGap, position);
break;
case 'angular':
ctx.moveTo(attr.centerX + attr.length, attr.centerY);
ctx.arc(attr.centerX, attr.centerY, attr.length, 0, Math.PI * 2, true);
break;
}
}
},
renderGridLines: function (surface, ctx, layout, clipRegion) {
var me = this,
attr = me.attr,
matrix = attr.matrix,
startGap = attr.startGap,
endGap = attr.endGap,
xx = matrix.getXX(),
yy = matrix.getYY(),
dx = matrix.getDX(),
dy = matrix.getDY(),
position = attr.position,
majorTicks = layout.majorTicks,
anchor, j, lastAnchor;
if (attr.grid) {
if (majorTicks) {
if (position === 'left' || position === 'right') {
lastAnchor = attr.min * yy + dy + endGap + startGap;
me.iterate(majorTicks, function (position, labelText, i) {
anchor = position * yy + dy + endGap;
me.putMarker('horizontal-' + (i % 2 ? 'odd' : 'even'), {
y: anchor,
height: lastAnchor - anchor
}, j = i, true);
lastAnchor = anchor;
});
j++;
anchor = 0;
me.putMarker('horizontal-' + (j % 2 ? 'odd' : 'even'), {
y: anchor,
height: lastAnchor - anchor
}, j, true);
} else if (position === 'top' || position === 'bottom') {
lastAnchor = attr.min * xx + dx + startGap;
if (startGap) {
me.putMarker('vertical-even', {
x: 0,
width: lastAnchor
}, -1, true);
}
me.iterate(majorTicks, function (position, labelText, i) {
anchor = position * xx + dx + startGap;
me.putMarker('vertical-' + (i % 2 ? 'odd' : 'even'), {
x: anchor,
width: lastAnchor - anchor
}, j = i, true);
lastAnchor = anchor;
});
j++;
anchor = attr.length + attr.startGap + attr.endGap;
me.putMarker('vertical-' + (j % 2 ? 'odd' : 'even'), {
x: anchor,
width: lastAnchor - anchor
}, j, true);
} else if (position === 'radial') {
me.iterate(majorTicks, function (position, labelText, i) {
anchor = position / attr.max * attr.length;
me.putMarker('circular-' + (i % 2 ? 'odd' : 'even'), {
scalingX: anchor,
scalingY: anchor
}, i, true);
lastAnchor = anchor;
});
} else if (position === 'angular') {
me.iterate(majorTicks, function (position, labelText, i) {
anchor = position / (attr.max + 1) * Math.PI * 2 + attr.baseRotation;
me.putMarker('radial-' + (i % 2 ? 'odd' : 'even'), {
rotationRads: anchor,
rotationCenterX: 0,
rotationCenterY: 0,
scalingX: attr.length,
scalingY: attr.length
}, i, true);
lastAnchor = anchor;
});
}
}
}
},
doThicknessChanged: function () {
var axis = this.getAxis();
if (axis) {
axis.onThicknessChanged();
}
},
render: function (surface, ctx, clipRegion) {
var me = this,
layout = me.getLayoutContext();
if (layout) {
if (false === me.renderLabels(surface, ctx, layout, clipRegion)) {
return false;
}
ctx.beginPath();
me.renderTicks(surface, ctx, layout, clipRegion);
me.renderAxisLine(surface, ctx, layout, clipRegion);
me.renderGridLines(surface, ctx, layout, clipRegion);
ctx.stroke();
}
}
});

View file

@ -0,0 +1,19 @@
/**
* @class Ext.chart.grid.CircularGrid
* @extends Ext.draw.sprite.Circle
*
* Circular Grid sprite. Used by Radar chart to render a series of concentric circles.
*/
Ext.define('Ext.chart.grid.CircularGrid', {
extend: 'Ext.draw.sprite.Circle',
alias: 'grid.circular',
inheritableStatics: {
def: {
defaults: {
r: 1,
strokeStyle: '#DDD'
}
}
}
});

View file

@ -0,0 +1,43 @@
/**
* @class Ext.chart.grid.HorizontalGrid
* @extends Ext.draw.sprite.Sprite
*
* Horizontal Grid sprite. Used in Cartesian Charts.
*/
Ext.define("Ext.chart.grid.HorizontalGrid", {
extend: 'Ext.draw.sprite.Sprite',
alias: 'grid.horizontal',
inheritableStatics: {
def: {
processors: {
x: 'number',
y: 'number',
width: 'number',
height: 'number'
},
defaults: {
x: 0,
y: 0,
width: 1,
height: 1,
strokeStyle: '#DDD'
}
}
},
render: function (surface, ctx, clipRegion) {
var attr = this.attr,
y = surface.roundPixel(attr.y),
halfLineWidth = ctx.lineWidth * 0.5;
ctx.beginPath();
ctx.rect(clipRegion[0] - surface.matrix.getDX(), y + halfLineWidth, +clipRegion[2], attr.height);
ctx.fill();
ctx.beginPath();
ctx.moveTo(clipRegion[0] - surface.matrix.getDX(), y + halfLineWidth);
ctx.lineTo(clipRegion[0] + clipRegion[2] - surface.matrix.getDX(), y + halfLineWidth);
ctx.stroke();
}
});

View file

@ -0,0 +1,44 @@
/**
* @class Ext.chart.grid.RadialGrid
* @extends Ext.draw.sprite.Path
*
* Radial Grid sprite. Used by Radar chart to render a series of radial lines.
* Represents the scale of the radar chart on the yField.
*/
Ext.define('Ext.chart.grid.RadialGrid', {
extend: 'Ext.draw.sprite.Path',
alias: 'grid.radial',
inheritableStatics: {
def: {
processors: {
startRadius: 'number',
endRadius: 'number'
},
defaults: {
startRadius: 0,
endRadius: 1,
scalingCenterX: 0,
scalingCenterY: 0,
strokeStyle: '#DDD'
},
dirtyTriggers: {
startRadius: 'path,bbox',
endRadius: 'path,bbox'
}
}
},
render: function () {
this.callSuper(arguments);
},
updatePath: function (path, attr) {
var startRadius = attr.startRadius,
endRadius = attr.endRadius;
path.moveTo(startRadius, 0);
path.lineTo(endRadius, 0);
}
});

View file

@ -0,0 +1,43 @@
/**
* @class Ext.chart.grid.VerticalGrid
* @extends Ext.draw.sprite.Sprite
*
* Vertical Grid sprite. Used in Cartesian Charts.
*/
Ext.define("Ext.chart.grid.VerticalGrid", {
extend: 'Ext.draw.sprite.Sprite',
alias: 'grid.vertical',
inheritableStatics: {
def: {
processors: {
x: 'number',
y: 'number',
width: 'number',
height: 'number'
},
defaults: {
x: 0,
y: 0,
width: 1,
height: 1,
strokeStyle: '#DDD'
}
}
},
render: function (surface, ctx, clipRegion) {
var attr = this.attr,
x = surface.roundPixel(attr.x),
halfLineWidth = ctx.lineWidth * 0.5;
ctx.beginPath();
ctx.rect(x - halfLineWidth, clipRegion[1] - surface.matrix.getDY(), attr.width, clipRegion[3]);
ctx.fill();
ctx.beginPath();
ctx.moveTo(x - halfLineWidth, clipRegion[1] - surface.matrix.getDY());
ctx.lineTo(x - halfLineWidth, clipRegion[1] + clipRegion[3] - surface.matrix.getDY());
ctx.stroke();
}
});

View file

@ -0,0 +1,246 @@
/**
* @class Ext.chart.interactions.Abstract
*
* Defines a common abstract parent class for all interactions.
*
*/
Ext.define('Ext.chart.interactions.Abstract', {
xtype: 'interaction',
mixins: {
observable: 'Ext.mixin.Observable'
},
config: {
/**
* @cfg {String} gesture
* Specifies which gesture type should be used for starting the interaction.
*/
gesture: 'tap',
/**
* @cfg {Ext.chart.AbstractChart} chart The chart that the interaction is bound.
*/
chart: null,
/**
* @cfg {Boolean} enabled 'true' if the interaction is enabled.
*/
enabled: true
},
/**
* Android device is emerging too many events so if we re-render every frame it will take for-ever to finish a frame.
* This throttle technique will limit the timespan between two frames.
*/
throttleGap: 0,
stopAnimationBeforeSync: false,
constructor: function (config) {
var me = this;
me.initConfig(config);
Ext.ComponentManager.register(this);
},
/**
* @protected
* A method to be implemented by subclasses where all event attachment should occur.
*/
initialize: Ext.emptyFn,
updateChart: function (newChart, oldChart) {
var me = this, gestures = me.getGestures();
if (oldChart) {
me.removeChartListener(oldChart);
}
if (newChart) {
me.addChartListener();
}
},
updateEnabled: function (enabled) {
var me = this,
chart = me.getChart();
if (chart) {
if (enabled) {
me.addChartListener();
} else {
me.removeChartListener(chart);
}
}
},
getGestures: function () {
var gestures = {};
gestures[this.getGesture()] = this.onGesture;
return gestures;
},
/**
* @protected
* Placeholder method.
*/
onGesture: Ext.emptyFn,
/**
* @protected Find and return a single series item corresponding to the given event,
* or null if no matching item is found.
* @param {Event} e
* @return {Object} the item object or null if none found.
*/
getItemForEvent: function (e) {
var me = this,
chart = me.getChart(),
chartXY = chart.getEventXY(e);
return chart.getItemForPoint(chartXY[0], chartXY[1]);
},
/**
* @protected Find and return all series items corresponding to the given event.
* @param {Event} e
* @return {Array} array of matching item objects
*/
getItemsForEvent: function (e) {
var me = this,
chart = me.getChart(),
chartXY = chart.getEventXY(e);
return chart.getItemsForPoint(chartXY[0], chartXY[1]);
},
/**
* @private
*/
addChartListener: function () {
var me = this,
chart = me.getChart(),
gestures = me.getGestures(),
gesture;
if (!me.getEnabled()) {
return;
}
function insertGesture(name, fn) {
chart.on(
name,
// wrap the handler so it does not fire if the event is locked by another interaction
me.listeners[name] = function (e) {
var locks = me.getLocks(), result;
if (me.getEnabled() && (!(name in locks) || locks[name] === me)) {
result = (Ext.isFunction(fn) ? fn : me[fn]).apply(this, arguments);
if (result === false && e && e.stopPropagation) {
e.stopPropagation();
}
return result;
}
},
me
);
}
me.listeners = me.listeners || {};
for (gesture in gestures) {
insertGesture(gesture, gestures[gesture]);
}
},
removeChartListener: function (chart) {
var me = this,
gestures = me.getGestures(),
gesture;
function removeGesture(name) {
chart.un(name, me.listeners[name]);
delete me.listeners[name];
}
for (gesture in gestures) {
removeGesture(gesture);
}
},
lockEvents: function () {
var me = this,
locks = me.getLocks(),
args = Array.prototype.slice.call(arguments),
i = args.length;
while (i--) {
locks[args[i]] = me;
}
},
unlockEvents: function () {
var locks = this.getLocks(),
args = Array.prototype.slice.call(arguments),
i = args.length;
while (i--) {
delete locks[args[i]];
}
},
getLocks: function () {
var chart = this.getChart();
return chart.lockedEvents || (chart.lockedEvents = {});
},
isMultiTouch: function () {
if (Ext.browser.is.IE10) {
return true;
}
return !(Ext.os.is.MultiTouch === false || Ext.browser.is.AndroidStock2 || Ext.os.is.Desktop);
},
initializeDefaults: Ext.emptyFn,
doSync: function () {
var chart = this.getChart();
if (this.syncTimer) {
clearTimeout(this.syncTimer);
this.syncTimer = null;
}
if (this.stopAnimationBeforeSync) {
chart.resizing = true;
}
chart.redraw();
if (this.stopAnimationBeforeSync) {
chart.resizing = false;
}
this.syncThrottle = Date.now() + this.throttleGap;
},
sync: function () {
var me = this;
if (me.throttleGap && Ext.frameStartTime < me.syncThrottle) {
if (me.syncTimer) {
return;
}
me.syncTimer = setTimeout(function () {
me.doSync();
}, me.throttleGap);
} else {
me.doSync();
}
},
getItemId: function () {
return this.getId();
},
isXType: function (xtype) {
return xtype === 'interaction';
},
destroy: function () {
Ext.ComponentManager.unregister(this);
this.listeners = [];
this.callSuper();
}
}, function () {
if (Ext.browser.is.AndroidStock2) {
this.prototype.throttleGap = 20;
} else if (Ext.os.is.Android4) {
this.prototype.throttleGap = 40;
}
});

View file

@ -0,0 +1,409 @@
/**
* @class Ext.chart.interactions.CrossZoom
* @extends Ext.chart.interactions.Abstract
*
* The CrossZoom interaction allows the user to zoom in on a selected area of the chart.
*
* @example preview
* var lineChart = new Ext.chart.CartesianChart({
* interactions: [{
* type: 'crosszoom'
* }],
* animate: true,
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['data1'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* grid: true,
* minimum: 0
* }, {
* type: 'category',
* position: 'bottom',
* fields: ['name'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* }
* }],
* series: [{
* type: 'line',
* highlight: {
* size: 7,
* radius: 7
* },
* style: {
* stroke: 'rgb(143,203,203)'
* },
* xField: 'name',
* yField: 'data1',
* marker: {
* type: 'path',
* path: ['M', -2, 0, 0, 2, 2, 0, 0, -2, 'Z'],
* stroke: 'blue',
* lineWidth: 0
* }
* }, {
* type: 'line',
* highlight: {
* size: 7,
* radius: 7
* },
* fill: true,
* xField: 'name',
* yField: 'data3',
* marker: {
* type: 'circle',
* radius: 4,
* lineWidth: 0
* }
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(lineChart);
*/
Ext.define('Ext.chart.interactions.CrossZoom', {
extend: 'Ext.chart.interactions.Abstract',
type: 'crosszoom',
alias: 'interaction.crosszoom',
config: {
/**
* @cfg {Object/Array} axes
* Specifies which axes should be made navigable. The config value can take the following formats:
*
* - An Object whose keys correspond to the {@link Ext.chart.axis.Axis#position position} of each
* axis that should be made navigable. Each key's value can either be an Object with further
* configuration options for each axis or simply `true` for a default set of options.
* {
* type: 'crosszoom',
* axes: {
* left: {
* maxZoom: 5,
* allowPan: false
* },
* bottom: true
* }
* }
*
* If using the full Object form, the following options can be specified for each axis:
*
* - minZoom (Number) A minimum zoom level for the axis. Defaults to `1` which is its natural size.
* - maxZoom (Number) A maximum zoom level for the axis. Defaults to `10`.
* - startZoom (Number) A starting zoom level for the axis. Defaults to `1`.
* - allowZoom (Boolean) Whether zooming is allowed for the axis. Defaults to `true`.
* - allowPan (Boolean) Whether panning is allowed for the axis. Defaults to `true`.
* - startPan (Boolean) A starting panning offset for the axis. Defaults to `0`.
*
* - An Array of strings, each one corresponding to the {@link Ext.chart.axis.Axis#position position}
* of an axis that should be made navigable. The default options will be used for each named axis.
*
* {
* type: 'crosszoom',
* axes: ['left', 'bottom']
* }
*
* If the `axes` config is not specified, it will default to making all axes navigable with the
* default axis options.
*/
axes: true,
gesture: 'drag',
undoButton: {}
},
stopAnimationBeforeSync: false,
zoomAnimationInProgress: false,
constructor: function () {
this.callSuper(arguments);
this.zoomHistory = [];
},
applyAxes: function (axesConfig) {
var result = {};
if (axesConfig === true) {
return {
top: {},
right: {},
bottom: {},
left: {}
};
} else if (Ext.isArray(axesConfig)) {
// array of axis names - translate to full object form
result = {};
Ext.each(axesConfig, function (axis) {
result[axis] = {};
});
} else if (Ext.isObject(axesConfig)) {
Ext.iterate(axesConfig, function (key, val) {
// axis name with `true` value -> translate to object
if (val === true) {
result[key] = {};
} else if (val !== false) {
result[key] = val;
}
});
}
return result;
},
applyUndoButton: function (button, oldButton) {
var me = this;
if (button) {
if (oldButton) {
oldButton.destroy();
}
return Ext.create('Ext.Button', Ext.apply({
cls: [],
iconCls: 'refresh',
text: 'Undo Zoom',
disabled: true,
handler: function () {
me.undoZoom();
}
}, button));
} else if (oldButton) {
oldButton.destroy();
}
},
getGestures: function () {
var me = this,
gestures = {};
gestures[me.getGesture()] = 'onGesture';
gestures[me.getGesture() + 'start'] = 'onGestureStart';
gestures[me.getGesture() + 'end'] = 'onGestureEnd';
gestures.doubletap = 'onDoubleTap';
return gestures;
},
getSurface: function () {
return this.getChart() && this.getChart().getSurface('main');
},
setSeriesOpacity: function (opacity) {
var surface = this.getChart() && this.getChart().getSurface('series-surface', 'series');
if (surface) {
surface.element.setStyle('opacity', opacity);
}
},
onGestureStart: function (e) {
var me = this,
chart = me.getChart(),
surface = me.getSurface(),
region = chart.getInnerRegion(),
chartWidth = region[2],
chartHeight = region[3],
xy = chart.element.getXY(),
x = e.pageX - xy[0] - region[0],
y = e.pageY - xy[1] - region[1];
if (me.zoomAnimationInProgress) {
return;
}
if (x > 0 && x < chartWidth && y > 0 && y < chartHeight) {
me.lockEvents(me.getGesture());
me.startX = x;
me.startY = y;
me.selectionRect = surface.add({
type: 'rect',
globalAlpha: 0.5,
fillStyle: 'rgba(80,80,140,0.5)',
strokeStyle: 'rgba(80,80,140,1)',
lineWidth: 2,
x: x,
y: y,
width: 0,
height: 0,
zIndex: 10000
});
me.setSeriesOpacity(0.8);
return false;
}
},
onGesture: function (e) {
var me = this;
if (me.zoomAnimationInProgress) {
return;
}
if (me.getLocks()[me.getGesture()] === me) {
var chart = me.getChart(),
surface = me.getSurface(),
region = chart.getInnerRegion(),
chartWidth = region[2],
chartHeight = region[3],
xy = chart.element.getXY(),
x = e.pageX - xy[0] - region[0],
y = e.pageY - xy[1] - region[1];
if (x < 0) {
x = 0;
} else if (x > chartWidth) {
x = chartWidth;
}
if (y < 0) {
y = 0;
} else if (y > chartHeight) {
y = chartHeight;
}
me.selectionRect.setAttributes({
width: x - me.startX,
height: y - me.startY
});
if (Math.abs(me.startX - x) < 11 || Math.abs(me.startY - y) < 11) {
me.selectionRect.setAttributes({globalAlpha: 0.5});
} else {
me.selectionRect.setAttributes({globalAlpha: 1});
}
surface.renderFrame();
return false;
}
},
onGestureEnd: function (e) {
var me = this;
if (me.zoomAnimationInProgress) {
return;
}
if (me.getLocks()[me.getGesture()] === me) {
var chart = me.getChart(),
surface = me.getSurface(),
region = chart.getInnerRegion(),
chartWidth = region[2],
chartHeight = region[3],
xy = chart.element.getXY(),
x = e.pageX - xy[0] - region[0],
y = e.pageY - xy[1] - region[1];
if (x < 0) {
x = 0;
} else if (x > chartWidth) {
x = chartWidth;
}
if (y < 0) {
y = 0;
} else if (y > chartHeight) {
y = chartHeight;
}
if (Math.abs(me.startX - x) < 11 || Math.abs(me.startY - y) < 11) {
surface.remove(me.selectionRect);
} else {
me.zoomBy([
Math.min(me.startX, x) / chartWidth,
1 - Math.max(me.startY, y) / chartHeight,
Math.max(me.startX, x) / chartWidth,
1 - Math.min(me.startY, y) / chartHeight
]);
me.selectionRect.setAttributes({
x: Math.min(me.startX, x),
y: Math.min(me.startY, y),
width: Math.abs(me.startX - x),
height: Math.abs(me.startY - y)
});
me.selectionRect.fx.setConfig(chart.getAnimate() || {duration: 0});
me.selectionRect.setAttributes({
globalAlpha: 0,
x: 0,
y: 0,
width: chartWidth,
height: chartHeight
});
me.zoomAnimationInProgress = true;
chart.suspendThicknessChanged();
me.selectionRect.fx.on('animationend', function () {
chart.resumeThicknessChanged();
surface.remove(me.selectionRect);
me.selectionRect = null;
me.zoomAnimationInProgress = false;
});
}
surface.renderFrame();
me.sync();
me.unlockEvents(me.getGesture());
me.setSeriesOpacity(1.0);
if (!me.zoomAnimationInProgress) {
surface.remove(me.selectionRect);
me.selectionRect = null;
}
}
},
zoomBy: function (region) {
var me = this,
axisConfigs = me.getAxes(),
axes = me.getChart().getAxes(),
config,
zoomMap = {};
for (var i = 0; i < axes.length; i++) {
var axis = axes[i];
config = axisConfigs[axis.getPosition()];
if (config && config.allowZoom !== false) {
var isSide = axis.isSide(),
oldRange = axis.getVisibleRange();
zoomMap[axis.getId()] = oldRange.slice(0);
if (!isSide) {
axis.setVisibleRange([
(oldRange[1] - oldRange[0]) * region[0] + oldRange[0],
(oldRange[1] - oldRange[0]) * region[2] + oldRange[0]
]);
} else {
axis.setVisibleRange([
(oldRange[1] - oldRange[0]) * region[1] + oldRange[0],
(oldRange[1] - oldRange[0]) * region[3] + oldRange[0]
]);
}
}
}
me.zoomHistory.push(zoomMap);
me.getUndoButton().setDisabled(false);
},
undoZoom: function () {
var zoomMap = this.zoomHistory.pop(),
axes = this.getChart().getAxes();
if (zoomMap) {
for (var i = 0; i < axes.length; i++) {
var axis = axes[i];
if (zoomMap[axis.getId()]) {
axis.setVisibleRange(zoomMap[axis.getId()]);
}
}
}
this.getUndoButton().setDisabled(this.zoomHistory.length === 0);
this.sync();
},
onDoubleTap: function (e) {
this.undoZoom();
}
});

View file

@ -0,0 +1,410 @@
/**
* The Crosshair interaction allows the user to get precise values for a specific point on the chart.
* The values are obtained by single-touch dragging on the chart.
*
* @example preview
* var lineChart = Ext.create('Ext.chart.CartesianChart', {
* innerPadding: 20,
* interactions: [{
* type: 'crosshair',
* axes: {
* left: {
* label: {
* fillStyle: 'white'
* },
* rect: {
* fillStyle: 'brown',
* radius: 6
* }
* },
* bottom: {
* label: {
* fontSize: '14px',
* fontWeight: 'bold'
* }
* }
* },
* lines: {
* horizontal: {
* strokeStyle: 'brown',
* lineWidth: 2,
* lineDash: [20, 2, 2, 2, 2, 2, 2, 2]
* }
* }
* }],
* store: {
* fields: ['name', 'data'],
* data: [
* {name: 'apple', data: 300},
* {name: 'orange', data: 900},
* {name: 'banana', data: 800},
* {name: 'pear', data: 400},
* {name: 'grape', data: 500}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['data'],
* title: {
* text: 'Value',
* fontSize: 15
* },
* grid: true,
* label: {
* rotationRads: -Math.PI / 4
* }
* }, {
* type: 'category',
* position: 'bottom',
* fields: ['name'],
* title: {
* text: 'Category',
* fontSize: 15
* }
* }],
* series: [{
* type: 'line',
* style: {
* strokeStyle: 'black'
* },
* xField: 'name',
* yField: 'data',
* marker: {
* type: 'circle',
* radius: 5,
* fillStyle: 'lightblue'
* }
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(lineChart);
*/
Ext.define('Ext.chart.interactions.Crosshair', {
extend: 'Ext.chart.interactions.Abstract',
requires: [
'Ext.chart.grid.HorizontalGrid',
'Ext.chart.grid.VerticalGrid',
'Ext.chart.CartesianChart',
'Ext.chart.axis.layout.Discrete'
],
type: 'crosshair',
alias: 'interaction.crosshair',
config: {
/**
* @cfg {Object} axes
* Specifies label text and label rect configs on per axis basis or as a single config for all axes.
*
* {
* type: 'crosshair',
* axes: {
* label: { fillStyle: 'white' },
* rect: { fillStyle: 'maroon'}
* }
* }
*
* In case per axis configuration is used, an object with keys corresponding
* to the {@link Ext.chart.axis.Axis#position position} must be provided.
*
* {
* type: 'crosshair',
* axes: {
* left: {
* label: { fillStyle: 'white' },
* rect: {
* fillStyle: 'maroon',
* radius: 4
* }
* },
* bottom: {
* label: {
* fontSize: '14px',
* fontWeight: 'bold'
* },
* rect: { fillStyle: 'white' }
* }
* }
*
* If the `axes` config is not specified, the following defaults will be used:
* - `label` will use values from the {@link Ext.chart.axis.Axis#label label} config.
* - `rect` will use the 'white' fillStyle.
*/
axes: {
top: {label: {}, rect: {}},
right: {label: {}, rect: {}},
bottom: {label: {}, rect: {}},
left: {label: {}, rect: {}}
},
/**
* @cfg {Object} lines
* Specifies attributes of horizontal and vertical lines that make up the crosshair.
* If this config is missing, black dashed lines will be used.
*
* {
* horizontal: {
* strokeStyle: 'red',
* lineDash: [] // solid line
* },
* vertical: {
* lineWidth: 2,
* lineDash: [15, 5, 5, 5]
* }
* }
*/
lines: {
horizontal: {
strokeStyle: 'black',
lineDash: [5, 5]
},
vertical: {
strokeStyle: 'black',
lineDash: [5, 5]
}
},
gesture: 'drag'
},
applyAxes: function (axesConfig, oldAxesConfig) {
return Ext.merge(oldAxesConfig || {}, axesConfig);
},
applyLines: function (linesConfig, oldLinesConfig) {
return Ext.merge(oldLinesConfig || {}, linesConfig);
},
updateChart: function (chart) {
if (!(chart instanceof Ext.chart.CartesianChart)) {
throw 'Crosshair interaction can only be used on cartesian charts.';
}
this.callParent(arguments);
},
getGestures: function () {
var me = this,
gestures = {};
gestures[me.getGesture()] = 'onGesture';
gestures[me.getGesture() + 'start'] = 'onGestureStart';
gestures[me.getGesture() + 'end'] = 'onGestureEnd';
return gestures;
},
onGestureStart: function (e) {
var me = this,
chart = me.getChart(),
surface = chart.getSurface('overlay-surface'),
region = chart.getInnerRegion(),
chartWidth = region[2],
chartHeight = region[3],
xy = chart.element.getXY(),
x = e.pageX - xy[0] - region[0],
y = e.pageY - xy[1] - region[1],
axes = chart.getAxes(),
axesConfig = me.getAxes(),
linesConfig = me.getLines(),
axis, axisSurface, axisRegion, axisWidth, axisHeight, axisPosition,
axisLabel, labelPadding,
axisSprite, attr, axisThickness, lineWidth, halfLineWidth,
i;
if (x > 0 && x < chartWidth && y > 0 && y < chartHeight) {
me.lockEvents(me.getGesture());
me.horizontalLine = surface.add(Ext.apply({
xclass: 'Ext.chart.grid.HorizontalGrid',
x: 0,
y: y,
width: chartWidth
}, linesConfig.horizontal));
me.verticalLine = surface.add(Ext.apply({
xclass: 'Ext.chart.grid.VerticalGrid',
x: x,
y: 0,
height: chartHeight
}, linesConfig.vertical));
me.axesLabels = me.axesLabels || {};
for (i = 0; i < axes.length; i++) {
axis = axes[i];
axisSurface = axis.getSurface();
axisRegion = axisSurface.getRegion();
axisSprite = axis.getSprites()[0];
axisWidth = axisRegion[2];
axisHeight = axisRegion[3];
axisPosition = axis.getPosition();
attr = axisSprite.attr;
axisThickness = axisSprite.thickness;
lineWidth = attr.axisLine ? attr.lineWidth : 0;
halfLineWidth = lineWidth / 2;
labelPadding = Math.max(attr.majorTickSize, attr.minorTickSize) + lineWidth;
axisLabel = me.axesLabels[axisPosition] = axisSurface.add({type: 'composite'});
axisLabel.labelRect = axisLabel.add(Ext.apply({
type: 'rect',
fillStyle: 'white',
x: axisPosition === 'right' ? lineWidth : axisSurface.roundPixel(axisWidth - axisThickness - labelPadding) - halfLineWidth,
y: axisPosition === 'bottom' ? lineWidth : axisSurface.roundPixel(axisHeight - axisThickness - labelPadding) - lineWidth,
width: axisPosition === 'left' ? axisThickness - halfLineWidth + labelPadding : axisThickness + labelPadding,
height: axisPosition === 'top' ? axisThickness + labelPadding : axisThickness + labelPadding
}, axesConfig.rect || axesConfig[axisPosition].rect));
axisLabel.labelText = axisLabel.add(Ext.apply(Ext.Object.chain(axis.config.label), axesConfig.label || axesConfig[axisPosition].label, {
type: 'text',
x: (function () {
switch (axisPosition) {
case 'left':
return axisWidth - labelPadding - halfLineWidth - axisThickness / 2;
case 'right':
return axisThickness / 2 + labelPadding - halfLineWidth;
default:
return 0;
}
})(),
y: (function () {
switch (axisPosition) {
case 'top':
return axisHeight - labelPadding - halfLineWidth - axisThickness / 2;
case 'bottom':
return axisThickness / 2 + labelPadding;
default:
return 0;
}
})()
}));
}
return false;
}
},
onGesture: function (e) {
var me = this;
if (me.getLocks()[me.getGesture()] !== me) {
return;
}
var chart = me.getChart(),
surface = chart.getSurface('overlay-surface'),
region = Ext.Array.slice(chart.getInnerRegion()),
padding = chart.getInnerPadding(),
px = padding.left,
py = padding.top,
chartWidth = region[2],
chartHeight = region[3],
xy = chart.element.getXY(),
x = e.pageX - xy[0] - region[0],
y = e.pageY - xy[1] - region[1],
axes = chart.getAxes(),
axis, axisPosition, axisAlignment, axisSurface, axisSprite, axisMatrix,
axisLayoutContext, axisSegmenter,
axisLabel, labelBBox, textPadding,
xx, yy, dx, dy,
xValue, yValue,
text,
i;
if (x < 0) {
x = 0;
} else if (x > chartWidth) {
x = chartWidth;
}
if (y < 0) {
y = 0;
} else if (y > chartHeight) {
y = chartHeight;
}
x += px;
y += py;
for (i = 0; i < axes.length; i++) {
axis = axes[i];
axisPosition = axis.getPosition();
axisAlignment = axis.getAlignment();
axisSurface = axis.getSurface();
axisSprite = axis.getSprites()[0];
axisMatrix = axisSprite.attr.matrix;
textPadding = axisSprite.attr.textPadding * 2;
axisLabel = me.axesLabels[axisPosition];
axisLayoutContext = axisSprite.getLayoutContext();
axisSegmenter = axis.getSegmenter();
if (axisLabel) {
if (axisAlignment === 'vertical') {
yy = axisMatrix.getYY();
dy = axisMatrix.getDY();
yValue = (y - dy - py) / yy;
if (axis.getLayout() instanceof Ext.chart.axis.layout.Discrete) {
y = Math.round(yValue) * yy + dy + py;
yValue = axisSegmenter.from(Math.round(yValue));
yValue = axisSprite.attr.data[yValue];
} else {
yValue = axisSegmenter.from(yValue);
}
text = axisSegmenter.renderer(yValue, axisLayoutContext);
axisLabel.setAttributes({translationY: y - py});
axisLabel.labelText.setAttributes({text: text});
labelBBox = axisLabel.labelText.getBBox();
axisLabel.labelRect.setAttributes({
height: labelBBox.height + textPadding,
y: -(labelBBox.height + textPadding) / 2
});
axisSurface.renderFrame();
} else {
xx = axisMatrix.getXX();
dx = axisMatrix.getDX();
xValue = (x - dx - px) / xx;
if (axis.getLayout() instanceof Ext.chart.axis.layout.Discrete) {
x = Math.round(xValue) * xx + dx + px;
xValue = axisSegmenter.from(Math.round(xValue));
xValue = axisSprite.attr.data[xValue];
} else {
xValue = axisSegmenter.from(xValue);
}
text = axisSegmenter.renderer(xValue, axisLayoutContext);
axisLabel.setAttributes({translationX: x - px});
axisLabel.labelText.setAttributes({text: text});
labelBBox = axisLabel.labelText.getBBox();
axisLabel.labelRect.setAttributes({
width: labelBBox.width + textPadding,
x: -(labelBBox.width + textPadding) / 2
});
axisSurface.renderFrame();
}
}
}
me.horizontalLine.setAttributes({y: y});
me.verticalLine.setAttributes({x: x});
surface.renderFrame();
return false;
},
onGestureEnd: function (e) {
var me = this,
chart = me.getChart(),
surface = chart.getSurface('overlay-surface'),
axes = chart.getAxes(),
axis, axisPosition, axisSurface, axisLabel,
i;
surface.remove(me.verticalLine);
surface.remove(me.horizontalLine);
for (i = 0; i < axes.length; i++) {
axis = axes[i];
axisPosition = axis.getPosition();
axisSurface = axis.getSurface();
axisLabel = me.axesLabels[axisPosition];
if (axisLabel) {
delete me.axesLabels[axisPosition];
axisSurface.remove(axisLabel);
}
axisSurface.renderFrame();
}
surface.renderFrame();
me.unlockEvents(me.getGesture());
}
});

View file

@ -0,0 +1,38 @@
/**
* @class Ext.chart.interactions.ItemHighlight
* @extends Ext.chart.interactions.Abstract
*
* The ItemHighlight interaction allows the user to highlight series items in the chart.
*/
Ext.define('Ext.chart.interactions.ItemHighlight', {
extend: 'Ext.chart.interactions.Abstract',
type: 'itemhighlight',
alias: 'interaction.itemhighlight',
config: {
/**
* @cfg {String} gesture
* Defines the gesture type that should trigger item highlighting.
*/
gesture: 'tap'
},
getGestures: function () {
var gestures = {};
gestures['item' + this.getGesture()] = 'onGesture';
gestures[this.getGesture()] = 'onFailedGesture';
return gestures;
},
onGesture: function (series, item, e) {
e.highlightItem = item;
return false;
},
onFailedGesture: function (e) {
this.getChart().setHighlightItem(e.highlightItem || null);
this.sync();
}
});

View file

@ -0,0 +1,107 @@
/**
* The ItemInfo interaction allows displaying detailed information about a series data
* point in a popup panel.
*
* To attach this interaction to a chart, include an entry in the chart's
* {@link Ext.chart.AbstractChart#interactions interactions} config with the `iteminfo` type:
*
* new Ext.chart.AbstractChart({
* renderTo: Ext.getBody(),
* width: 800,
* height: 600,
* store: store1,
* axes: [ ...some axes options... ],
* series: [ ...some series options... ],
* interactions: [{
* type: 'iteminfo',
* listeners: {
* show: function(me, item, panel) {
* panel.setHtml('Stock Price: $' + item.record.get('price'));
* }
* }
* }]
* });
*/
Ext.define('Ext.chart.interactions.ItemInfo', {
extend: 'Ext.chart.interactions.Abstract',
type: 'iteminfo',
alias: 'interaction.iteminfo',
/**
* @event show
* Fires when the info panel is shown.
* @param {Ext.chart.interactions.ItemInfo} this The interaction instance
* @param {Object} item The item whose info is being displayed
* @param {Ext.Panel} panel The panel for displaying the info
*/
config: {
/**
* @cfg {String} gesture
* Defines the gesture type that should trigger the item info panel to be displayed.
*/
gesture: 'itemtap',
/**
* @cfg {Object} panel
* An optional set of configuration overrides for the {@link Ext.Panel} that gets
* displayed. This object will be merged with the default panel configuration.
*/
panel: {
modal: true,
centered: true,
width: 250,
height: 300,
styleHtmlContent: true,
scrollable: 'vertical',
hideOnMaskTap: true,
fullscreen: false,
hidden: true,
zIndex: 30,
items: [
{
docked: 'top',
xtype: 'toolbar',
title: 'Item Detail'
}
]
}
},
applyPanel: function (panel, oldPanel) {
return Ext.factory(panel, 'Ext.Panel', oldPanel);
},
updatePanel: function (panel, oldPanel) {
if (panel) {
panel.on('hide', "reset", this);
}
if (oldPanel) {
oldPanel.un('hide', "reset", this);
}
},
onGesture: function (series, item) {
var me = this,
panel = me.getPanel();
me.item = item;
me.fireEvent('show', me, item, panel);
Ext.Viewport.add(panel);
panel.show('pop');
series.setAttributesForItem(item, { highlighted: true });
me.sync();
return false;
},
reset: function () {
var me = this,
item = me.item;
if (item) {
item.series.setAttributesForItem(item, { highlighted: false });
delete me.item;
me.sync();
}
}
});

View file

@ -0,0 +1,502 @@
/**
* The PanZoom interaction allows the user to navigate the data for one or more chart
* axes by panning and/or zooming. Navigation can be limited to particular axes. Zooming is
* performed by pinching on the chart or axis area; panning is performed by single-touch dragging.
*
* For devices which do not support multiple-touch events, zooming can not be done via pinch gestures; in this case the
* interaction will allow the user to perform both zooming and panning using the same single-touch drag gesture.
* {@link #modeToggleButton} provides a button to indicate and toggle between two modes.
*
* @example preview
* var lineChart = new Ext.chart.CartesianChart({
* interactions: [{
* type: 'panzoom',
* zoomOnPanGesture: true
* }],
* animate: true,
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['data1'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* grid: true,
* minimum: 0
* }, {
* type: 'category',
* position: 'bottom',
* fields: ['name'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* }
* }],
* series: [{
* type: 'line',
* highlight: {
* size: 7,
* radius: 7
* },
* style: {
* stroke: 'rgb(143,203,203)'
* },
* xField: 'name',
* yField: 'data1',
* marker: {
* type: 'path',
* path: ['M', -2, 0, 0, 2, 2, 0, 0, -2, 'Z'],
* stroke: 'blue',
* lineWidth: 0
* }
* }, {
* type: 'line',
* highlight: {
* size: 7,
* radius: 7
* },
* fill: true,
* xField: 'name',
* yField: 'data3',
* marker: {
* type: 'circle',
* radius: 4,
* lineWidth: 0
* }
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(lineChart);
*
* The configuration object for the `panzoom` interaction type should specify which axes
* will be made navigable via the `axes` config. See the {@link #axes} config documentation
* for details on the allowed formats. If the `axes` config is not specified, it will default
* to making all axes navigable with the default axis options.
*
*/
Ext.define('Ext.chart.interactions.PanZoom', {
extend: 'Ext.chart.interactions.Abstract',
type: 'panzoom',
alias: 'interaction.panzoom',
requires: [
'Ext.util.Region',
'Ext.draw.Animator'
],
config: {
/**
* @cfg {Object/Array} axes
* Specifies which axes should be made navigable. The config value can take the following formats:
*
* - An Object with keys corresponding to the {@link Ext.chart.axis.Axis#position position} of each
* axis that should be made navigable. Each key's value can either be an Object with further
* configuration options for each axis or simply `true` for a default set of options.
*
* {
* type: 'panzoom',
* axes: {
* left: {
* maxZoom: 5,
* allowPan: false
* },
* bottom: true
* }
* }
*
* If using the full Object form, the following options can be specified for each axis:
*
* - minZoom (Number) A minimum zoom level for the axis. Defaults to `1` which is its natural size.
* - maxZoom (Number) A maximum zoom level for the axis. Defaults to `10`.
* - startZoom (Number) A starting zoom level for the axis. Defaults to `1`.
* - allowZoom (Boolean) Whether zooming is allowed for the axis. Defaults to `true`.
* - allowPan (Boolean) Whether panning is allowed for the axis. Defaults to `true`.
* - startPan (Boolean) A starting panning offset for the axis. Defaults to `0`.
*
* - An Array of strings, each one corresponding to the {@link Ext.chart.axis.Axis#position position}
* of an axis that should be made navigable. The default options will be used for each named axis.
*
* {
* type: 'panzoom',
* axes: ['left', 'bottom']
* }
*
* If the `axes` config is not specified, it will default to making all axes navigable with the
* default axis options.
*/
axes: {
top: {},
right: {},
bottom: {},
left: {}
},
minZoom: null,
maxZoom: null,
/**
* @cfg {Boolean} showOverflowArrows
* If `true`, arrows will be conditionally shown at either end of each axis to indicate that the
* axis is overflowing and can therefore be panned in that direction. Set this to `false` to
* prevent the arrows from being displayed.
*/
showOverflowArrows: true,
/**
* @cfg {Object} overflowArrowOptions
* A set of optional overrides for the overflow arrow sprites' options. Only relevant when
* {@link #showOverflowArrows} is `true`.
*/
gesture: 'pinch',
panGesture: 'drag',
zoomOnPanGesture: false,
modeToggleButton: {
cls: ['x-panzoom-toggle', 'x-zooming'],
iconCls: 'expand'
},
hideLabelInGesture: false //Ext.os.is.Android
},
stopAnimationBeforeSync: true,
applyAxes: function (axesConfig, oldAxesConfig) {
return Ext.merge(oldAxesConfig || {}, axesConfig);
},
applyZoomOnPanGesture: function (zoomOnPanGesture) {
this.getChart();
if (this.isMultiTouch()) {
return false;
}
return zoomOnPanGesture;
},
updateZoomOnPanGesture: function (zoomOnPanGesture) {
if (!this.isMultiTouch()) {
var button = this.getModeToggleButton(),
zoomModeCls = Ext.baseCSSPrefix + 'zooming';
if (zoomOnPanGesture) {
button.addCls(zoomModeCls);
if (!button.config.hideText) {
button.setText('Zoom');
}
} else {
button.removeCls(zoomModeCls);
if (!button.config.hideText) {
button.setText('Pan');
}
}
}
},
toggleMode: function () {
var me = this;
if (!me.isMultiTouch()) {
me.setZoomOnPanGesture(!me.getZoomOnPanGesture());
}
},
applyModeToggleButton: function (button, oldButton) {
var me = this,
result = Ext.factory(button, "Ext.Button", oldButton);
if (result && !oldButton) {
result.setHandler(function () {
me.toggleMode();
});
}
return result;
},
getGestures: function () {
var me = this,
gestures = {};
gestures[me.getGesture()] = 'onGesture';
gestures[me.getGesture() + 'start'] = 'onGestureStart';
gestures[me.getGesture() + 'end'] = 'onGestureEnd';
gestures[me.getPanGesture()] = 'onPanGesture';
gestures[me.getPanGesture() + 'start'] = 'onPanGestureStart';
gestures[me.getPanGesture() + 'end'] = 'onPanGestureEnd';
gestures.doubletap = 'onDoubleTap';
return gestures;
},
onDoubleTap: function (e) {
},
onPanGestureStart: function (e) {
if (!e || !e.touches || e.touches.length < 2) { //Limit drags to single touch
var me = this,
region = me.getChart().getInnerRegion(),
xy = me.getChart().element.getXY();
me.startX = e.pageX - xy[0] - region[0];
me.startY = e.pageY - xy[1] - region[1];
me.oldVisibleRanges = null;
me.hideLabels();
me.getChart().suspendThicknessChanged();
me.lockEvents(me.getPanGesture());
return false;
}
},
onPanGesture: function (e) {
if (this.getLocks()[this.getPanGesture()] === this) { //Limit drags to single touch
var me = this,
region = me.getChart().getInnerRegion(),
xy = me.getChart().element.getXY();
if (me.getZoomOnPanGesture()) {
me.transformAxesBy(me.getZoomableAxes(e), 0, 0, (e.pageX - xy[0] - region[0]) / me.startX, me.startY / (e.pageY - xy[1] - region[1]));
} else {
me.transformAxesBy(me.getPannableAxes(e), e.pageX - xy[0] - region[0] - me.startX, e.pageY - xy[1] - region[1] - me.startY, 1, 1);
}
me.sync();
return false;
}
},
onPanGestureEnd: function (e) {
var me = this;
if (this.getLocks()[this.getPanGesture()] === this) {
me.getChart().resumeThicknessChanged();
me.showLabels();
me.sync();
me.unlockEvents(me.getGestures());
return false;
}
},
onGestureStart: function (e) {
if (e.touches && e.touches.length === 2) {
var me = this,
xy = me.getChart().element.getXY(),
region = me.getChart().getInnerRegion(),
x = xy[0] + region[0],
y = xy[1] + region[1],
newPoints = [e.touches[0].point.x - x, e.touches[0].point.y - y, e.touches[1].point.x - x, e.touches[1].point.y - y],
xDistance = Math.max(44, Math.abs(newPoints[2] - newPoints[0])),
yDistance = Math.max(44, Math.abs(newPoints[3] - newPoints[1]));
me.getChart().suspendThicknessChanged();
me.lastZoomDistances = [xDistance, yDistance];
me.lastPoints = newPoints;
me.oldVisibleRanges = null;
me.hideLabels();
me.lockEvents(me.getGesture());
return false;
}
},
onGesture: function (e) {
if (this.getLocks()[this.getGesture()] === this) {
var me = this,
region = me.getChart().getInnerRegion(),
xy = me.getChart().element.getXY(),
x = xy[0] + region[0],
y = xy[1] + region[1],
abs = Math.abs,
lastPoints = me.lastPoints,
newPoints = [e.touches[0].point.x - x, e.touches[0].point.y - y, e.touches[1].point.x - x, e.touches[1].point.y - y],
xDistance = Math.max(44, abs(newPoints[2] - newPoints[0])),
yDistance = Math.max(44, abs(newPoints[3] - newPoints[1])),
lastDistances = this.lastZoomDistances || [xDistance, yDistance],
zoomX = xDistance / lastDistances[0],
zoomY = yDistance / lastDistances[1];
me.transformAxesBy(me.getZoomableAxes(e),
region[2] * (zoomX - 1) / 2 + newPoints[2] - lastPoints[2] * zoomX,
region[3] * (zoomY - 1) / 2 + newPoints[3] - lastPoints[3] * zoomY,
zoomX,
zoomY);
me.sync();
return false;
}
},
onGestureEnd: function (e) {
var me = this;
if (me.getLocks()[me.getGesture()] === me) {
me.getChart().resumeThicknessChanged();
me.showLabels();
me.sync();
me.unlockEvents(me.getGestures());
return false;
}
},
hideLabels: function () {
if (this.getHideLabelInGesture()) {
this.eachInteractiveAxes(function (axis) {
axis.hideLabels();
});
}
},
showLabels: function () {
if (this.getHideLabelInGesture()) {
this.eachInteractiveAxes(function (axis) {
axis.showLabels();
});
}
},
isEventOnAxis: function (e, axis) {
// TODO: right now this uses the current event position but really we want to only
// use the gesture's start event. Pinch does not give that to us though.
var region = axis.getSurface().getRegion();
return region[0] <= e.pageX && e.pageX <= region[0] + region[2] && region[1] <= e.pageY && e.pageY <= region[1] + region[3];
},
getPannableAxes: function (e) {
var me = this,
axisConfigs = me.getAxes(),
axes = me.getChart().getAxes(),
i, ln = axes.length,
result = [], isEventOnAxis = false,
config;
if (e) {
for (i = 0; i < ln; i++) {
if (this.isEventOnAxis(e, axes[i])) {
isEventOnAxis = true;
break;
}
}
}
for (i = 0; i < ln; i++) {
config = axisConfigs[axes[i].getPosition()];
if (config && config.allowPan !== false && (!isEventOnAxis || this.isEventOnAxis(e, axes[i]))) {
result.push(axes[i]);
}
}
return result;
},
getZoomableAxes: function (e) {
var me = this,
axisConfigs = me.getAxes(),
axes = me.getChart().getAxes(),
result = [],
i, ln = axes.length, axis,
isEventOnAxis = false, config;
if (e) {
for (i = 0; i < ln; i++) {
if (this.isEventOnAxis(e, axes[i])) {
isEventOnAxis = true;
break;
}
}
}
for (i = 0; i < ln; i++) {
axis = axes[i];
config = axisConfigs[axis.getPosition()];
if (config && config.allowZoom !== false && (!isEventOnAxis || this.isEventOnAxis(e, axis))) {
result.push(axis);
}
}
return result;
},
eachInteractiveAxes: function (fn) {
var me = this,
axisConfigs = me.getAxes(),
axes = me.getChart().getAxes();
for (var i = 0; i < axes.length; i++) {
if (axisConfigs[axes[i].getPosition()]) {
if (false === fn.call(this, axes[i])) {
return;
}
}
}
},
transformAxesBy: function (axes, panX, panY, sx, sy) {
var region = this.getChart().getInnerRegion(),
axesCfg = this.getAxes(), axisCfg,
oldVisibleRanges = this.oldVisibleRanges,
result = false;
if (!oldVisibleRanges) {
this.oldVisibleRanges = oldVisibleRanges = {};
this.eachInteractiveAxes(function (axis) {
oldVisibleRanges[axis.getId()] = axis.getVisibleRange();
});
}
if (!region) {
return;
}
for (var i = 0; i < axes.length; i++) {
axisCfg = axesCfg[axes[i].getPosition()];
result = this.transformAxisBy(axes[i], oldVisibleRanges[axes[i].getId()], panX, panY, sx, sy, this.minZoom || axisCfg.minZoom, this.maxZoom || axisCfg.maxZoom) || result;
}
return result;
},
transformAxisBy: function (axis, oldVisibleRange, panX, panY, sx, sy, minZoom, maxZoom) {
var me = this,
visibleLength = oldVisibleRange[1] - oldVisibleRange[0],
visibleRange = axis.getVisibleRange(),
actualMinZoom = minZoom || me.getMinZoom() || axis.config.minZoom,
actualMaxZoom = maxZoom || me.getMaxZoom() || axis.config.maxZoom,
region = me.getChart().getInnerRegion(),
left, right;
if (!region) {
return;
}
var isSide = axis.isSide(),
length = isSide ? region[3] : region[2],
pan = isSide ? -panY : panX;
visibleLength /= isSide ? sy : sx;
if (visibleLength < 0) {
visibleLength = -visibleLength;
}
if (visibleLength * actualMinZoom > 1) {
visibleLength = 1;
}
if (visibleLength * actualMaxZoom < 1) {
visibleLength = 1 / actualMaxZoom;
}
left = oldVisibleRange[0];
right = oldVisibleRange[1];
visibleRange = visibleRange[1] - visibleRange[0];
if (visibleLength === visibleRange && visibleRange === 1) {
return;
}
axis.setVisibleRange([
(oldVisibleRange[0] + oldVisibleRange[1] - visibleLength) * 0.5 - pan / length * visibleLength,
(oldVisibleRange[0] + oldVisibleRange[1] + visibleLength) * 0.5 - pan / length * visibleLength
]);
return (Math.abs(left - axis.getVisibleRange()[0]) > 1e-10 || Math.abs(right - axis.getVisibleRange()[1]) > 1e-10);
},
destroy: function () {
this.setModeToggleButton(null);
this.callSuper();
}
});

View file

@ -0,0 +1,197 @@
/**
* @class Ext.chart.interactions.Rotate
* @extends Ext.chart.interactions.Abstract
*
* The Rotate interaction allows the user to rotate a polar chart about its central point.
*
* @example preview
* var chart = new Ext.chart.PolarChart({
* animate: true,
* interactions: ['rotate'],
* colors: ["#115fa6", "#94ae0a", "#a61120", "#ff8809", "#ffd13e"],
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* series: [{
* type: 'pie',
* label: {
* field: 'name',
* display: 'rotate'
* },
* xField: 'data3',
* donut: 30
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*/
Ext.define('Ext.chart.interactions.Rotate', {
extend: 'Ext.chart.interactions.Abstract',
type: 'rotate',
alias: 'interaction.rotate',
/**
* @event rotate
* Fires on every tick of the rotation
* @param {Ext.chart.interactions.Rotate} this This interaction.
* @param {Number} angle The new current rotation angle.
*/
/**
* @event rotationEnd
* Fires after a user finishes the rotation
* @param {Ext.chart.interactions.Rotate} this This interaction.
* @param {Number} angle The new current rotation angle.
*/
config: {
/**
* @cfg {String} gesture
* Defines the gesture type that will be used to rotate the chart. Currently only
* supports `pinch` for two-finger rotation and `drag` for single-finger rotation.
*/
gesture: 'rotate',
/**
* @cfg {Number} currentRotation
* Saves the current rotation of the series. Accepts negative values and values > 360 ( / 180 * Math.PI)
* @private
*/
currentRotation: 0
},
oldRotations: null,
getGestures: function() {
return {
rotate: 'onRotate',
rotateend: 'onRotate',
dragstart: 'onGestureStart',
drag: 'onGesture',
dragend: 'onGestureEnd'
};
},
getAngle: function(e) {
var me = this,
chart = me.getChart(),
xy = chart.getEventXY(e),
center = chart.getCenter();
return Math.atan2(
xy[1] - center[1],
xy[0] - center[0]
);
},
getEventRadius: function(e) {
var me = this,
chart = me.getChart(),
xy = chart.getEventXY(e),
center = chart.getCenter(),
dx = xy[0] - center[0],
dy = xy[1] - center[1];
return Math.sqrt(dx * dx + dy * dy);
},
onGestureStart: function(e) {
var me = this,
chart = me.getChart(),
radius = chart.getRadius(),
eventRadius = me.getEventRadius(e);
if (radius >= eventRadius) {
me.lockEvents('drag');
me.angle = me.getAngle(e);
me.oldRotations = {};
return false;
}
},
onGesture: function(e) {
var me = this,
chart = me.getChart(),
angle = me.getAngle(e) - me.angle,
axes = chart.getAxes(),
series = chart.getSeries(), seriesItem,
oldRotations = me.oldRotations,
axis, oldRotation, i, ln;
if (me.getLocks().drag === me) {
chart.suspendAnimation();
for (i = 0, ln = axes.length; i < ln; i++) {
axis = axes[i];
oldRotation = oldRotations[axis.getId()] || (oldRotations[axis.getId()] = axis.getRotation());
axis.setRotation(angle + oldRotation);
}
for (i = 0, ln = series.length; i < ln; i++) {
seriesItem = series[i];
oldRotation = oldRotations[seriesItem.getId()] || (oldRotations[seriesItem.getId()] = seriesItem.getRotation());
seriesItem.setRotation(angle + oldRotation);
}
me.setCurrentRotation(angle + oldRotation);
me.fireEvent('rotate', me, me.getCurrentRotation());
me.sync();
chart.resumeAnimation();
return false;
}
},
rotateTo: function(angle) {
var me = this,
chart = me.getChart(),
axes = chart.getAxes(),
series = chart.getSeries(),
i, ln;
chart.suspendAnimation();
for (i = 0, ln = axes.length; i < ln; i++) {
axes[i].setRotation(angle);
}
for (i = 0, ln = series.length; i < ln; i++) {
series[i].setRotation(angle);
}
me.setCurrentRotation(angle);
me.fireEvent('rotate', me, me.getCurrentRotation());
me.sync();
chart.resumeAnimation();
},
onGestureEnd: function(e) {
var me = this;
if (me.getLocks().drag === me) {
me.onGesture(e);
me.unlockEvents('drag');
me.fireEvent('rotationEnd', me, me.getCurrentRotation());
return false;
}
},
onRotate: function(e) {
}
});

View file

@ -0,0 +1,22 @@
/**
* @class Ext.chart.interactions.RotatePie3D
* @extends Ext.chart.interactions.Rotate
*
* A special version of the Rotate interaction used by Pie3D Chart.
*/
Ext.define('Ext.chart.interactions.RotatePie3D', {
extend: 'Ext.chart.interactions.Rotate',
type: 'rotatePie3d',
alias: 'interaction.rotatePie3d',
getAngle: function (e) {
var me = this,
chart = me.getChart(),
xy = chart.element.getXY(),
region = chart.getMainRegion();
return Math.atan2(e.pageY - xy[1] - region[3] * 0.5, e.pageX - xy[0] - region[2] * 0.5);
}
});

107
vendor/touch/src/chart/label/Callout.js vendored Normal file
View file

@ -0,0 +1,107 @@
/**
* @class Ext.chart.label.Callout
* @extends Ext.draw.modifier.Modifier
*
* This is a modifier to place labels and callouts by additional attributes.
*/
Ext.define("Ext.chart.label.Callout", {
extend: 'Ext.draw.modifier.Modifier',
prepareAttributes: function (attr) {
if (!attr.hasOwnProperty('calloutOriginal')) {
attr.calloutOriginal = Ext.Object.chain(attr);
}
if (this._previous) {
this._previous.prepareAttributes(attr.calloutOriginal);
}
},
setAttrs: function (attr, changes) {
var callout = attr.callout,
origin = attr.calloutOriginal,
bbox = attr.bbox.plain,
width = (bbox.width || 0) + attr.labelOverflowPadding,
height = (bbox.height || 0) + attr.labelOverflowPadding,
dx, dy;
if ('callout' in changes) {
callout = changes.callout;
}
if ('callout' in changes || 'calloutPlaceX' in changes || 'calloutPlaceY' in changes || 'x' in changes || 'y' in changes) {
var rotationRads = 'rotationRads' in changes ? origin.rotationRads = changes.rotationRads : origin.rotationRads,
x = 'x' in changes ? (origin.x = changes.x) : origin.x,
y = 'y' in changes ? (origin.y = changes.y) : origin.y,
calloutPlaceX = 'calloutPlaceX' in changes ? changes.calloutPlaceX : attr.calloutPlaceX,
calloutPlaceY = 'calloutPlaceY' in changes ? changes.calloutPlaceY : attr.calloutPlaceY,
calloutVertical = 'calloutVertical' in changes ? changes.calloutVertical : attr.calloutVertical,
temp;
// Normalize Rotations
rotationRads %= Math.PI * 2;
if (Math.cos(rotationRads) < 0) {
rotationRads = (rotationRads + Math.PI) % (Math.PI * 2);
}
if (rotationRads > Math.PI) {
rotationRads -= Math.PI * 2;
}
if (calloutVertical) {
rotationRads = rotationRads * (1 - callout) - Math.PI / 2 * callout;
temp = width;
width = height;
height = temp;
} else {
rotationRads = rotationRads * (1 - callout);
}
changes.rotationRads = rotationRads;
// Placing label.
changes.x = x * (1 - callout) + calloutPlaceX * callout;
changes.y = y * (1 - callout) + calloutPlaceY * callout;
// Placing the end of the callout line.
dx = calloutPlaceX - x;
dy = calloutPlaceY - y;
if (Math.abs(dy * width) > Math.abs(height * dx)) {
// on top/bottom
if (dy > 0) {
changes.calloutEndX = changes.x - (height / (dy * 2) * dx) * callout;
changes.calloutEndY = changes.y - height / 2 * callout;
} else {
changes.calloutEndX = changes.x + (height / (dy * 2) * dx) * callout;
changes.calloutEndY = changes.y + height / 2 * callout;
}
} else {
// on left/right
if (dx > 0) {
changes.calloutEndX = changes.x - width / 2;
changes.calloutEndY = changes.y - (width / (dx * 2) * dy) * callout;
} else {
changes.calloutEndX = changes.x + width / 2;
changes.calloutEndY = changes.y + (width / (dx * 2) * dy) * callout;
}
}
}
return changes;
},
pushDown: function (attr, changes) {
changes = Ext.draw.modifier.Modifier.prototype.pushDown.call(this, attr.calloutOriginal, changes);
return this.setAttrs(attr, changes);
},
popUp: function (attr, changes) {
attr = Object.getPrototypeOf(attr);
changes = this.setAttrs(attr, changes);
if (this._next) {
return this._next.popUp(attr, changes);
} else {
return Ext.apply(attr, changes);
}
}
});

105
vendor/touch/src/chart/label/Label.js vendored Normal file
View file

@ -0,0 +1,105 @@
/**
* @class Ext.chart.label.Label
* @extends Ext.draw.sprite.Text
*
* Sprite used to represent labels in series.
*/
Ext.define('Ext.chart.label.Label', {
extend: 'Ext.draw.sprite.Text',
requires: ['Ext.chart.label.Callout'],
inheritableStatics: {
def: {
processors: {
callout: 'limited01',
calloutPlaceX: 'number',
calloutPlaceY: 'number',
calloutStartX: 'number',
calloutStartY: 'number',
calloutEndX: 'number',
calloutEndY: 'number',
calloutColor: 'color',
calloutVertical: 'bool',
labelOverflowPadding: 'number',
display: 'enums(none,under,over,rotate,insideStart,insideEnd,outside)',
orientation: 'enums(horizontal,vertical)',
renderer: 'default'
},
defaults: {
callout: 0,
calloutPlaceX: 0,
calloutPlaceY: 0,
calloutStartX: 0,
calloutStartY: 0,
calloutEndX: 0,
calloutEndY: 0,
calloutVertical: false,
calloutColor: 'black',
labelOverflowPadding: 5,
display: 'none',
orientation: '',
renderer: null
},
dirtyTriggers: {
callout: 'transform',
calloutPlaceX: 'transform',
calloutPlaceY: 'transform',
labelOverflowPadding: 'transform',
calloutRotation: 'transform',
display: 'hidden'
},
updaters: {
hidden: function (attrs) {
attrs.hidden = attrs.display === 'none';
}
}
}
},
config: {
/**
* @cfg {Object} fx Animation configuration.
*/
fx: {
customDuration: {
callout: 200
}
},
field: null
},
prepareModifiers: function () {
this.callSuper(arguments);
this.calloutModifier = new Ext.chart.label.Callout({sprite: this});
this.fx.setNext(this.calloutModifier);
this.calloutModifier.setNext(this.topModifier);
},
render: function (surface, ctx, clipRegion) {
var me = this,
attr = me.attr;
ctx.save();
ctx.globalAlpha *= Math.max(0, attr.callout - 0.5) * 2;
if (ctx.globalAlpha > 0) {
ctx.strokeStyle = attr.calloutColor;
ctx.fillStyle = attr.calloutColor;
ctx.beginPath();
ctx.moveTo(me.attr.calloutStartX, me.attr.calloutStartY);
ctx.lineTo(me.attr.calloutEndX, me.attr.calloutEndY);
ctx.stroke();
ctx.beginPath();
ctx.arc(me.attr.calloutStartX, me.attr.calloutStartY, 1, 0, 2 * Math.PI, true);
ctx.fill();
ctx.beginPath();
ctx.arc(me.attr.calloutEndX, me.attr.calloutEndY, 1, 0, 2 * Math.PI, true);
ctx.fill();
}
ctx.restore();
Ext.draw.sprite.Text.prototype.render.apply(me, arguments);
}
});

61
vendor/touch/src/chart/series/Area.js vendored Normal file
View file

@ -0,0 +1,61 @@
/**
* @class Ext.chart.series.Area
* @extends Ext.chart.series.StackedCartesian
*
* Creates an Area Chart.
*
* @example preview
* var chart = new Ext.chart.CartesianChart({
* animate: true,
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['data1'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* grid: true,
* minimum: 0
* }, {
* type: 'category',
* position: 'bottom',
* fields: ['name'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* }
* }],
* series: [{
* type: 'area',
* subStyle: {
* fill: ['blue', 'green', 'red']
* },
* xField: 'name',
* yField: ['data1', 'data2', 'data3']
*
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*/
Ext.define('Ext.chart.series.Area', {
extend: 'Ext.chart.series.StackedCartesian',
alias: 'series.area',
type: 'area',
seriesType: 'areaSeries',
requires: ['Ext.chart.series.sprite.Area']
});

134
vendor/touch/src/chart/series/Bar.js vendored Normal file
View file

@ -0,0 +1,134 @@
/**
* @class Ext.chart.series.Bar
* @extends Ext.chart.series.StackedCartesian
*
* Creates a Bar Chart.
*
* @example preview
* var chart = new Ext.chart.Chart({
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* fields: 'data1'
* }, {
* type: 'category',
* position: 'bottom',
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* fields: 'name'
* }],
* series: [{
* type: 'bar',
* xField: 'name',
* yField: 'data1',
* style: {
* fill: 'blue'
* }
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*/
Ext.define('Ext.chart.series.Bar', {
extend: 'Ext.chart.series.StackedCartesian',
alias: 'series.bar',
type: 'bar',
seriesType: 'barSeries',
requires: [
'Ext.chart.series.sprite.Bar',
'Ext.draw.sprite.Rect'
],
config: {
/**
* @private
* @cfg {Object} itemInstancing Sprite template used for series.
*/
itemInstancing: {
type: 'rect',
fx: {
customDuration: {
x: 0,
y: 0,
width: 0,
height: 0,
radius: 0
}
}
}
},
getItemForPoint: function (x, y) {
if (this.getSprites()) {
var me = this,
chart = me.getChart(),
padding = chart.getInnerPadding();
// Convert the coordinates because the "items" sprites that draw the bars ignore the chart's InnerPadding.
// See also Ext.chart.series.sprite.Bar.getItemForPoint(x,y) regarding the series's vertical coordinate system.
//
// TODO: Cleanup the bar sprites.
arguments[0] = x - padding.left;
arguments[1] = y + padding.bottom;
return me.callParent(arguments);
}
},
updateXAxis: function (axis) {
axis.setLabelInSpan(true);
this.callSuper(arguments);
},
updateHidden: function (hidden) {
this.callParent(arguments);
this.updateStacked();
},
updateStacked: function (stacked) {
var sprites = this.getSprites(),
ln = sprites.length,
visible = [],
attrs = {}, i;
for (i = 0; i < ln; i++) {
if (!sprites[i].attr.hidden) {
visible.push(sprites[i]);
}
}
ln = visible.length;
if (this.getStacked()) {
attrs.groupCount = 1;
attrs.groupOffset = 0;
for (i = 0; i < ln; i++) {
visible[i].setAttributes(attrs);
}
} else {
attrs.groupCount = visible.length;
for (i = 0; i < ln; i++) {
attrs.groupOffset = i;
visible[i].setAttributes(attrs);
}
}
this.callSuper(arguments);
}
});

View file

@ -0,0 +1,100 @@
/**
* @class Ext.chart.series.CandleStick
* @extends Ext.chart.series.Cartesian
*
* Creates a candlestick or OHLC Chart.
*
* @example preview
* var chart = new Ext.chart.CartesianChart({
* animate: true,
* store: {
* fields: ['time', 'open', 'high', 'low', 'close'],
* data: [
* {'time':new Date('Jan 1 2010').getTime(), 'open':600, 'high':614, 'low':578, 'close':590},
* {'time':new Date('Jan 2 2010').getTime(), 'open':590, 'high':609, 'low':580, 'close':580},
* {'time':new Date('Jan 3 2010').getTime(), 'open':580, 'high':602, 'low':578, 'close':602},
* {'time':new Date('Jan 4 2010').getTime(), 'open':602, 'high':614, 'low':586, 'close':586},
* {'time':new Date('Jan 5 2010').getTime(), 'open':586, 'high':602, 'low':565, 'close':565}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['open', 'high', 'low', 'close'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* grid: true,
* minimum: 560,
* maximum: 640
* }, {
* type: 'time',
* position: 'bottom',
* fields: ['time'],
* fromDate: new Date('Dec 31 2009'),
* toDate: new Date('Jan 6 2010'),
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* style: {
* axisLine: false
* }
* }],
* series: [{
* type: 'candlestick',
* xField: 'time',
* openField: 'open',
* highField: 'high',
* lowField: 'low',
* closeField: 'close',
* style: {
* dropStyle: {
* fill: 'rgb(237, 123, 43)',
* stroke: 'rgb(237, 123, 43)'
* },
* raiseStyle: {
* fill: 'rgb(55, 153, 19)',
* stroke: 'rgb(55, 153, 19)'
* }
* },
* aggregator: {
* strategy: 'time'
* }
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*/
Ext.define('Ext.chart.series.CandleStick', {
extend: 'Ext.chart.series.Cartesian',
requires: ['Ext.chart.series.sprite.CandleStick'],
alias: 'series.candlestick',
type: 'candlestick',
seriesType: 'candlestickSeries',
config: {
/**
* @cfg {String} openField
* The store record field name that represents the opening value of the given period.
*/
openField: null,
/**
* @cfg {String} highField
* The store record field name that represents the highest value of the time interval represented.
*/
highField: null,
/**
* @cfg {String} lowField
* The store record field name that represents the lowest value of the time interval represented.
*/
lowField: null,
/**
* @cfg {String} closeField
* The store record field name that represents the closing value of the given period.
*/
closeField: null
},
fieldCategoryY: ['Open', 'High', 'Low', 'Close']
});

View file

@ -0,0 +1,145 @@
/**
* @abstract
* @class Ext.chart.series.Cartesian
* @extends Ext.chart.series.Series
*
* Common base class for series implementations which plot values using x/y coordinates.
*
* @constructor
*/
Ext.define('Ext.chart.series.Cartesian', {
extend: 'Ext.chart.series.Series',
config: {
/**
* The field used to access the x axis value from the items from the data source.
*
* @cfg {String} xField
*/
xField: null,
/**
* The field(s) used to access the y-axis value(s) of the items from the data source.
*
* @cfg {String|String[]} yField
*/
yField: null,
/**
* @cfg {Ext.chart.axis.Axis} xAxis The chart axis bound to the series on the x-axis.
*/
xAxis: null,
/**
* @cfg {Ext.chart.axis.Axis} yAxis The chart axis bound to the series on the y-axis.
*/
yAxis: null
},
directions: ['X', 'Y'],
fieldCategoryX: ['X'],
fieldCategoryY: ['Y'],
updateXAxis: function (axis) {
axis.processData(this);
},
updateYAxis: function (axis) {
axis.processData(this);
},
coordinateX: function () {
return this.coordinate('X', 0, 2);
},
coordinateY: function () {
return this.coordinate('Y', 1, 2);
},
getItemForPoint: function (x, y) {
if (this.getSprites()) {
var me = this,
sprite = me.getSprites()[0],
store = me.getStore(),
item;
if(me.getHidden()) {
return null;
}
if (sprite) {
var index = sprite.getIndexNearPoint(x, y);
if (index !== -1) {
item = {
series: this,
category: this.getItemInstancing() ? 'items' : 'markers',
index: index,
record: store.getData().items[index],
field: this.getYField(),
sprite: sprite
};
return item;
}
}
}
},
createSprite: function () {
var sprite = this.callSuper(),
xAxis = this.getXAxis();
sprite.setAttributes({flipXY: this.getChart().getFlipXY()});
if (sprite.setAggregator && xAxis && xAxis.getAggregator) {
if (xAxis.getAggregator) {
sprite.setAggregator({strategy: xAxis.getAggregator()});
} else {
sprite.setAggregator({});
}
}
return sprite;
},
getSprites: function () {
var me = this,
chart = this.getChart(),
animation = chart && chart.getAnimate(),
itemInstancing = me.getItemInstancing(),
sprites = me.sprites, sprite;
if (!chart) {
return [];
}
if (!sprites.length) {
sprite = me.createSprite();
} else {
sprite = sprites[0];
}
if (animation) {
me.getLabel().getTemplate().fx.setConfig(animation);
if (itemInstancing) {
sprite.itemsMarker.getTemplate().fx.setConfig(animation);
}
sprite.fx.setConfig(animation);
}
return sprites;
},
provideLegendInfo: function (target) {
var style = this.getStyle();
target.push({
name: this.getTitle() || this.getYField() || this.getId(),
mark: style.fillStyle || style.strokeStyle || 'black',
disabled: false,
series: this.getId(),
index: 0
});
},
getXRange: function () {
return [this.dataRange[0], this.dataRange[2]];
},
getYRange: function () {
return [this.dataRange[1], this.dataRange[3]];
}
})
;

467
vendor/touch/src/chart/series/Gauge.js vendored Normal file
View file

@ -0,0 +1,467 @@
/**
* @class Ext.chart.series.Gauge
* @extends Ext.chart.series.Series
*
* Creates a Gauge Chart.
*
* @example preview
* var chart = new Ext.chart.SpaceFillingChart({
* series: [{
* type: 'gauge',
* minimum: 100,
* maximum: 800,
* value: 400,
* donut: 30,
* colors: ["#115fa6", "lightgrey"]
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*/
Ext.define('Ext.chart.series.Gauge', {
alias: 'series.gauge',
extend: 'Ext.chart.series.Series',
type: "gauge",
seriesType: 'pieslice',
requires: [
'Ext.draw.sprite.Sector'
],
config: {
/**
* @cfg {String} angleField
* @deprecated Use `field` directly
* The store record field name to be used for the gauge angles.
* The values bound to this field name must be positive real numbers.
*/
angleField: null,
/**
* @cfg {String} field
* The store record field name to be used for the gauge value.
* The values bound to this field name must be positive real numbers.
*/
field: null,
/**
* @cfg {Boolean} needle
* If true, display the gauge as a needle, otherwise as a sector.
*/
needle: false,
/**
* @cfg {Number} needleLengthRatio
* @deprecated Use `needleLength` directly
* Ratio of the length of needle compared to the radius of the entire disk.
*/
needleLengthRatio: undefined,
/**
* @cfg {Number} needleLength
* Percentage of the length of needle compared to the radius of the entire disk.
*/
needleLength: 90,
/**
* @cfg {Number} needleWidth
* Width of the needle in pixels.
*/
needleWidth: 4,
/**
* @cfg {Number} donut
* Percentage of the radius of the donut hole compared to the entire disk.
*/
donut: 30,
/**
* @cfg {Boolean} showInLegend
* Whether to add the gauge chart elements as legend items.
*/
showInLegend: false,
/**
* @cfg {Number} value
* Directly sets the displayed value of the gauge.
* It is ignored if {@link #field} is provided.
*/
value: null,
/**
* @cfg {Array} colors (required)
* An array of color values which is used for the needle and the `sectors`.
*/
colors: null,
/**
* @cfg {Array} sectors
* Allows to paint sectors of different colors in the background of the gauge,
* with optional labels.
*
* It can be an array of numbers (each between `minimum` and `maximum`) that
* define the highest value of each sector. For N sectors, only (N-1) values are
* needed because it is assumed that the first sector starts at `minimum` and the
* last sector ends at `maximum`. Example: a water temperature gauge that is blue
* below 20C, red above 80C, gray in-between, and with an orange needle...
*
* minimum: 0,
* maximum: 100,
* sectors: [20, 80],
* colors: ['orange', 'blue', 'lightgray', 'red']
*
* It can be also an array of objects, each with the following properties:
*
* @cfg {Number} sectors.start The starting value of the sector. If omitted, it
* uses the previous sector's `end` value or the chart's `minimum`.
* @cfg {Number} sectors.end The ending value of the sector. If omitted, it uses
* the `maximum` defined for the chart.
* @cfg {String} sectors.label The label for this sector. Labels are styled using
* the series' {@link Ext.chart.series.Series#label label} config.
* @cfg {String} sectors.color The color of the sector. If omitted, it uses one
* of the `colors` defined for the series or for the chart.
* @cfg {Object} sectors.style An additional style object for the sector (for
* instance to set the opacity or to draw a line of a different color around the
* sector).
*
* minimum: 0,
* maximum: 100,
* sectors: [{
* end: 20,
* label: 'Cold',
* color: 'aqua'
* },
* {
* end: 80,
* label: 'Temp.',
* color: 'lightgray',
* style: { strokeStyle:'black', strokeOpacity:1, lineWidth:1 }
* },
* {
* label: 'Hot',
* color: 'tomato'
* }]
*/
sectors: null,
/**
* @cfg {Number} minimum
* The minimum value of the gauge.
*/
minimum: 0,
/**
* @cfg {Number} maximum
* The maximum value of the gauge.
*/
maximum: 100,
rotation: 0,
/**
* @cfg {Number} totalAngle
* The size of the sector that the series will occupy.
*/
totalAngle: Math.PI / 2,
region: [0, 0, 1, 1],
center: [0.5, 0.75],
radius: 0.5,
/**
* @cfg {Boolean} wholeDisk Indicates whether to show the whole disk or only the marked part.
*/
wholeDisk: false
},
updateNeedle: function(needle) {
var me = this,
sprites = me.getSprites(),
angle = me.valueToAngle(me.getValue());
if (sprites && sprites.length) {
sprites[0].setAttributes({
startAngle: (needle ? angle : 0),
endAngle: angle,
strokeOpacity: (needle ? 1 : 0),
lineWidth: (needle ? me.getNeedleWidth() : 0)
});
me.doUpdateStyles();
}
},
updateColors: function (colors, oldColors) {
var me = this,
sectors = me.getSectors(),
sectorCount = sectors && sectors.length,
sprites = me.getSprites(),
spriteCount = sprites && sprites.length,
newColors = Ext.Array.clone(colors),
colorCount = colors && colors.length,
needle = me.getNeedle(),
i;
if (!colorCount || !colors[0]) {
return;
}
// Make sure the 'sectors' colors are not overridden.
for (i = 0; i < sectorCount; i++) {
newColors[i+1] = sectors[i].color || newColors[i+1] || colors[i%colorCount];
}
sprites[0].setAttributes({stroke:newColors[0]});
this.setSubStyle({color:newColors});
this.doUpdateStyles();
},
updateAngleField: function (angleField) {
this.setField(angleField);
},
updateNeedleLengthRatio: function (needleLengthRatio) {
this.setNeedleLength(needleLengthRatio * 100);
},
updateRegion: function (region) {
var wholeDisk = this.getWholeDisk(),
halfTotalAngle = wholeDisk ? Math.PI : this.getTotalAngle() / 2,
donut = this.getDonut() / 100,
width, height, radius;
if (halfTotalAngle <= Math.PI / 2) {
width = 2 * Math.sin(halfTotalAngle);
height = 1 - donut * Math.cos(halfTotalAngle);
} else {
width = 2;
height = 1 - Math.cos(halfTotalAngle);
}
radius = Math.min(region[2] / width, region[3] / height);
this.setRadius(radius);
this.setCenter([region[2] / 2, radius + (region[3] - height * radius) / 2]);
},
updateCenter: function (center) {
this.setStyle({
centerX: center[0],
centerY: center[1],
rotationCenterX: center[0],
rotationCenterY: center[1]
});
this.doUpdateStyles();
},
updateRotation: function (rotation) {
this.setStyle({
rotationRads: rotation - (this.getTotalAngle() + Math.PI) / 2
});
this.doUpdateStyles();
},
doUpdateShape: function (radius, donut) {
var endRhoArray,
sectors = this.getSectors(),
sectorCount = (sectors && sectors.length) || 0,
needleLength = this.getNeedleLength() / 100;
// Initialize an array that contains the endRho for each sprite.
// The first sprite is for the needle, the others for the gauge background sectors.
// Note: SubStyle arrays are handled in series.getOverriddenStyleByIndex().
endRhoArray = [radius * needleLength, radius];
while (sectorCount --) {
endRhoArray.push(radius);
}
this.setSubStyle({
endRho: endRhoArray,
startRho: radius / 100 * donut
});
this.doUpdateStyles();
},
updateRadius: function (radius) {
var donut = this.getDonut();
this.doUpdateShape(radius, donut);
},
updateDonut: function (donut) {
var radius = this.getRadius();
this.doUpdateShape(radius, donut);
},
valueToAngle: function(value) {
value = this.applyValue(value);
return this.getTotalAngle() * (value - this.getMinimum()) / (this.getMaximum() - this.getMinimum());
},
applyValue: function (value) {
return Math.min(this.getMaximum(), Math.max(value, this.getMinimum()));
},
updateValue: function (value) {
var me = this,
needle = me.getNeedle(),
angle = me.valueToAngle(value),
sprites = me.getSprites();
sprites[0].rendererData.value = value;
sprites[0].setAttributes({
startAngle: (needle ? angle : 0),
endAngle: angle
});
me.doUpdateStyles();
},
processData: function () {
var store = this.getStore();
if (!store) {
return;
}
var field = this.getField();
if (!field) {
return;
}
if (!store.getData().items.length) {
return;
}
this.setValue(store.getData().items[0].get(field));
},
getDefaultSpriteConfig: function () {
return {
type: this.seriesType,
renderer: this.getRenderer(),
fx: {
customDuration: {
translationX: 0,
translationY: 0,
rotationCenterX: 0,
rotationCenterY: 0,
centerX: 0,
centerY: 0,
startRho: 0,
endRho: 0,
baseRotation: 0
}
}
};
},
normalizeSectors: function(sectors) {
// Make sure all the sectors in the array have a legit start and end.
// Note: the array is modified in-place.
var me = this,
sectorCount = (sectors && sectors.length) || 0,
i, value, start, end;
if (sectorCount) {
for (i = 0; i < sectorCount; i++) {
value = sectors[i];
if (typeof value == "number") {
sectors[i] = {
start: (i > 0 ? sectors[i-1].end : me.getMinimum()),
end: Math.min(value, me.getMaximum())
};
if (i == (sectorCount - 1) && sectors[i].end < me.getMaximum()) {
sectors[i+1] = {
start: sectors[i].end,
end: me.getMaximum()
};
}
} else {
if (typeof value.start == "number") {
start = Math.max(value.start, me.getMinimum());
} else {
start = (i > 0 ? sectors[i-1].end : me.getMinimum());
}
if (typeof value.end == "number") {
end = Math.min(value.end, me.getMaximum());
} else {
end = me.getMaximum();
}
sectors[i].start = start;
sectors[i].end = end;
}
}
} else {
sectors = [{
start: me.getMinimum(),
end: me.getMaximum()
}];
}
return sectors;
},
getSprites: function () {
var me = this,
store = me.getStore(),
value = me.getValue(),
i, ln;
// The store must be initialized, or the value must be set
if (!store && !Ext.isNumber(value)) {
return [];
}
// Return cached sprites
var chart = me.getChart(),
animate = chart.getAnimate(),
sprites = me.sprites,
spriteIndex = 0,
sprite, sectors, attr, rendererData;
if (sprites && sprites.length) {
sprites[0].fx.setConfig(animate);
return sprites;
}
rendererData = {
store: store,
field: me.getField(),
value: value,
series: me
};
// Create needle sprite
sprite = me.createSprite();
sprite.setAttributes({
zIndex: 10
}, true);
sprite.rendererData = rendererData;
sprite.rendererIndex = spriteIndex++;
// Create background sprite(s)
me.getLabel().getTemplate().setField(true); // Enable labels
sectors = me.normalizeSectors(me.getSectors());
for (i = 0, ln = sectors.length; i < ln; i++) {
attr = {
startAngle: me.valueToAngle(sectors[i].start),
endAngle: me.valueToAngle(sectors[i].end),
label: sectors[i].label,
fillStyle: sectors[i].color,
strokeOpacity: 0,
rotateLabels: false,
doCallout: false, // Show labels inside sectors.
labelOverflowPadding: -1 // Allow labels to overlap.
};
Ext.apply(attr, sectors[i].style);
sprite = me.createSprite();
sprite.rendererData = rendererData;
sprite.rendererIndex = spriteIndex++;
sprite.setAttributes(attr, true);
}
// Make sure we have some default colors
var colors = me.getColors() || (chart && chart.config.colors);
if (!colors) {
me.setColors(['blue','lightgray']);
}
me.doUpdateStyles();
return sprites;
}
});

View file

@ -0,0 +1,337 @@
/**
* @private
*/
Ext.define('Ext.chart.series.ItemPublisher', {
extend: 'Ext.event.publisher.Publisher',
targetType: 'series',
handledEvents: [
/**
* @event itemmousemove
* Fires when the mouse is moved on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemmousemove',
/**
* @event itemmouseup
* Fires when a mouseup event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemmouseup',
/**
* @event itemmousedown
* Fires when a mousedown event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemmousedown',
/**
* @event itemmouseover
* Fires when the mouse enters a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemmouseover',
/**
* @event itemmouseout
* Fires when the mouse exits a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemmouseout',
/**
* @event itemclick
* Fires when a click event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemclick',
/**
* @event itemdoubleclick
* Fires when a doubleclick event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemdoubleclick',
/**
* @event itemtap
* Fires when a tap event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemtap',
/**
* @event itemtapstart
* Fires when a tapstart event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemtapstart',
/**
* @event itemtapend
* Fires when a tapend event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemtapend',
/**
* @event itemtapcancel
* Fires when a tapcancel event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemtapcancel',
/**
* @event itemtaphold
* Fires when a taphold event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemtaphold',
/**
* @event itemdoubletap
* Fires when a doubletap event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemdoubletap',
/**
* @event itemsingletap
* Fires when a singletap event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemsingletap',
/**
* @event itemtouchstart
* Fires when a touchstart event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemtouchstart',
/**
* @event itemtouchmove
* Fires when a touchmove event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemtouchmove',
/**
* @event itemtouchend
* Fires when a touchend event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemtouchend',
/**
* @event itemdragstart
* Fires when a dragstart event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemdragstart',
/**
* @event itemdrag
* Fires when a drag event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemdrag',
/**
* @event itemdragend
* Fires when a dragend event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemdragend',
/**
* @event itempinchstart
* Fires when a pinchstart event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itempinchstart',
/**
* @event itempinch
* Fires when a pinch event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itempinch',
/**
* @event itempinchend
* Fires when a pinchend event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itempinchend',
/**
* @event itemswipe
* Fires when a swipe event occurs on a series item.
* @param {Ext.chart.series.Series} series
* @param {Object} item
* @param {Event} event
*/
'itemswipe'
],
delegationRegex: /^item([a-z]+)$/i,
getSubscribers: function (chartId) {
var subscribers = this.subscribers;
if (!subscribers.hasOwnProperty(chartId)) {
subscribers[chartId] = {};
}
return subscribers[chartId];
},
subscribe: function (target, eventName) {
var match = target.match(this.idSelectorRegex),
dispatcher = this.dispatcher,
targetType = this.targetType,
series, id;
if (!match) {
return false;
}
id = match[1];
series = Ext.ComponentManager.get(id);
if (!series) {
return false;
}
if (!series.getChart()) {
dispatcher.addListener(targetType, target, 'chartattached', 'attachChart', this, [series, eventName], 'before');
} else {
this.attachChart(series.getChart(), [series, eventName]);
}
return true;
},
attachChart: function (chart, args) {
var dispatcher = this.dispatcher,
targetType = this.targetType,
series = args[0],
eventName = args[1],
subscribers = this.getSubscribers(chart.getId()),
match = eventName.match(this.delegationRegex);
if (match) {
var chartEventName = match[1];
if (!subscribers.hasOwnProperty(eventName)) {
subscribers[eventName] = [];
dispatcher.addListener(targetType, '#' + series.getId(), 'chartdetached', 'detachChart', this, [series, eventName, subscribers], 'after');
chart.element.on(chartEventName, "relayMethod", this, [chart, eventName]);
}
subscribers[eventName].push(series);
return true;
} else {
return false;
}
},
unsubscribe: function (target, eventName) {
var match = target.match(this.idSelectorRegex),
dispatcher = this.dispatcher,
targetType = this.targetType,
series, id;
if (!match) {
return false;
}
id = match[1];
series = Ext.ComponentManager.get(id);
if (!series) {
return false;
}
dispatcher.removeListener(targetType, target, 'chartattached', 'attachChart', this, 'before');
if (series.getChart()) {
this.detachChart(series.getChart(), [series, eventName]);
}
return true;
},
detachChart: function (chart, args) {
var dispatcher = this.dispatcher,
targetType = this.targetType,
series = args[0],
eventName = args[1],
subscribers = this.getSubscribers(chart.getId()),
match = eventName.match(this.delegationRegex),
index, seriesArray;
if (match) {
var chartEventName = match[1];
if (subscribers.hasOwnProperty(eventName)) {
seriesArray = subscribers[eventName];
index = seriesArray.indexOf(series);
if (index > -1) {
seriesArray.splice(index, 1);
}
if (seriesArray.length === 0) {
chart.element.un(chartEventName, "relayMethod", this, [chart, eventName]);
dispatcher.removeListener(targetType, '#' + series.getId(), 'chartdetached', 'detachChart', this, 'after');
delete subscribers[eventName];
}
}
}
},
relayMethod: function (e, sender, args) {
var chart = args[0],
eventName = args[1],
dispatcher = this.dispatcher,
targetType = this.targetType,
chartXY = chart.getEventXY(e),
x = chartXY[0],
y = chartXY[1],
subscriber = this.getSubscribers(chart.getId())[eventName],
i, ln;
if (subscriber) {
for (i = 0, ln = subscriber.length; i < ln; i++) {
var series = subscriber[i],
item = series.getItemForPoint(x, y);
if (item) {
// TODO: Don't stop at the first item.
// Depending on the selectionTolerance, there might be an item in another
// series that's closer to the event location. See test case 3943c.
dispatcher.doDispatchEvent(targetType, '#' + series.getId(), eventName, [series, item, e]);
return;
}
}
}
}
}, function () {
});

202
vendor/touch/src/chart/series/Line.js vendored Normal file
View file

@ -0,0 +1,202 @@
/**
* @class Ext.chart.series.Line
* @extends Ext.chart.series.Cartesian
*
* Creates a Line Chart. A Line Chart is a useful visualization technique to display quantitative information for different
* categories or other real values (as opposed to the bar chart), that can show some progression (or regression) in the dataset.
* As with all other series, the Line Series must be appended in the *series* Chart array configuration. See the Chart
* documentation for more information. A typical configuration object for the line series could be:
*
* @example preview
* var lineChart = new Ext.chart.CartesianChart({
* animate: true,
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['data1'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* grid: true,
* minimum: 0
* }, {
* type: 'category',
* position: 'bottom',
* fields: ['name'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* }
* }],
* series: [{
* type: 'line',
* highlight: {
* size: 7,
* radius: 7
* },
* style: {
* stroke: 'rgb(143,203,203)'
* },
* xField: 'name',
* yField: 'data1',
* marker: {
* type: 'path',
* path: ['M', -2, 0, 0, 2, 2, 0, 0, -2, 'Z'],
* stroke: 'blue',
* lineWidth: 0
* }
* }, {
* type: 'line',
* highlight: {
* size: 7,
* radius: 7
* },
* fill: true,
* xField: 'name',
* yField: 'data3',
* marker: {
* type: 'circle',
* radius: 4,
* lineWidth: 0
* }
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(lineChart);
*
* In this configuration we're adding two series (or lines), one bound to the `data1`
* property of the store and the other to `data3`. The type for both configurations is
* `line`. The `xField` for both series is the same, the `name` property of the store.
* Both line series share the same axis, the left axis. You can set particular marker
* configuration by adding properties onto the markerConfig object. Both series have
* an object as highlight so that markers animate smoothly to the properties in highlight
* when hovered. The second series has `fill = true` which means that the line will also
* have an area below it of the same color.
*
* **Note:** In the series definition remember to explicitly set the axis to bind the
* values of the line series to. This can be done by using the `axis` configuration property.
*/
Ext.define('Ext.chart.series.Line', {
extend: 'Ext.chart.series.Cartesian',
alias: 'series.line',
type: 'line',
seriesType: 'lineSeries',
requires: [
'Ext.chart.series.sprite.Line'
],
config: {
/**
* @cfg {Number} selectionTolerance
* The offset distance from the cursor position to the line series to trigger events (then used for highlighting series, etc).
*/
selectionTolerance: 20,
/**
* @cfg {Object} style
* An object containing styles for the visualization lines. These styles will override the theme styles.
* Some options contained within the style object will are described next.
*/
/**
* @cfg {Boolean/Number} smooth
* If set to `true` or a non-zero number, the line will be smoothed/rounded around its points; otherwise
* straight line segments will be drawn.
*
* A numeric value is interpreted as a divisor of the horizontal distance between consecutive points in
* the line; larger numbers result in sharper curves while smaller numbers result in smoother curves.
*
* If set to `true` then a default numeric value of 3 will be used.
*/
smooth: false,
/**
* @cfg {Boolean} step
* If set to `true`, the line uses steps instead of straight lines to connect the dots.
* It is ignored if `smooth` is true.
*/
step: false,
/**
* @cfg {Boolean} fill
* If set to `true`, the area underneath the line is filled with the color defined as follows, listed by priority:
* - The color that is configured for this series ({@link Ext.chart.series.Series#colors}).
* - The color that is configured for this chart ({@link Ext.chart.AbstractChart#colors}).
* - The fill color that is set in the {@link #style} config.
* - The stroke color that is set in the {@link #style} config, or the same color as the line.
*
* Note: Do not confuse `series.config.fill` (which is a boolean) with `series.style.fill' (which is an alias
* for the `fillStyle` property and contains a color). For compatibility with previous versions of the API,
* if `config.fill` is undefined but a `style.fill' color is provided, `config.fill` is considered true.
* So the default value below must be undefined, not false.
*/
fill: undefined,
aggregator: { strategy: 'double' }
},
/**
* @private Default numeric smoothing value to be used when `{@link #smooth} = true`.
*/
defaultSmoothness: 3,
/**
* @private Size of the buffer area on either side of the viewport to provide seamless zoom/pan
* transforms. Expressed as a multiple of the viewport length, e.g. 1 will make the buffer on
* each side equal to the length of the visible axis viewport.
*/
overflowBuffer: 1,
/**
* @private Override {@link Ext.chart.series.Series#getDefaultSpriteConfig}
*/
getDefaultSpriteConfig: function () {
var me = this,
parentConfig = me.callSuper(arguments),
style = me.getStyle(),
fillArea = false;
if (typeof me.config.fill != 'undefined') {
// If config.fill is present but there is no fillStyle, then use the
// strokeStyle to fill (and paint the area the same color as the line).
if (me.config.fill) {
fillArea = true;
if (typeof style.fillStyle == 'undefined') {
style.fillStyle = style.strokeStyle;
}
}
} else {
// For compatibility with previous versions of the API, if config.fill
// is undefined but style.fillStyle is provided, we fill the area.
if (style.fillStyle) {
fillArea = true;
}
}
// If we don't fill, then delete the fillStyle because that's what is used by
// the Line sprite to fill below the line.
if (!fillArea) {
delete style.fillStyle;
}
return Ext.apply(parentConfig || {}, {
fillArea: fillArea,
step: me.config.step,
smooth: me.config.smooth,
selectionTolerance: me.config.selectionTolerance
});
}
});

393
vendor/touch/src/chart/series/Pie.js vendored Normal file
View file

@ -0,0 +1,393 @@
/**
* @class Ext.chart.series.Pie
* @extends Ext.chart.series.Polar
*
* Creates a Pie Chart. A Pie Chart is a useful visualization technique to display quantitative information for different
* categories that also have a meaning as a whole.
* As with all other series, the Pie Series must be appended in the *series* Chart array configuration. See the Chart
* documentation for more information. A typical configuration object for the pie series could be:
*
* @example preview
* var chart = new Ext.chart.PolarChart({
* animate: true,
* interactions: ['rotate'],
* colors: ['#115fa6', '#94ae0a', '#a61120', '#ff8809', '#ffd13e'],
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {name: 'metric one', data1: 10, data2: 12, data3: 14, data4: 8, data5: 13},
* {name: 'metric two', data1: 7, data2: 8, data3: 16, data4: 10, data5: 3},
* {name: 'metric three', data1: 5, data2: 2, data3: 14, data4: 12, data5: 7},
* {name: 'metric four', data1: 2, data2: 14, data3: 6, data4: 1, data5: 23},
* {name: 'metric five', data1: 27, data2: 38, data3: 36, data4: 13, data5: 33}
* ]
* },
* series: [{
* type: 'pie',
* label: {
* field: 'name',
* display: 'rotate'
* },
* xField: 'data3',
* donut: 30
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*
* In this configuration we set `pie` as the type for the series, set an object with specific style properties for highlighting options
* (triggered when hovering elements). We also set true to `showInLegend` so all the pie slices can be represented by a legend item.
* We set `data1` as the value of the field to determine the angle span for each pie slice. We also set a label configuration object
* where we set the field name of the store field to be rendered as text for the label. The labels will also be displayed rotated.
* We set `contrast` to `true` to flip the color of the label if it is to similar to the background color. Finally, we set the font family
* and size through the `font` parameter.
*
*/
Ext.define('Ext.chart.series.Pie', {
extend: 'Ext.chart.series.Polar',
requires: [
'Ext.chart.series.sprite.PieSlice'
],
type: 'pie',
alias: 'series.pie',
seriesType: 'pieslice',
config: {
/**
* @cfg {String} labelField
* @deprecated Use {@link Ext.chart.series.Pie#label} instead.
* The store record field name to be used for the pie slice labels.
*/
labelField: false,
/**
* @cfg {Number} donut Specifies the radius of the donut hole, as a percentage of the chart's radius.
* Defaults to 0 (no donut hole).
*/
donut: 0,
/**
* @cfg {String} field
* @deprecated Use xField directly
*/
field: null,
/**
* @cfg {Number} rotation The starting angle of the pie slices.
*/
rotation: 0,
/**
* @cfg {Number} [totalAngle=2*PI] The total angle of the pie series.
*/
totalAngle: Math.PI * 2,
/**
* @cfg {Array} hidden Determines which pie slices are hidden.
*/
hidden: [],
/**
* @cfg {Number} Allows adjustment of the radius by a spefic perfentage.
*/
radiusFactor: 100,
style: {
}
},
directions: ['X'],
setField: function (f) {
return this.setXField(f);
},
getField: function () {
return this.getXField();
},
applyRadius : function (radius) {
return radius * this.getRadiusFactor() * 0.01;
},
updateLabelData: function () {
var me = this,
store = me.getStore(),
items = store.getData().items,
sprites = me.getSprites(),
labelField = me.getLabel().getTemplate().getField(),
hidden = me.getHidden(),
i, ln, labels, sprite;
if (sprites.length > 0 && labelField) {
labels = [];
for (i = 0, ln = items.length; i < ln; i++) {
labels.push(items[i].get(labelField));
}
for (i = 0, ln = sprites.length; i < ln; i++) {
sprite = sprites[i];
sprite.setAttributes({label: labels[i]});
sprite.putMarker('labels', {hidden: hidden[i]}, sprite.attr.attributeId);
}
}
},
coordinateX: function () {
var me = this,
store = me.getStore(),
items = store.getData().items,
length = items.length,
field = me.getXField(),
value, sum = 0,
hidden = me.getHidden(),
summation = [], i,
lastAngle = 0,
totalAngle = me.getTotalAngle(),
sprites = me.getSprites();
if (!sprites) {
return;
}
for (i = 0; i < length; i++) {
value = Math.abs(Number(items[i].get(field))) || 0;
if (!hidden[i]) {
sum += value;
}
summation[i] = sum;
if (i >= hidden.length) {
hidden[i] = false;
}
}
if (sum !== 0) {
sum = totalAngle / sum;
}
for (i = 0; i < length; i++) {
sprites[i].setAttributes({
startAngle: lastAngle,
endAngle: lastAngle = (sum ? summation[i] * sum : 0),
globalAlpha: 1
});
}
for (; i < me.sprites.length; i++) {
sprites[i].setAttributes({
startAngle: totalAngle,
endAngle: totalAngle,
globalAlpha: 0
});
}
me.getChart().refreshLegendStore();
},
updateCenter: function (center) {
this.setStyle({
translationX: center[0] + this.getOffsetX(),
translationY: center[1] + this.getOffsetY()
});
this.doUpdateStyles();
},
updateRadius: function (radius) {
this.setStyle({
startRho: radius * this.getDonut() * 0.01, // Percentage
endRho: radius
});
this.doUpdateStyles();
},
updateDonut: function (donut) {
var radius = this.getRadius();
this.setStyle({
startRho: radius * donut * 0.01, // Percentage
endRho: radius
});
this.doUpdateStyles();
},
updateRotation: function (rotation) {
this.setStyle({
rotationRads: rotation
});
this.doUpdateStyles();
},
updateTotalAngle: function (totalAngle) {
this.processData();
},
getSprites: function () {
var me = this,
chart = me.getChart(),
store = me.getStore();
if (!chart || !store) {
return [];
}
me.getColors();
me.getSubStyle();
var items = store.getData().items,
length = items.length,
animation = chart && chart.getAnimate(),
sprites = me.sprites, sprite,
spriteIndex = 0, rendererData,
i, spriteCreated = false,
label = me.getLabel(),
labelTpl = label.getTemplate();
rendererData = {
store: store,
field: me.getField(),
series: me
};
for (i = 0; i < length; i++) {
sprite = sprites[i];
if (!sprite) {
sprite = me.createSprite();
if (me.getHighlightCfg()) {
sprite.config.highlightCfg = me.getHighlightCfg();
sprite.addModifier('highlight', true);
}
if (labelTpl.getField()) {
labelTpl.setAttributes({
labelOverflowPadding: me.getLabelOverflowPadding()
});
labelTpl.fx.setCustomDuration({'callout': 200});
sprite.bindMarker('labels', label);
}
sprite.setAttributes(me.getStyleByIndex(i));
sprite.rendererData = rendererData;
sprite.rendererIndex = spriteIndex++;
spriteCreated = true;
}
sprite.fx.setConfig(animation);
}
if (spriteCreated) {
me.doUpdateStyles();
}
return me.sprites;
},
normalizeAngle: function (angle) {
var pi2 = Math.PI * 2;
if (angle >= 0) {
return angle % pi2;
}
return (angle % pi2 + pi2) % pi2;
},
betweenAngle: function (x, a, b) {
var normalize = this.normalizeAngle;
a = normalize(a);
b = normalize(b);
x = normalize(x);
if (b === 0) {
b = Math.PI * 2;
}
return x >= a && x < b;
},
/**
* Returns the pie slice for a given angle
* @param {Number} angle The angle to search for the slice
* @return {Object} An object containing the reocord, sprite, scope etc.
*/
getItemForAngle: function (angle) {
var me = this,
sprites = me.getSprites(),
attr;
angle %= Math.PI * 2;
while (angle < 0) {
angle += Math.PI * 2;
}
if (sprites) {
var store = me.getStore(),
items = store.getData().items,
hidden = me.getHidden(),
i = 0,
ln = store.getCount();
for (; i < ln; i++) {
if(!hidden[i]) {
// Fortunately, the id of items equals the index of it in instances list.
attr = sprites[i].attr;
if (attr.startAngle <= angle && attr.endAngle >= angle) {
return {
series: me,
sprite: sprites[i],
index: i,
record: items[i],
field: me.getXField()
};
}
}
}
}
return null;
},
getItemForPoint: function (x, y) {
var me = this,
sprites = me.getSprites();
if (sprites) {
var center = me.getCenter(),
offsetX = me.getOffsetX(),
offsetY = me.getOffsetY(),
originalX = x - center[0] + offsetX,
originalY = y - center[1] + offsetY,
store = me.getStore(),
donut = me.getDonut(),
items = store.getData().items,
direction = Math.atan2(originalY, originalX) - me.getRotation(),
donutLimit = Math.sqrt(originalX * originalX + originalY * originalY),
endRadius = me.getRadius(),
startRadius = donut / 100 * endRadius,
hidden = me.getHidden(),
i, ln, attr;
for (i = 0, ln = items.length; i < ln; i++) {
if(!hidden[i]) {
// Fortunately, the id of items equals the index of it in instances list.
attr = sprites[i].attr;
if (startRadius + attr.margin <= donutLimit && donutLimit + attr.margin <= endRadius) {
if (this.betweenAngle(direction, attr.startAngle, attr.endAngle)) {
return {
series: this,
sprite: sprites[i],
index: i,
record: items[i],
field: this.getXField()
};
}
}
}
}
return null;
}
},
provideLegendInfo: function (target) {
var store = this.getStore();
if (store) {
var items = store.getData().items,
labelField = this.getLabel().getTemplate().getField(),
field = this.getField(),
hidden = this.getHidden();
for (var i = 0; i < items.length; i++) {
target.push({
name: labelField ? String(items[i].get(labelField)) : field + ' ' + i,
mark: this.getStyleByIndex(i).fillStyle || this.getStyleByIndex(i).strokeStyle || 'black',
disabled: hidden[i],
series: this.getId(),
index: i
});
}
}
}
});

247
vendor/touch/src/chart/series/Pie3D.js vendored Normal file
View file

@ -0,0 +1,247 @@
/**
* @class Ext.chart.series.Pie3D
* @extends Ext.chart.series.Polar
*
* Creates a 3D Pie Chart.
*
* @example preview
* var chart = new Ext.chart.PolarChart({
* animate: true,
* interactions: ['rotate'],
* colors: ["#115fa6", "#94ae0a", "#a61120", "#ff8809", "#ffd13e"],
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* series: [{
* type: 'pie3d',
* field: 'data3',
* donut: 30
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*/
Ext.define('Ext.chart.series.Pie3D', {
requires: ['Ext.chart.series.sprite.Pie3DPart'],
extend: 'Ext.chart.series.Polar',
type: 'pie3d',
seriesType: 'pie3d',
alias: 'series.pie3d',
config: {
region: [0, 0, 0, 0],
thickness: 35,
distortion: 0.5,
/**
* @cfg {String} field (required)
* The store record field name to be used for the pie angles.
* The values bound to this field name must be positive real numbers.
*/
field: false,
/**
* @private
* @cfg {String} lengthField
* Not supported.
*/
lengthField: false,
/**
* @cfg {Boolean/Number} donut
* Whether to set the pie chart as donut chart.
* Can be set to a particular percentage to set the radius
* of the donut chart.
*/
donut: false,
rotation: 0
},
applyRotation: function (rotation) {
var twoPie = Math.PI * 2;
return (rotation % twoPie + twoPie) % twoPie;
},
updateRotation: function (rotation) {
var sprites = this.getSprites(),
i, ln;
for (i = 0, ln = sprites.length; i < ln; i++) {
sprites[i].setAttributes({
baseRotation: rotation
});
}
},
updateColors: function (colorSet) {
this.setSubStyle({baseColor: colorSet});
},
doUpdateStyles: function () {
var sprites = this.getSprites(),
i = 0, j = 0, ln = sprites && sprites.length;
for (; i < ln; i += 5, j++) {
sprites[i].setAttributes(this.getStyleByIndex(j));
sprites[i + 1].setAttributes(this.getStyleByIndex(j));
sprites[i + 2].setAttributes(this.getStyleByIndex(j));
sprites[i + 3].setAttributes(this.getStyleByIndex(j));
sprites[i + 4].setAttributes(this.getStyleByIndex(j));
}
},
processData: function () {
var me = this,
chart = me.getChart(),
animation = chart && chart.getAnimate(),
store = me.getStore(),
items = store.getData().items,
length = items.length,
field = me.getField(),
value, sum = 0, ratio,
summation = [],
i,
sprites = this.getSprites(),
lastAngle;
for (i = 0; i < length; i++) {
value = items[i].get(field);
sum += value;
summation[i] = sum;
}
if (sum === 0) {
return;
}
ratio = 2 * Math.PI / sum;
for (i = 0; i < length; i++) {
summation[i] *= ratio;
}
for (i = 0; i < sprites.length; i++) {
sprites[i].fx.setConfig(animation);
}
for (i = 0, lastAngle = 0; i < length; i++) {
var commonAttributes = {opacity: 1, startAngle: lastAngle, endAngle: summation[i]};
sprites[i * 5].setAttributes(commonAttributes);
sprites[i * 5 + 1].setAttributes(commonAttributes);
sprites[i * 5 + 2].setAttributes(commonAttributes);
sprites[i * 5 + 3].setAttributes(commonAttributes);
sprites[i * 5 + 4].setAttributes(commonAttributes);
lastAngle = summation[i];
}
},
getSprites: function () {
var me = this,
chart = this.getChart(),
surface = me.getSurface(),
store = me.getStore();
if (!store) {
return [];
}
var items = store.getData().items,
length = items.length,
animation = chart && chart.getAnimate(),
region = chart.getMainRegion() || [0, 0, 1, 1],
rotation = me.getRotation(),
center = me.getCenter(),
offsetX = me.getOffsetX(),
offsetY = me.getOffsetY(),
radius = Math.min((region[3] - me.getThickness() * 2) / me.getDistortion(), region[2]) / 2,
commonAttributes = {
centerX: center[0] + offsetX,
centerY: center[1] + offsetY - me.getThickness() / 2,
endRho: radius,
startRho: radius * me.getDonut() / 100,
thickness: me.getThickness(),
distortion: me.getDistortion()
}, sliceAttributes, twoPie = Math.PI * 2,
topSprite, startSprite, endSprite, innerSideSprite, outerSideSprite,
i;
for (i = 0; i < length; i++) {
sliceAttributes = Ext.apply({}, this.getStyleByIndex(i), commonAttributes);
topSprite = me.sprites[i * 5];
if (!topSprite) {
topSprite = surface.add({
type: 'pie3dPart',
part: 'top',
startAngle: twoPie,
endAngle: twoPie
});
startSprite = surface.add({
type: 'pie3dPart',
part: 'start',
startAngle: twoPie,
endAngle: twoPie
});
endSprite = surface.add({
type: 'pie3dPart',
part: 'end',
startAngle: twoPie,
endAngle: twoPie
});
innerSideSprite = surface.add({
type: 'pie3dPart',
part: 'inner',
startAngle: twoPie,
endAngle: twoPie,
thickness: 0
});
outerSideSprite = surface.add({
type: 'pie3dPart',
part: 'outer',
startAngle: twoPie,
endAngle: twoPie,
thickness: 0
});
topSprite.fx.setDurationOn('baseRotation', 0);
startSprite.fx.setDurationOn('baseRotation', 0);
endSprite.fx.setDurationOn('baseRotation', 0);
innerSideSprite.fx.setDurationOn('baseRotation', 0);
outerSideSprite.fx.setDurationOn('baseRotation', 0);
topSprite.setAttributes(sliceAttributes);
startSprite.setAttributes(sliceAttributes);
endSprite.setAttributes(sliceAttributes);
innerSideSprite.setAttributes(sliceAttributes);
outerSideSprite.setAttributes(sliceAttributes);
me.sprites.push(topSprite, startSprite, endSprite, innerSideSprite, outerSideSprite);
} else {
startSprite = me.sprites[i * 5 + 1];
endSprite = me.sprites[i * 5 + 2];
innerSideSprite = me.sprites[i * 5 + 3];
outerSideSprite = me.sprites[i * 5 + 4];
if (animation) {
topSprite.fx.setConfig(animation);
startSprite.fx.setConfig(animation);
endSprite.fx.setConfig(animation);
innerSideSprite.fx.setConfig(animation);
outerSideSprite.fx.setConfig(animation);
}
topSprite.setAttributes(sliceAttributes);
startSprite.setAttributes(sliceAttributes);
endSprite.setAttributes(sliceAttributes);
innerSideSprite.setAttributes(sliceAttributes);
outerSideSprite.setAttributes(sliceAttributes);
}
}
for (i *= 5; i < me.sprites.length; i++) {
me.sprites[i].fx.setConfig(animation);
me.sprites[i].setAttributes({
opacity: 0,
startAngle: twoPie,
endAngle: twoPie,
baseRotation: rotation
});
}
return me.sprites;
}
});

90
vendor/touch/src/chart/series/Polar.js vendored Normal file
View file

@ -0,0 +1,90 @@
/**
* Polar series.
*/
Ext.define('Ext.chart.series.Polar', {
extend: 'Ext.chart.series.Series',
config: {
/**
* @cfg {Number} rotation
* The angle in degrees at which the first polar series item should start.
*/
rotation: 0,
/**
* @cfg {Number} radius
* The radius of the polar series. Set to `null` will fit the polar series to the boundary.
*/
radius: null,
/**
* @cfg {Array} center for the polar series.
*/
center: [0, 0],
/**
* @cfg {Number} offsetX
* The x-offset of center of the polar series related to the center of the boundary.
*/
offsetX: 0,
/**
* @cfg {Number} offsetY
* The y-offset of center of the polar series related to the center of the boundary.
*/
offsetY: 0,
/**
* @cfg {Boolean} showInLegend
* Whether to add the series elements as legend items.
*/
showInLegend: true,
/**
* @cfg {String} xField
* The store record field name for the labels used in the radar series.
*/
xField: null,
/**
* @cfg {String} yField
* The store record field name for the deflection of the graph in the radar series.
*/
yField: null,
xAxis: null,
yAxis: null
},
directions: ['X', 'Y'],
fieldCategoryX: ['X'],
fieldCategoryY: ['Y'],
getDefaultSpriteConfig: function () {
return {
type: this.seriesType,
renderer: this.getRenderer(),
centerX: 0,
centerY: 0,
rotationCenterX: 0,
rotationCenterY: 0
};
},
applyRotation: function (rotation) {
var twoPie = Math.PI * 2;
return (rotation % twoPie + Math.PI) % twoPie - Math.PI;
},
updateRotation: function (rotation) {
var sprites = this.getSprites();
if (sprites && sprites[0]) {
sprites[0].setAttributes({
baseRotation: rotation
});
}
}
});

171
vendor/touch/src/chart/series/Radar.js vendored Normal file
View file

@ -0,0 +1,171 @@
/**
* @class Ext.chart.series.Radar
* @extends Ext.chart.series.Polar
*
* Creates a Radar Chart. A Radar Chart is a useful visualization technique for comparing different quantitative values for
* a constrained number of categories.
* As with all other series, the Radar series must be appended in the *series* Chart array configuration. See the Chart
* documentation for more information. A typical configuration object for the radar series could be:
*
* @example preview
* var chart = new Ext.chart.PolarChart({
* animate: true,
* interactions: ['rotate'],
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* series: [{
* type: 'radar',
* xField: 'name',
* yField: 'data4',
* style: {
* fillStyle: 'rgba(0, 0, 255, 0.1)',
* strokeStyle: 'rgba(0, 0, 0, 0.8)',
* lineWidth: 1
* }
* }],
* axes: [
* {
* type: 'numeric',
* position: 'radial',
* fields: 'data4',
* style: {
* estStepSize: 10
* },
* grid: true
* },
* {
* type: 'category',
* position: 'angular',
* fields: 'name',
* style: {
* estStepSize: 1
* },
* grid: true
* }
* ]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*
*
*/
Ext.define('Ext.chart.series.Radar', {
extend: 'Ext.chart.series.Polar',
type: "radar",
seriesType: 'radar',
alias: 'series.radar',
requires: ['Ext.chart.series.Cartesian', 'Ext.chart.series.sprite.Radar'],
/**
* @cfg {Object} style
* An object containing styles for overriding series styles from theming.
*/
config: {
},
updateAngularAxis: function (axis) {
axis.processData(this);
},
updateRadialAxis: function (axis) {
axis.processData(this);
},
coordinateX: function () {
return this.coordinate('X', 0, 2);
},
coordinateY: function () {
return this.coordinate('Y', 1, 2);
},
updateCenter: function (center) {
this.setStyle({
translationX: center[0] + this.getOffsetX(),
translationY: center[1] + this.getOffsetY()
});
this.doUpdateStyles();
},
updateRadius: function (radius) {
this.setStyle({
endRho: radius
});
this.doUpdateStyles();
},
updateRotation: function (rotation) {
this.setStyle({
rotationRads: rotation
});
this.doUpdateStyles();
},
updateTotalAngle: function (totalAngle) {
this.processData();
},
getItemForPoint: function (x, y) {
var me = this,
sprite = me.sprites && me.sprites[0],
attr = sprite.attr,
dataX = attr.dataX,
dataY = attr.dataY,
centerX = attr.centerX,
centerY = attr.centerY,
minX = attr.dataMinX,
maxX = attr.dataMaxX,
maxY = attr.dataMaxY,
endRho = attr.endRho,
startRho = attr.startRho,
baseRotation = attr.baseRotation,
i, length = dataX.length,
store = me.getStore(),
marker = me.getMarker(),
item, th, r;
if(me.getHidden()) {
return null;
}
if (sprite && marker) {
for (i = 0; i < length; i++) {
th = (dataX[i] - minX) / (maxX - minX + 1) * 2 * Math.PI + baseRotation;
r = dataY[i] / maxY * (endRho - startRho) + startRho;
if (Math.abs(centerX + Math.cos(th) * r - x) < 22 && Math.abs(centerY + Math.sin(th) * r - y) < 22) {
item = {
series: this,
sprite: sprite,
index: i,
record: store.getData().items[i],
field: store.getFields().items[i]
};
return item;
}
}
}
return this.callSuper(arguments);
},
getXRange: function () {
return [this.dataRange[0], this.dataRange[2]];
},
getYRange: function () {
return [this.dataRange[1], this.dataRange[3]];
}
}, function () {
var klass = this;
// TODO: [HACK] Steal from cartesian series.
klass.prototype.onAxesChanged = Ext.chart.series.Cartesian.prototype.onAxesChanged;
klass.prototype.getSprites = Ext.chart.series.Cartesian.prototype.getSprites;
});

108
vendor/touch/src/chart/series/Scatter.js vendored Normal file
View file

@ -0,0 +1,108 @@
/**
* @class Ext.chart.series.Scatter
* @extends Ext.chart.series.Cartesian
*
* Creates a Scatter Chart. The scatter plot is useful when trying to display more than two variables in the same visualization.
* These variables can be mapped into x, y coordinates and also to an element's radius/size, color, etc.
* As with all other series, the Scatter Series must be appended in the *series* Chart array configuration. See the Chart
* documentation for more information on creating charts. A typical configuration object for the scatter could be:
*
* @example preview
* var chart = new Ext.chart.CartesianChart({
* animate: true,
* store: {
* fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
* data: [
* {'name':'metric one', 'data1':10, 'data2':12, 'data3':14, 'data4':8, 'data5':13},
* {'name':'metric two', 'data1':7, 'data2':8, 'data3':16, 'data4':10, 'data5':3},
* {'name':'metric three', 'data1':5, 'data2':2, 'data3':14, 'data4':12, 'data5':7},
* {'name':'metric four', 'data1':2, 'data2':14, 'data3':6, 'data4':1, 'data5':23},
* {'name':'metric five', 'data1':27, 'data2':38, 'data3':36, 'data4':13, 'data5':33}
* ]
* },
* axes: [{
* type: 'numeric',
* position: 'left',
* fields: ['data1'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* },
* grid: true,
* minimum: 0
* }, {
* type: 'category',
* position: 'bottom',
* fields: ['name'],
* title: {
* text: 'Sample Values',
* fontSize: 15
* }
* }],
* series: [{
* type: 'scatter',
* highlight: {
* size: 7,
* radius: 7
* },
* fill: true,
* xField: 'name',
* yField: 'data3',
* marker: {
* type: 'circle',
* fillStyle: 'blue',
* radius: 10,
* lineWidth: 0
* }
* }]
* });
* Ext.Viewport.setLayout('fit');
* Ext.Viewport.add(chart);
*
* In this configuration we add three different categories of scatter series. Each of them is bound to a different field of the same data store,
* `data1`, `data2` and `data3` respectively. All x-fields for the series must be the same field, in this case `name`.
* Each scatter series has a different styling configuration for markers, specified by the `marker` object. Finally we set the left axis as
* axis to show the current values of the elements.
*
*/
Ext.define('Ext.chart.series.Scatter', {
extend: 'Ext.chart.series.Cartesian',
alias: 'series.scatter',
type: 'scatter',
seriesType: 'scatterSeries',
requires: [
'Ext.chart.series.sprite.Scatter'
],
config: {
itemInstancing: {
fx: {
customDuration: {
translationX: 0,
translationY: 0
}
}
}
},
applyMarker: function (marker) {
this.getItemInstancing();
this.setItemInstancing(marker);
},
provideLegendInfo: function (target) {
var style = this.config.marker;
target.push({
name: this.getTitle() || this.getYField() || this.getId(),
mark: style.fill || style.stroke || 'black',
disabled: false,
series: this.getId(),
index: 0
});
}
});

1028
vendor/touch/src/chart/series/Series.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,160 @@
/**
* @abstract
* @extends Ext.chart.series.Cartesian
* Abstract class for all the stacked cartesian series including area series
* and bar series.
*/
Ext.define('Ext.chart.series.StackedCartesian', {
extend: 'Ext.chart.series.Cartesian',
config: {
/**
* @cfg {Boolean}
* 'true' to display the series in its stacked configuration.
*/
stacked: true,
/**
* @cfg {Array} hidden
*/
hidden: []
},
animatingSprites: 0,
updateStacked: function () {
this.processData();
},
coordinateY: function () {
return this.coordinateStacked('Y', 1, 2);
},
getFields: function (fieldCategory) {
var me = this,
fields = [], fieldsItem,
i, ln;
for (i = 0, ln = fieldCategory.length; i < ln; i++) {
fieldsItem = me['get' + fieldCategory[i] + 'Field']();
if (Ext.isArray(fieldsItem)) {
fields.push.apply(fields, fieldsItem);
} else {
fields.push(fieldsItem);
}
}
return fields;
},
updateLabelOverflowPadding: function (labelOverflowPadding) {
this.getLabel().setAttributes({labelOverflowPadding: labelOverflowPadding});
},
getSprites: function () {
var me = this,
chart = this.getChart(),
animation = chart && chart.getAnimate(),
fields = me.getFields(me.fieldCategoryY),
itemInstancing = me.getItemInstancing(),
sprites = me.sprites, sprite,
hidden = me.getHidden(),
spritesCreated = false,
i, length = fields.length;
if (!chart) {
return [];
}
for (i = 0; i < length; i++) {
sprite = sprites[i];
if (!sprite) {
sprite = me.createSprite();
if (chart.getFlipXY()) {
sprite.setAttributes({zIndex: i});
} else {
sprite.setAttributes({zIndex: -i});
}
sprite.setField(fields[i]);
spritesCreated = true;
hidden.push(false);
if (itemInstancing) {
sprite.itemsMarker.getTemplate().setAttributes(me.getOverriddenStyleByIndex(i));
} else {
sprite.setAttributes(me.getStyleByIndex(i));
}
}
if (animation) {
if (itemInstancing) {
sprite.itemsMarker.getTemplate().fx.setConfig(animation);
}
sprite.fx.setConfig(animation);
}
}
if (spritesCreated) {
me.updateHidden(hidden);
}
return sprites;
},
getItemForPoint: function (x, y) {
if (this.getSprites()) {
var me = this,
i, ln, sprite,
itemInstancing = me.getItemInstancing(),
sprites = me.getSprites(),
store = me.getStore(),
hidden = me.getHidden(),
item;
for (i = 0, ln = sprites.length; i < ln; i++) {
if(!hidden[i]) {
sprite = sprites[i];
var index = sprite.getIndexNearPoint(x, y);
if (index !== -1) {
item = {
series: me,
index: index,
category: itemInstancing ? 'items' : 'markers',
record: store.getData().items[index],
field: this.getYField()[i],
sprite: sprite
};
return item;
}
}
}
return null;
}
},
provideLegendInfo: function (target) {
var sprites = this.getSprites(),
title = this.getTitle(),
field = this.getYField(),
hidden = this.getHidden();
for (var i = 0; i < sprites.length; i++) {
target.push({
name: Ext.isArray(this.getTitle()) ? this.getTitle()[i] : (field && field[i]) || this.getId(),
mark: this.getStyleByIndex(i).fillStyle || this.getStyleByIndex(i).strokeStyle || 'black',
disabled: hidden[i],
series: this.getId(),
index: i
});
}
},
onSpriteAnimationStart: function (sprite) {
this.animatingSprites++;
if (this.animatingSprites === 1) {
this.fireEvent('animationstart');
}
},
onSpriteAnimationEnd: function (sprite) {
this.animatingSprites--;
if (this.animatingSprites === 0) {
this.fireEvent('animationend');
}
}
});

View file

@ -0,0 +1,86 @@
/**
*
*/
Ext.define('Ext.chart.series.sprite.Aggregative', {
extend: 'Ext.chart.series.sprite.Cartesian',
requires: ['Ext.draw.LimitedCache', 'Ext.draw.SegmentTree'],
inheritableStatics: {
def: {
processors: {
/**
* @cfg {Object} [dataHigh=null] Data items representing the high values of the aggregated data.
*/
dataHigh: 'data',
/**
* @cfg {Object} [dataLow=null] Data items representing the low values of the aggregated data.
*/
dataLow: 'data',
/**
* @cfg {Object} [dataClose=null] Data items representing the closing values of the aggregated data.
*/
dataClose: 'data'
},
aliases: {
/**
* @cfg {Object} [dataOpen=null] Data items representing the opening values of the aggregated data.
*/
dataOpen: 'dataY'
},
defaults: {
dataHigh: null,
dataLow: null,
dataClose: null
}
}
},
config: {
aggregator: {}
},
applyAggregator: function (aggregator, oldAggr) {
return Ext.factory(aggregator, Ext.draw.SegmentTree, oldAggr);
},
constructor: function () {
this.callSuper(arguments);
},
processDataY: function () {
var me = this,
attr = me.attr,
high = attr.dataHigh,
low = attr.dataLow,
close = attr.dataClose,
open = attr.dataY;
me.callSuper(arguments);
if (attr.dataX && open && open.length > 0) {
if (high) {
me.getAggregator().setData(attr.dataX, attr.dataY, high, low, close);
} else {
me.getAggregator().setData(attr.dataX, attr.dataY);
}
}
},
getGapWidth: function () {
return 1;
},
renderClipped: function (surface, ctx, clip, region) {
var me = this,
aggregates = me.getAggregator() && me.getAggregator().getAggregation(
clip[0],
clip[2],
(clip[2] - clip[0]) / region[2] * me.getGapWidth()
);
if (aggregates) {
me.dataStart = aggregates.data.startIdx[aggregates.start];
me.dataEnd = aggregates.data.endIdx[aggregates.end - 1];
me.renderAggregates(aggregates.data, aggregates.start, aggregates.end, surface, ctx, clip, region);
}
}
});

View file

@ -0,0 +1,116 @@
/**
* @class Ext.chart.series.sprite.Area
* @extends Ext.chart.series.sprite.StackedCartesian
*
* Area series sprite.
*/
Ext.define("Ext.chart.series.sprite.Area", {
alias: 'sprite.areaSeries',
extend: "Ext.chart.series.sprite.StackedCartesian",
inheritableStatics: {
def: {
processors: {
/**
* @cfg {Boolean} [step=false] 'true' if the area is represented with steps instead of lines.
*/
step: 'bool'
},
defaults: {
step: false
}
}
},
renderClipped: function (surface, ctx, clip, clipRegion) {
var me = this,
attr = me.attr,
dataX = attr.dataX,
dataY = attr.dataY,
dataStartY = attr.dataStartY,
matrix = attr.matrix,
x, y, i, lastX, lastY,
xx = matrix.elements[0],
dx = matrix.elements[4],
yy = matrix.elements[3],
dy = matrix.elements[5],
surfaceMatrix = me.surfaceMatrix,
markerCfg = {},
start = Math.max(0, this.binarySearch(clip[0])),
end = Math.min(dataX.length - 1, this.binarySearch(clip[2]) + 1);
ctx.beginPath();
if (attr.step) {
lastY = dataY[start] * yy + dy;
for (i = start; i <= end; i++) {
x = dataX[i] * xx + dx;
y = dataY[i] * yy + dy;
ctx.lineTo(x, lastY);
ctx.lineTo(x, lastY = y);
}
} else {
for (i = start; i <= end; i++) {
x = dataX[i] * xx + dx;
y = dataY[i] * yy + dy;
ctx.lineTo(x, y);
}
}
if (dataStartY) {
if (attr.step) {
lastX = dataX[end] * xx + dx;
for (i = end; i >= start; i--) {
x = dataX[i] * xx + dx;
y = dataStartY[i] * yy + dy;
ctx.lineTo(lastX, y);
ctx.lineTo(lastX = x, y);
}
} else {
for (i = end; i >= start; i--) {
x = dataX[i] * xx + dx;
y = dataStartY[i] * yy + dy;
ctx.lineTo(x, y);
}
}
} else {
// dataStartY[i] == 0;
ctx.lineTo(dataX[end] * xx + dx, y);
ctx.lineTo(dataX[end] * xx + dx, dy);
ctx.lineTo(dataX[start] * xx + dx, dy);
ctx.lineTo(dataX[start] * xx + dx, dataY[i] * yy + dy);
}
if (attr.transformFillStroke) {
attr.matrix.toContext(ctx);
}
ctx.fill();
if (attr.transformFillStroke) {
attr.inverseMatrix.toContext(ctx);
}
ctx.beginPath();
if (attr.step) {
for (i = start; i <= end; i++) {
x = dataX[i] * xx + dx;
y = dataY[i] * yy + dy;
ctx.lineTo(x, lastY);
ctx.lineTo(x, lastY = y);
markerCfg.translationX = surfaceMatrix.x(x, y);
markerCfg.translationY = surfaceMatrix.y(x, y);
me.putMarker("markers", markerCfg, i, !attr.renderer);
}
} else {
for (i = start; i <= end; i++) {
x = dataX[i] * xx + dx;
y = dataY[i] * yy + dy;
ctx.lineTo(x, y);
markerCfg.translationX = surfaceMatrix.x(x, y);
markerCfg.translationY = surfaceMatrix.y(x, y);
me.putMarker("markers", markerCfg, i, !attr.renderer);
}
}
if (attr.transformFillStroke) {
attr.matrix.toContext(ctx);
}
ctx.stroke();
}
});

View file

@ -0,0 +1,223 @@
/**
* @class Ext.chart.series.sprite.Bar
* @extends Ext.chart.series.sprite.StackedCartesian
*
* Draws a sprite used in the bar series.
*/
Ext.define('Ext.chart.series.sprite.Bar', {
alias: 'sprite.barSeries',
extend: 'Ext.chart.series.sprite.StackedCartesian',
inheritableStatics: {
def: {
processors: {
/**
* @cfg {Number} [minBarWidth=2] The minimum bar width.
*/
minBarWidth: 'number',
/**
* @cfg {Number} [maxBarWidth=100] The maximum bar width.
*/
maxBarWidth: 'number',
/**
* @cfg {Number} [minGapWidth=5] The minimum gap between bars.
*/
minGapWidth: 'number',
/**
* @cfg {Number} [radius=0] The degree of rounding for rounded bars.
*/
radius: 'number',
/**
* @cfg {Number} [inGroupGapWidth=3] The gap between grouped bars.
*/
inGroupGapWidth: 'number'
},
defaults: {
minBarWidth: 2,
maxBarWidth: 100,
minGapWidth: 5,
inGroupGapWidth: 3,
radius: 0
}
}
},
// TODO: design this more carefully
drawLabel: function (text, dataX, dataStartY, dataY, labelId) {
var me = this,
attr = me.attr,
label = me.getBoundMarker('labels')[0],
labelTpl = label.getTemplate(),
labelCfg = me.labelCfg || (me.labelCfg = {}),
surfaceMatrix = me.surfaceMatrix,
labelOverflowPadding = attr.labelOverflowPadding,
labelDisplay = labelTpl.attr.display,
labelOrientation = labelTpl.attr.orientation,
labelY, halfWidth, labelBox,
changes;
labelBox = me.getMarkerBBox('labels', labelId, true);
labelCfg.text = text;
if (!labelBox) {
me.putMarker('labels', labelCfg, labelId);
labelBox = me.getMarkerBBox('labels', labelId, true);
}
if (!attr.flipXY) {
labelCfg.rotationRads = -Math.PI * 0.5;
} else {
labelCfg.rotationRads = 0;
}
labelCfg.calloutVertical = !attr.flipXY;
switch (labelOrientation) {
case 'horizontal': labelCfg.rotationRads = 0; break;
case 'vertical': labelCfg.rotationRads = -Math.PI * 0.5; break;
}
halfWidth = (labelBox.width / 2 + labelOverflowPadding);
if (dataStartY > dataY) {
halfWidth = -halfWidth;
}
if ((labelOrientation === 'horizontal' && attr.flipXY) || (labelOrientation === 'vertical' && !attr.flipXY) || !labelOrientation) {
labelY = (labelDisplay === 'insideStart') ? dataStartY + halfWidth : dataY - halfWidth;
} else {
labelY = (labelDisplay === 'insideStart') ? dataStartY + labelOverflowPadding * 2 : dataY - labelOverflowPadding * 2;
}
labelCfg.x = surfaceMatrix.x(dataX, labelY);
labelCfg.y = surfaceMatrix.y(dataX, labelY);
labelY = (labelDisplay === 'insideStart') ? dataStartY - halfWidth : dataY + halfWidth;
labelCfg.calloutPlaceX = surfaceMatrix.x(dataX, labelY);
labelCfg.calloutPlaceY = surfaceMatrix.y(dataX, labelY);
labelY = (labelDisplay === 'insideStart') ? dataStartY : dataY;
labelCfg.calloutStartX = surfaceMatrix.x(dataX, labelY);
labelCfg.calloutStartY = surfaceMatrix.y(dataX, labelY);
if (dataStartY > dataY) {
halfWidth = -halfWidth;
}
if (Math.abs(dataY - dataStartY) <= halfWidth * 2 || labelDisplay === 'outside') {
labelCfg.callout = 1;
} else {
labelCfg.callout = 0;
}
if (labelTpl.attr.renderer) {
changes = labelTpl.attr.renderer.call(this, text, label, labelCfg, {store: this.getStore()}, labelId);
if (typeof changes === 'string') {
labelCfg.text = changes;
} else {
Ext.apply(labelCfg, changes);
}
}
me.putMarker('labels', labelCfg, labelId);
},
drawBar: function (ctx, surface, clip, left, top, right, bottom, index) {
var itemCfg = this.itemCfg || (this.itemCfg = {}),
changes;
itemCfg.x = left;
itemCfg.y = top;
itemCfg.width = right - left;
itemCfg.height = bottom - top;
itemCfg.radius = this.attr.radius;
if (this.attr.renderer) {
changes = this.attr.renderer.call(this, this, itemCfg, {store:this.getStore()}, index);
Ext.apply(itemCfg, changes);
}
this.putMarker('items', itemCfg, index, !this.attr.renderer);
},
//@inheritdoc
renderClipped: function (surface, ctx, clip) {
if (this.cleanRedraw) {
return;
}
var me = this,
attr = me.attr,
dataX = attr.dataX,
dataY = attr.dataY,
dataText = attr.labels,
dataStartY = attr.dataStartY,
groupCount = attr.groupCount,
groupOffset = attr.groupOffset - (groupCount - 1) * 0.5,
inGroupGapWidth = attr.inGroupGapWidth,
yLow, yHi,
lineWidth = ctx.lineWidth,
matrix = attr.matrix,
xx = matrix.elements[0],
yy = matrix.elements[3],
dx = matrix.elements[4],
dy = surface.roundPixel(matrix.elements[5]) - 1,
maxBarWidth = xx - attr.minGapWidth,
barWidth = surface.roundPixel(Math.max(attr.minBarWidth, (Math.min(maxBarWidth, attr.maxBarWidth) - inGroupGapWidth * (groupCount - 1)) / groupCount)),
surfaceMatrix = this.surfaceMatrix,
left, right, bottom, top, i, center,
halfLineWidth = 0.5 * attr.lineWidth,
start = Math.max(0, Math.floor(clip[0])),
end = Math.min(dataX.length - 1, Math.ceil(clip[2])),
drawMarkers = dataText && !!this.getBoundMarker('labels');
for (i = start; i <= end; i++) {
yLow = dataStartY ? dataStartY[i] : 0;
yHi = dataY[i];
center = dataX[i] * xx + dx + groupOffset * (barWidth + inGroupGapWidth);
left = surface.roundPixel(center - barWidth / 2) + halfLineWidth;
top = surface.roundPixel(yHi * yy + lineWidth + dy);
right = surface.roundPixel(center + barWidth / 2) - halfLineWidth;
bottom = surface.roundPixel(yLow * yy + lineWidth + dy);
me.drawBar(ctx, surface, clip, left, top - halfLineWidth, right, bottom - halfLineWidth, i);
if (drawMarkers && dataText[i]) {
me.drawLabel(dataText[i], center, bottom, top, i);
}
me.putMarker('markers', {
translationX: surfaceMatrix.x(center, top),
translationY: surfaceMatrix.y(center, top)
}, i, true);
}
},
//@inheritdoc
getIndexNearPoint: function (x, y) {
var sprite = this,
attr = sprite.attr,
dataX = attr.dataX,
surface = sprite.getParent(),
surfaceRegion = surface.getRegion(),
surfaceHeight = surfaceRegion[3],
hitX, hitY, index = -1;
// The "items" sprites that draw the bars work in a reverse vertical coordinate system
// starting with 0 at the bottom and increasing the Y coordinate toward the top.
// See also Ext.chart.series.Bar.getItemForPoint(x,y) regarding the chart's InnerPadding.
//
// TODO: Cleanup the bar sprites.
if (attr.flipXY) {
hitX = surfaceHeight - y;
hitY = x;
} else {
hitX = x;
hitY = surfaceHeight - y;
}
for (var i = 0; i < dataX.length; i++) {
var bbox = sprite.getMarkerBBox('items', i);
if (bbox && hitX >= bbox.x && hitX <= (bbox.x + bbox.width) && hitY >= bbox.y && hitY <= (bbox.y + bbox.height)) {
index = i;
}
}
return index;
}
});

View file

@ -0,0 +1,165 @@
/**
* @class Ext.chart.series.sprite.CandleStick
* @extends Ext.chart.series.sprite.Aggregative
*
* CandleStick series sprite.
*/
Ext.define('Ext.chart.series.sprite.CandleStick', {
alias: 'sprite.candlestickSeries',
extend: 'Ext.chart.series.sprite.Aggregative',
inheritableStatics: {
def: {
processors: {
raiseStyle: function (n, o) {
return Ext.merge({}, o || {}, n);
},
dropStyle: function (n, o) {
return Ext.merge({}, o || {}, n);
},
/**
* @cfg {Number} [barWidth=15] The bar width of the candles.
*/
barWidth: 'number',
/**
* @cfg {Number} [padding=3] The amount of padding between candles.
*/
padding: 'number',
/**
* @cfg {String} [ohlcType='candlestick'] Determines whether candlestick or ohlc is used.
*/
ohlcType: 'enums(candlestick,ohlc)'
},
defaults: {
raiseStyle: {
strokeStyle: 'green',
fillStyle: 'green'
},
dropStyle: {
strokeStyle: 'red',
fillStyle: 'red'
},
planar: false,
barWidth: 15,
padding: 3,
lineJoin: 'miter',
miterLimit: 5,
ohlcType: 'candlestick'
},
dirtyTriggers: {
raiseStyle: 'raiseStyle',
dropStyle: 'dropStyle'
},
updaters: {
raiseStyle: function () {
this.raiseTemplate && this.raiseTemplate.setAttributes(this.attr.raiseStyle);
},
dropStyle: function () {
this.dropTemplate && this.dropTemplate.setAttributes(this.attr.dropStyle);
}
}
}
},
candlestick: function (ctx, open, high, low, close, mid, halfWidth) {
var minOC = Math.min(open, close),
maxOC = Math.max(open, close);
ctx.moveTo(mid, low);
ctx.lineTo(mid, maxOC);
ctx.moveTo(mid + halfWidth, maxOC);
ctx.lineTo(mid + halfWidth, minOC);
ctx.lineTo(mid - halfWidth, minOC);
ctx.lineTo(mid - halfWidth, maxOC);
ctx.closePath();
ctx.moveTo(mid, high);
ctx.lineTo(mid, minOC);
},
ohlc: function (ctx, open, high, low, close, mid, halfWidth) {
ctx.moveTo(mid, high);
ctx.lineTo(mid, low);
ctx.moveTo(mid, open);
ctx.lineTo(mid - halfWidth, open);
ctx.moveTo(mid, close);
ctx.lineTo(mid + halfWidth, close);
},
constructor: function () {
this.callSuper(arguments);
this.raiseTemplate = new Ext.draw.sprite.Rect({parent: this});
this.dropTemplate = new Ext.draw.sprite.Rect({parent: this});
},
getGapWidth: function () {
var attr = this.attr,
barWidth = attr.barWidth,
padding = attr.padding;
return barWidth + padding;
},
renderAggregates: function (aggregates, start, end, surface, ctx, clip, region) {
var me = this,
attr = this.attr,
dataX = attr.dataX,
matrix = attr.matrix,
xx = matrix.getXX(),
yy = matrix.getYY(),
dx = matrix.getDX(),
dy = matrix.getDY(),
barWidth = attr.barWidth / xx,
template,
ohlcType = attr.ohlcType,
halfWidth = Math.round(barWidth * 0.5 * xx),
opens = aggregates.open,
highs = aggregates.high,
lows = aggregates.low,
closes = aggregates.close,
maxYs = aggregates.maxY,
minYs = aggregates.minY,
startIdxs = aggregates.startIdx,
open, high, low, close, mid,
i,
pixelAdjust = attr.lineWidth * surface.devicePixelRatio / 2;
pixelAdjust -= Math.floor(pixelAdjust);
ctx.save();
template = this.raiseTemplate;
template.useAttributes(ctx);
ctx.beginPath();
for (i = start; i < end; i++) {
if (opens[i] <= closes[i]) {
open = Math.round(opens[i] * yy + dy) + pixelAdjust;
high = Math.round(maxYs[i] * yy + dy) + pixelAdjust;
low = Math.round(minYs[i] * yy + dy) + pixelAdjust;
close = Math.round(closes[i] * yy + dy) + pixelAdjust;
mid = Math.round(dataX[startIdxs[i]] * xx + dx) + pixelAdjust;
me[ohlcType](ctx, open, high, low, close, mid, halfWidth);
}
}
ctx.fillStroke(template.attr);
ctx.restore();
ctx.save();
template = this.dropTemplate;
template.useAttributes(ctx);
ctx.beginPath();
for (i = start; i < end; i++) {
if (opens[i] > closes[i]) {
open = Math.round(opens[i] * yy + dy) + pixelAdjust;
high = Math.round(maxYs[i] * yy + dy) + pixelAdjust;
low = Math.round(minYs[i] * yy + dy) + pixelAdjust;
close = Math.round(closes[i] * yy + dy) + pixelAdjust;
mid = Math.round(dataX[startIdxs[i]] * xx + dx) + pixelAdjust;
me[ohlcType](ctx, open, high, low, close, mid, halfWidth);
}
}
ctx.fillStroke(template.attr);
ctx.restore();
}
});

View file

@ -0,0 +1,284 @@
/**
* @class Ext.chart.series.sprite.Cartesian
* @extends Ext.draw.sprite.Sprite
*
* Cartesian sprite.
*/
Ext.define('Ext.chart.series.sprite.Cartesian', {
extend: 'Ext.draw.sprite.Sprite',
mixins: {
markerHolder: 'Ext.chart.MarkerHolder'
},
homogeneous: true,
ascending: true,
inheritableStatics: {
def: {
processors: {
/**
* @cfg {Number} [dataMinX=0] Data minimum on the x-axis.
*/
dataMinX: 'number',
/**
* @cfg {Number} [dataMaxX=1] Data maximum on the x-axis.
*/
dataMaxX: 'number',
/**
* @cfg {Number} [dataMinY=0] Data minimum on the y-axis.
*/
dataMinY: 'number',
/**
* @cfg {Number} [dataMaxY=2] Data maximum on the y-axis.
*/
dataMaxY: 'number',
/**
* @cfg {Array} Data range derived from all the series bound to the x-axis.
*/
rangeX: 'data',
/**
* @cfg {Array} Data range derived from all the series bound to the y-axis.
*/
rangeY: 'data',
/**
* @cfg {Object} [dataY=null] Data items on the y-axis.
*/
dataY: 'data',
/**
* @cfg {Object} [dataX=null] Data items on the x-axis.
*/
dataX: 'data',
/**
* @cfg {Object} [labels=null] Labels used in the series.
*/
labels: 'default',
/**
* @cfg {Number} [labelOverflowPadding=10] Padding around labels to determine overlap.
*/
labelOverflowPadding: 'number',
/**
* @cfg {Number} [selectionTolerance=20]
* The distance from the event position to the sprite's data points to trigger interactions (used for 'iteminfo', etc).
*/
selectionTolerance: 'number',
/**
* @cfg {Boolean} If flipXY is 'true', the series is flipped.
*/
flipXY: 'bool',
renderer: 'default',
// PanZoom information
visibleMinX: 'number',
visibleMinY: 'number',
visibleMaxX: 'number',
visibleMaxY: 'number',
innerWidth: 'number',
innerHeight: 'number'
},
defaults: {
dataY: null,
dataX: null,
dataMinX: 0,
dataMaxX: 1,
dataMinY: 0,
dataMaxY: 1,
labels: null,
labelOverflowPadding: 10,
selectionTolerance: 20,
flipXY: false,
renderer: null,
transformFillStroke: false,
visibleMinX: 0,
visibleMinY: 0,
visibleMaxX: 1,
visibleMaxY: 1,
innerWidth: 1,
innerHeight: 1
},
dirtyTriggers: {
dataX: 'dataX,bbox',
dataY: 'dataY,bbox',
dataMinX: 'bbox',
dataMaxX: 'bbox',
dataMinY: 'bbox',
dataMaxY: 'bbox',
visibleMinX: 'panzoom',
visibleMinY: 'panzoom',
visibleMaxX: 'panzoom',
visibleMaxY: 'panzoom',
innerWidth: 'panzoom',
innerHeight: 'panzoom'
},
updaters: {
dataX: function (attrs) {
this.processDataX();
if (!attrs.dirtyFlags.dataY) {
attrs.dirtyFlags.dataY = [];
}
attrs.dirtyFlags.dataY.push('dataY');
},
dataY: function () {
this.processDataY();
},
panzoom: function (attrs) {
var dx = attrs.visibleMaxX - attrs.visibleMinX,
dy = attrs.visibleMaxY - attrs.visibleMinY,
innerWidth = attrs.flipXY ? attrs.innerHeight : attrs.innerWidth,
innerHeight = !attrs.flipXY ? attrs.innerHeight : attrs.innerWidth;
attrs.translationX = -attrs.visibleMinX * innerWidth / dx;
attrs.translationY = -attrs.visibleMinY * innerHeight / dy;
attrs.scalingX = innerWidth / dx;
attrs.scalingY = innerHeight / dy;
attrs.scalingCenterX = 0;
attrs.scalingCenterY = 0;
this.applyTransformations(true);
}
}
}
},
config: {
/**
* @private
* @cfg {Object} store The store that is passed to the renderer.
*/
store: null,
/**
* @cfg {String} field The store field used by the series.
*/
field: null
},
processDataY: Ext.emptyFn,
processDataX: Ext.emptyFn,
updatePlainBBox: function (plain) {
var attr = this.attr;
plain.x = attr.dataMinX;
plain.y = attr.dataMinY;
plain.width = attr.dataMaxX - attr.dataMinX;
plain.height = attr.dataMaxY - attr.dataMinY;
},
/**
* Does a binary search of the data on the x-axis using the given key.
* @param {String} key
* @return {*}
*/
binarySearch: function (key) {
var dx = this.attr.dataX,
start = 0,
end = dx.length;
if (key <= dx[0]) {
return start;
}
if (key >= dx[end - 1]) {
return end - 1;
}
while (start + 1 < end) {
var mid = (start + end) >> 1,
val = dx[mid];
if (val === key) {
return mid;
} else if (val < key) {
start = mid;
} else {
end = mid;
}
}
return start;
},
render: function (surface, ctx, region) {
var me = this,
attr = me.attr,
flipXY = attr.flipXY,
inverseMatrix = attr.inverseMatrix.clone();
inverseMatrix.appendMatrix(surface.inverseMatrix);
if (attr.dataX === null) {
return;
}
if (attr.dataY === null) {
return;
}
if (inverseMatrix.getXX() * inverseMatrix.getYX() || inverseMatrix.getXY() * inverseMatrix.getYY()) {
console.log('Cartesian Series sprite does not support rotation/sheering');
return;
}
var clip = inverseMatrix.transformList([
[region[0] - 1, region[3] + 1],
[region[0] + region[2] + 1, -1]
]);
clip = clip[0].concat(clip[1]);
if (clip[2] < clip[0]) {
console.log('Cartesian Series sprite does not supports flipped X.');
// TODO: support it
return;
}
me.renderClipped(surface, ctx, clip, region);
},
/**
* Render the given visible clip range.
* @param {Ext.draw.Surface} surface
* @param {Ext.draw.engine.Canvas/Ext.draw.engine.SvgContext} ctx
* @param {Array} clip
* @param {Arrary} region
*/
renderClipped: Ext.emptyFn,
/**
* Get the nearest item index from point (x, y). -1 as not found.
* @param {Number} x
* @param {Number} y
* @return {Number} The index
*/
getIndexNearPoint: function (x, y) {
var sprite = this,
mat = sprite.attr.matrix,
dataX = sprite.attr.dataX,
dataY = sprite.attr.dataY,
selectionTolerance = sprite.attr.selectionTolerance,
minX, minY, index = -1,
imat = mat.clone().prependMatrix(this.surfaceMatrix).inverse(),
center = imat.transformPoint([x, y]),
positionLB = imat.transformPoint([x - selectionTolerance, y - selectionTolerance]),
positionTR = imat.transformPoint([x + selectionTolerance, y + selectionTolerance]),
left = Math.min(positionLB[0], positionTR[0]),
right = Math.max(positionLB[0], positionTR[0]),
top = Math.min(positionLB[1], positionTR[1]),
bottom = Math.max(positionLB[1], positionTR[1]);
for (var i = 0; i < dataX.length; i++) {
if (left < dataX[i] && dataX[i] < right && top < dataY[i] && dataY[i] < bottom) {
if (index === -1 || (Math.abs(dataX[i] - center[0]) < minX) && (Math.abs(dataY[i] - center[1]) < minY)) {
minX = Math.abs(dataX[i] - center[0]);
minY = Math.abs(dataY[i] - center[1]);
index = i;
}
}
}
return index;
}
});

View file

@ -0,0 +1,387 @@
/**
* @class Ext.chart.series.sprite.Line
* @extends Ext.chart.series.sprite.Aggregative
*
* Line series sprite.
*/
Ext.define('Ext.chart.series.sprite.Line', {
alias: 'sprite.lineSeries',
extend: 'Ext.chart.series.sprite.Aggregative',
inheritableStatics: {
def: {
processors: {
smooth: 'bool',
fillArea: 'bool',
step: 'bool',
preciseStroke: 'bool'
},
defaults: {
/**
* @cfg {Boolean} smooth 'true' if the sprite uses line smoothing.
*/
smooth: false,
/**
* @cfg {Boolean} fillArea 'true' if the sprite paints the area underneath the line.
*/
fillArea: false,
/**
* @cfg {Boolean} step 'true' if the line uses steps instead of straight lines to connect the dots.
* It is ignored if `smooth` is true.
*/
step: false,
/**
* @cfg {Boolean} preciseStroke 'true' if the line uses precise stroke.
*/
preciseStroke: true
},
dirtyTriggers: {
dataX: 'dataX,bbox,smooth',
dataY: 'dataY,bbox,smooth',
smooth: 'smooth'
},
updaters: {
smooth: function (attr) {
if (attr.smooth && attr.dataX && attr.dataY && attr.dataX.length > 2 && attr.dataY.length > 2) {
this.smoothX = Ext.draw.Draw.spline(attr.dataX);
this.smoothY = Ext.draw.Draw.spline(attr.dataY);
} else {
delete this.smoothX;
delete this.smoothY;
}
}
}
}
},
list: null,
updatePlainBBox: function (plain) {
var attr = this.attr,
ymin = Math.min(0, attr.dataMinY),
ymax = Math.max(0, attr.dataMaxY);
plain.x = attr.dataMinX;
plain.y = ymin;
plain.width = attr.dataMaxX - attr.dataMinX;
plain.height = ymax - ymin;
},
drawStroke: function (surface, ctx, start, end, list, xAxis) {
var attr = this.attr,
matrix = attr.matrix,
xx = matrix.getXX(),
yy = matrix.getYY(),
dx = matrix.getDX(),
dy = matrix.getDY(),
smooth = attr.smooth,
step = attr.step,
scale = Math.pow(2, power(attr.dataX.length, end)),
smoothX = this.smoothX,
smoothY = this.smoothY,
i, j, lineConfig, changes,
cx1, cy1, cx2, cy2, x, y, x0, y0, saveOpacity;
function power(count, end) {
var power = 0,
n = count;
while (n > 0 && n < end) {
power++;
n += count >> power;
}
return power > 0 ? power - 1 : power;
}
ctx.beginPath();
if (smooth && smoothX && smoothY) {
ctx.moveTo(smoothX[start * 3] * xx + dx, smoothY[start * 3] * yy + dy);
for (i = 0, j = start * 3 + 1; i < list.length - 3; i += 3, j += 3 * scale) {
cx1 = smoothX[j] * xx + dx;
cy1 = smoothY[j] * yy + dy;
cx2 = smoothX[j + 1] * xx + dx;
cy2 = smoothY[j + 1] * yy + dy;
x = list[i + 3];
y = list[i + 4];
x0 = list[i];
y0 = list[i + 1];
if (attr.renderer) {
lineConfig = {
type: 'line',
smooth: true,
step: step,
cx1: cx1,
cy1: cy1,
cx2: cx2,
cy2: cy2,
x: x,
y: y,
x0: x0,
y0: y0
};
changes = attr.renderer.call(this, this, lineConfig, {store:this.getStore()}, (i/3 + 1));
ctx.save();
Ext.apply(ctx, changes);
// Fill the area if we need to, using the fill color and transparent strokes.
if (attr.fillArea) {
saveOpacity = ctx.strokeOpacity;
ctx.save();
ctx.strokeOpacity = 0;
ctx.moveTo(x0, y0);
ctx.bezierCurveTo(cx1, cy1, cx2, cy2, x, y);
ctx.lineTo(x, xAxis);
ctx.lineTo(x0, xAxis);
ctx.lineTo(x0, y0);
ctx.closePath();
ctx.fillStroke(attr, true);
ctx.restore();
ctx.strokeOpacity = saveOpacity;
ctx.beginPath();
}
// Draw the line on top of the filled area.
ctx.moveTo(x0, y0);
ctx.bezierCurveTo(cx1, cy1, cx2, cy2, x, y);
ctx.moveTo(x0, y0);
ctx.closePath();
ctx.stroke();
ctx.restore();
ctx.beginPath();
ctx.moveTo(x, y);
} else {
ctx.bezierCurveTo(cx1, cy1, cx2, cy2, x, y);
}
}
} else {
ctx.moveTo(list[0], list[1]);
for (i = 3; i < list.length; i += 3) {
x = list[i];
y = list[i + 1];
x0 = list[i - 3];
y0 = list[i - 2];
if (attr.renderer) {
lineConfig = {
type: 'line',
smooth: false,
step: step,
x: x,
y: y,
x0: x0,
y0: y0
};
changes = attr.renderer.call(this, this, lineConfig, {store:this.getStore()}, i/3);
ctx.save();
Ext.apply(ctx, changes);
// Fill the area if we need to, using the fill color and transparent strokes.
if (attr.fillArea) {
saveOpacity = ctx.strokeOpacity;
ctx.save();
ctx.strokeOpacity = 0;
if (step) {
ctx.lineTo(x, y0);
} else {
ctx.lineTo(x, y);
}
ctx.lineTo(x, xAxis);
ctx.lineTo(x0, xAxis);
ctx.lineTo(x0, y0);
ctx.closePath();
ctx.fillStroke(attr, true);
ctx.restore();
ctx.strokeOpacity = saveOpacity;
ctx.beginPath();
}
// Draw the line (or the 2 lines if 'step') on top of the filled area.
ctx.moveTo(x0, y0);
if (step) {
ctx.lineTo(x, y0);
ctx.closePath();
ctx.stroke();
ctx.beginPath();
ctx.moveTo(x, y0);
}
ctx.lineTo(x, y);
ctx.closePath();
ctx.stroke();
ctx.restore();
ctx.beginPath();
ctx.moveTo(x, y);
} else {
if (step) {
ctx.lineTo(x, y0);
}
ctx.lineTo(x, y);
}
}
}
},
drawLabel: function (text, dataX, dataY, labelId, region) {
var me = this,
attr = me.attr,
label = me.getBoundMarker('labels')[0],
labelTpl = label.getTemplate(),
labelCfg = me.labelCfg || (me.labelCfg = {}),
surfaceMatrix = me.surfaceMatrix,
labelX, labelY,
labelOverflowPadding = attr.labelOverflowPadding,
halfWidth, halfHeight,
labelBox,
changes;
labelCfg.text = text;
labelBox = this.getMarkerBBox('labels', labelId, true);
if (!labelBox) {
me.putMarker('labels', labelCfg, labelId);
labelBox = this.getMarkerBBox('labels', labelId, true);
}
if (attr.flipXY) {
labelCfg.rotationRads = Math.PI * 0.5;
} else {
labelCfg.rotationRads = 0;
}
halfWidth = labelBox.width / 2;
halfHeight = labelBox.height / 2;
labelX = dataX;
if (labelTpl.attr.display === 'over') {
labelY = dataY + halfHeight + labelOverflowPadding;
} else {
labelY = dataY - halfHeight - labelOverflowPadding;
}
if (labelX <= region[0] + halfWidth) {
labelX = region[0] + halfWidth;
} else if (labelX >= region[2] - halfWidth) {
labelX = region[2] - halfWidth;
}
if (labelY <= region[1] + halfHeight) {
labelY = region[1] + halfHeight;
} else if (labelY >= region[3] - halfHeight) {
labelY = region[3] - halfHeight;
}
labelCfg.x = surfaceMatrix.x(labelX, labelY);
labelCfg.y = surfaceMatrix.y(labelX, labelY);
if (labelTpl.attr.renderer) {
changes = labelTpl.attr.renderer.call(this, text, label, labelCfg, {store: this.getStore()}, labelId);
if (typeof changes === 'string') {
labelCfg.text = changes;
} else {
Ext.apply(labelCfg, changes);
}
}
me.putMarker('labels', labelCfg, labelId);
},
renderAggregates: function (aggregates, start, end, surface, ctx, clip, region) {
var me = this,
attr = me.attr,
dataX = attr.dataX,
dataY = attr.dataY,
labels = attr.labels,
drawLabels = labels && !!me.getBoundMarker('labels'),
matrix = attr.matrix,
surfaceMatrix = surface.matrix,
pixel = surface.devicePixelRatio,
xx = matrix.getXX(),
yy = matrix.getYY(),
dx = matrix.getDX(),
dy = matrix.getDY(),
markerCfg = {},
list = this.list || (this.list = []),
x, y, i, index,
minXs = aggregates.minX,
maxXs = aggregates.maxX,
minYs = aggregates.minY,
maxYs = aggregates.maxY,
idx = aggregates.startIdx;
list.length = 0;
for (i = start; i < end; i++) {
var minX = minXs[i],
maxX = maxXs[i],
minY = minYs[i],
maxY = maxYs[i];
if (minX < maxX) {
list.push(minX * xx + dx, minY * yy + dy, idx[i]);
list.push(maxX * xx + dx, maxY * yy + dy, idx[i]);
} else if (minX > maxX) {
list.push(maxX * xx + dx, maxY * yy + dy, idx[i]);
list.push(minX * xx + dx, minY * yy + dy, idx[i]);
} else {
list.push(maxX * xx + dx, maxY * yy + dy, idx[i]);
}
}
if (list.length) {
for (i = 0; i < list.length; i += 3) {
x = list[i];
y = list[i + 1];
index = list[i + 2];
if (attr.renderer) {
markerCfg = {
type: 'marker',
x: x,
y: y
};
markerCfg = attr.renderer.call(this, this, markerCfg, {store:this.getStore()}, i/3) || {};
}
markerCfg.translationX = surfaceMatrix.x(x, y);
markerCfg.translationY = surfaceMatrix.y(x, y);
me.putMarker('markers', markerCfg, index, !attr.renderer);
if (drawLabels && labels[index]) {
me.drawLabel(labels[index], x, y, index, region);
}
}
me.drawStroke(surface, ctx, start, end, list, region[1] - pixel);
if (!attr.renderer) {
var lastPointX = dataX[dataX.length - 1] * xx + dx + pixel,
lastPointY = dataY[dataY.length - 1] * yy + dy,
bottomY = region[1] - pixel,
firstPointX = dataX[0] * xx + dx - pixel,
firstPointY = dataY[0] * yy + dy;
ctx.lineTo(lastPointX, lastPointY);
ctx.lineTo(lastPointX, bottomY);
ctx.lineTo(firstPointX, bottomY);
ctx.lineTo(firstPointX, firstPointY);
}
ctx.closePath();
if (attr.transformFillStroke) {
attr.matrix.toContext(ctx);
}
if (attr.preciseStroke) {
if (attr.fillArea) {
ctx.fill();
}
if (attr.transformFillStroke) {
attr.inverseMatrix.toContext(ctx);
}
me.drawStroke(surface, ctx, start, end, list, region[1] - pixel);
if (attr.transformFillStroke) {
attr.matrix.toContext(ctx);
}
ctx.stroke();
} else {
// Prevent the reverse transform to fix floating point err.
if (attr.fillArea) {
ctx.fillStroke(attr, true);
} else {
ctx.stroke(true);
}
}
}
}
});

View file

@ -0,0 +1,377 @@
/**
* @class Ext.chart.series.sprite.Pie3DPart
* @extends Ext.draw.sprite.Path
*
* Pie3D series sprite.
*/
Ext.define("Ext.chart.series.sprite.Pie3DPart", {
extend: 'Ext.draw.sprite.Path',
mixins: {
markerHolder: "Ext.chart.MarkerHolder"
},
alias: 'sprite.pie3dPart',
type: 'pie3dPart',
inheritableStatics: {
def: {
processors: {
/**
* @cfg {Number} [centerX=0] The central point of the series on the x-axis.
*/
centerX: "number",
/**
* @cfg {Number} [centerY=0] The central point of the series on the x-axis.
*/
centerY: "number",
/**
* @cfg {Number} [startAngle=0] The starting angle of the polar series.
*/
startAngle: "number",
/**
* @cfg {Number} [endAngle=Math.PI] The ending angle of the polar series.
*/
endAngle: "number",
/**
* @cfg {Number} [startRho=0] The starting radius of the polar series.
*/
startRho: "number",
/**
* @cfg {Number} [endRho=150] The ending radius of the polar series.
*/
endRho: "number",
/**
* @cfg {Number} [margin=0] Margin from the center of the pie. Used for donut.
*/
margin: "number",
/**
* @cfg {Number} [thickness=0] The thickness of the 3D pie part.
*/
thickness: "number",
/**
* @cfg {Number} [distortion=0] The distortion of the 3D pie part.
*/
distortion: "number",
/**
* @cfg {Object} [baseColor='white'] The color of the 3D pie part before adding the 3D effect.
*/
baseColor: "color",
/**
* @cfg {Number} [baseRotation=0] The starting rotation of the polar series.
*/
baseRotation: "number",
/**
* @cfg {String} [part=0] The part of the 3D Pie represented by the sprite.
*/
part: "enums(top,start,end,inner,outer)"
},
aliases: {
rho: 'endRho'
},
dirtyTriggers: {
centerX: "path,bbox",
centerY: "path,bbox",
startAngle: "path,partZIndex",
endAngle: "path,partZIndex",
startRho: "path",
endRho: "path,bbox",
margin: "path,bbox",
thickness: "path",
baseRotation: "path,partZIndex,partColor",
baseColor: 'partZIndex,partColor',
part: "path,partZIndex"
},
defaults: {
centerX: 0,
centerY: 0,
startAngle: 0,
endAngle: 0,
startRho: 0,
endRho: 150,
margin: 0,
distortion: 1,
baseRotation: 0,
baseColor: 'white',
part: "top"
},
updaters: {
"partColor": function (attrs) {
var color = Ext.draw.Color.fly(attrs.baseColor),
fillStyle;
switch (attrs.part) {
case 'top':
fillStyle = color.toString();
break;
case 'outer':
fillStyle = Ext.create("Ext.draw.gradient.Linear", {
type: 'linear',
stops: [
{
offset: 0,
color: color.createDarker(0.3).toString()
},
{
offset: 0.3,
color: color.toString()
},
{
offset: 0.8,
color: color.createLighter(0.2).toString()
},
{
offset: 1,
color: color.createDarker(0.4).toString()
}
]
});
break;
case 'start':
fillStyle = color.createDarker(0.3).toString();
break;
case 'end':
fillStyle = color.createDarker(0.3).toString();
break;
case 'inner':
fillStyle = Ext.create("Ext.draw.gradient.Linear", {
type: 'linear',
stops: [
{
offset: 0,
color: color.createDarker(0.4).toString()
},
{
offset: 0.2,
color: color.createLighter(0.2).toString()
},
{
offset: 0.7,
color: color.toString()
},
{
offset: 1,
color: color.createDarker(0.3).toString()
}
]
});
break;
}
attrs.fillStyle = fillStyle;
attrs.canvasAttributes.fillStyle = fillStyle;
},
"partZIndex": function (attrs) {
var rotation = attrs.baseRotation;
switch (attrs.part) {
case 'top':
attrs.zIndex = 5;
break;
case 'outer':
attrs.zIndex = 4;
break;
case 'start':
attrs.zIndex = 1 + Math.sin(attrs.startAngle + rotation);
break;
case 'end':
attrs.zIndex = 1 + Math.sin(attrs.endAngle + rotation);
break;
case 'inner':
attrs.zIndex = 1;
break;
}
attrs.dirtyZIndex = true;
}
}
}
},
updatePlainBBox: function (plain) {
var attr = this.attr,
rho = attr.part === 'inner' ? attr.startRho : attr.endRho;
plain.width = rho * 2;
plain.height = rho * attr.distortion * 2 + attr.thickness;
plain.x = attr.centerX - rho;
plain.y = attr.centerY - rho * attr.distortion;
},
updateTransformedBBox: function (transform) {
return this.updatePlainBBox(transform);
},
updatePath: function (path) {
if (this.attr.endAngle < this.attr.startAngle) {
return;
}
this[this.attr.part + 'Renderer'](path);
},
topRenderer: function (path) {
var attr = this.attr,
margin = attr.margin,
distortion = attr.distortion,
centerX = attr.centerX,
centerY = attr.centerY,
baseRotation = attr.baseRotation,
startAngle = attr.startAngle + baseRotation ,
endAngle = attr.endAngle + baseRotation ,
startRho = attr.startRho,
endRho = attr.endRho,
midAngle,
sinEnd = Math.sin(endAngle),
cosEnd = Math.cos(endAngle);
midAngle = (startAngle + endAngle) * 0.5;
centerX += Math.cos(midAngle) * margin;
centerY += Math.sin(midAngle) * margin * distortion;
path.ellipse(centerX, centerY, startRho, startRho * distortion, 0, startAngle, endAngle, false);
path.lineTo(centerX + cosEnd * endRho, centerY + sinEnd * endRho * distortion);
path.ellipse(centerX, centerY, endRho, endRho * distortion, 0, endAngle, startAngle, true);
path.closePath();
},
startRenderer: function (path) {
var attr = this.attr,
margin = attr.margin,
centerX = attr.centerX,
centerY = attr.centerY,
distortion = attr.distortion,
baseRotation = attr.baseRotation,
startAngle = attr.startAngle + baseRotation ,
endAngle = attr.endAngle + baseRotation,
thickness = attr.thickness,
startRho = attr.startRho,
endRho = attr.endRho,
sinStart = Math.sin(startAngle),
cosStart = Math.cos(startAngle),
midAngle;
if (cosStart < 0) {
midAngle = (startAngle + endAngle) * 0.5;
centerX += Math.cos(midAngle) * margin;
centerY += Math.sin(midAngle) * margin * distortion;
path.moveTo(centerX + cosStart * startRho, centerY + sinStart * startRho * distortion);
path.lineTo(centerX + cosStart * endRho, centerY + sinStart * endRho * distortion);
path.lineTo(centerX + cosStart * endRho, centerY + sinStart * endRho * distortion + thickness);
path.lineTo(centerX + cosStart * startRho, centerY + sinStart * startRho * distortion + thickness);
path.closePath();
}
},
endRenderer: function (path) {
var attr = this.attr,
margin = attr.margin,
centerX = attr.centerX,
centerY = attr.centerY,
distortion = attr.distortion,
baseRotation = attr.baseRotation,
startAngle = attr.startAngle + baseRotation ,
endAngle = attr.endAngle + baseRotation,
thickness = attr.thickness,
startRho = attr.startRho,
endRho = attr.endRho,
sin = Math.sin(endAngle),
cos = Math.cos(endAngle), midAngle;
if (cos > 0) {
midAngle = (startAngle + endAngle) * 0.5;
centerX += Math.cos(midAngle) * margin;
centerY += Math.sin(midAngle) * margin * distortion;
path.moveTo(centerX + cos * startRho, centerY + sin * startRho * distortion);
path.lineTo(centerX + cos * endRho, centerY + sin * endRho * distortion);
path.lineTo(centerX + cos * endRho, centerY + sin * endRho * distortion + thickness);
path.lineTo(centerX + cos * startRho, centerY + sin * startRho * distortion + thickness);
path.closePath();
}
},
innerRenderer: function (path) {
var attr = this.attr,
margin = attr.margin,
centerX = attr.centerX,
centerY = attr.centerY,
distortion = attr.distortion,
baseRotation = attr.baseRotation,
startAngle = attr.startAngle + baseRotation ,
endAngle = attr.endAngle + baseRotation,
thickness = attr.thickness,
startRho = attr.startRho,
sinEnd, cosEnd,
tempStart, tempEnd, midAngle;
midAngle = (startAngle + endAngle) * 0.5;
centerX += Math.cos(midAngle) * margin;
centerY += Math.sin(midAngle) * margin * distortion;
if (startAngle >= Math.PI * 2) {
startAngle -= Math.PI * 2;
endAngle -= Math.PI * 2;
}
if (endAngle > Math.PI && endAngle < Math.PI * 3) {
tempStart = startAngle;
tempEnd = Math.min(endAngle, Math.PI * 2);
sinEnd = Math.sin(tempEnd);
cosEnd = Math.cos(tempEnd);
path.ellipse(centerX, centerY, startRho, startRho * distortion, 0, tempStart, tempEnd, false);
path.lineTo(centerX + cosEnd * startRho, centerY + sinEnd * startRho * distortion + thickness);
path.ellipse(centerX, centerY + thickness, startRho, startRho * distortion, 0, tempEnd, tempStart, true);
path.closePath();
}
if (endAngle > Math.PI * 3) {
tempStart = Math.PI;
tempEnd = endAngle;
sinEnd = Math.sin(tempEnd);
cosEnd = Math.cos(tempEnd);
path.ellipse(centerX, centerY, startRho, startRho * distortion, 0, tempStart, tempEnd, false);
path.lineTo(centerX + cosEnd * startRho, centerY + sinEnd * startRho * distortion + thickness);
path.ellipse(centerX, centerY + thickness, startRho, startRho * distortion, 0, tempEnd, tempStart, true);
path.closePath();
}
},
outerRenderer: function (path) {
var attr = this.attr,
margin = attr.margin,
centerX = attr.centerX,
centerY = attr.centerY,
distortion = attr.distortion,
baseRotation = attr.baseRotation,
startAngle = attr.startAngle + baseRotation ,
endAngle = attr.endAngle + baseRotation,
thickness = attr.thickness,
endRho = attr.endRho,
sinEnd, cosEnd,
tempStart, tempEnd, midAngle;
midAngle = (startAngle + endAngle) * 0.5;
centerX += Math.cos(midAngle) * margin;
centerY += Math.sin(midAngle) * margin * distortion;
if (startAngle >= Math.PI * 2) {
startAngle -= Math.PI * 2;
endAngle -= Math.PI * 2;
}
if (startAngle < Math.PI) {
tempStart = startAngle;
tempEnd = Math.min(endAngle, Math.PI);
sinEnd = Math.sin(tempEnd);
cosEnd = Math.cos(tempEnd);
path.ellipse(centerX, centerY, endRho, endRho * distortion, 0, tempStart, tempEnd, false);
path.lineTo(centerX + cosEnd * endRho, centerY + sinEnd * endRho * distortion + thickness);
path.ellipse(centerX, centerY + thickness, endRho, endRho * distortion, 0, tempEnd, tempStart, true);
path.closePath();
}
if (endAngle > Math.PI * 2) {
tempStart = Math.max(startAngle, Math.PI * 2);
tempEnd = endAngle;
sinEnd = Math.sin(tempEnd);
cosEnd = Math.cos(tempEnd);
path.ellipse(centerX, centerY, endRho, endRho * distortion, 0, tempStart, tempEnd, false);
path.lineTo(centerX + cosEnd * endRho, centerY + sinEnd * endRho * distortion + thickness);
path.ellipse(centerX, centerY + thickness, endRho, endRho * distortion, 0, tempEnd, tempStart, true);
path.closePath();
}
}
});

View file

@ -0,0 +1,180 @@
/**
* @class Ext.chart.series.sprite.PieSlice
*
* Pie slice sprite.
*/
Ext.define('Ext.chart.series.sprite.PieSlice', {
alias: 'sprite.pieslice',
mixins: {
markerHolder: 'Ext.chart.MarkerHolder'
},
extend: 'Ext.draw.sprite.Sector',
inheritableStatics: {
def: {
processors: {
/**
* @cfg {Boolean} [doCallout=true] 'true' if the pie series uses label callouts.
*/
doCallout: 'bool',
/**
* @cfg {Boolean} [rotateLabels=true] 'true' if the labels are rotated for easier reading.
*/
rotateLabels: 'bool',
/**
* @cfg {String} [label=''] Label associated with the Pie sprite.
*/
label: 'string',
/**
* @cfg {Number} [labelOverflowPadding=10] Padding around labels to determine overlap.
* Any negative number allows the labels to overlap.
*/
labelOverflowPadding: 'number',
renderer: 'default'
},
defaults: {
doCallout: true,
rotateLabels: true,
label: '',
labelOverflowPadding: 10,
renderer: null
}
}
},
config: {
/**
* @private
* @cfg {Object} rendererData The object that is passed to the renderer.
*
* For instance when the PieSlice sprite is used in a Gauge chart, the object
* contains the 'store' and 'field' properties, and the 'value' as well
* for that one PieSlice that is used to draw the needle of the Gauge.
*/
rendererData: null,
rendererIndex: 0
},
render: function (ctx, surface, clipRegion) {
var me = this,
attr = me.attr,
itemCfg = {},
changes;
if (attr.renderer) {
itemCfg = {
type: 'sector',
text: attr.text,
centerX: attr.centerX,
centerY: attr.centerY,
margin: attr.margin,
startAngle: Math.min(attr.startAngle, attr.endAngle),
endAngle: Math.max(attr.startAngle, attr.endAngle),
startRho: Math.min(attr.startRho, attr.endRho),
endRho: Math.max(attr.startRho, attr.endRho)
};
changes = attr.renderer.call(me, me, itemCfg, me.rendererData, me.rendererIndex);
Ext.apply(me.attr, changes);
}
// Draw the sector
me.callSuper(arguments);
// Draw the labels
if (attr.label && me.getBoundMarker('labels')) {
me.placeLabel();
}
},
placeLabel: function () {
var me = this,
attr = me.attr,
startAngle = Math.min(attr.startAngle, attr.endAngle),
endAngle = Math.max(attr.startAngle, attr.endAngle),
midAngle = (startAngle + endAngle) * 0.5,
margin = attr.margin,
centerX = attr.centerX,
centerY = attr.centerY,
startRho = Math.min(attr.startRho, attr.endRho) + margin,
endRho = Math.max(attr.startRho, attr.endRho) + margin,
midRho = (startRho + endRho) * 0.5,
surfaceMatrix = me.surfaceMatrix,
labelCfg = me.labelCfg || (me.labelCfg = {}),
labelTpl = me.getBoundMarker('labels')[0].getTemplate(),
labelBox, x, y, changes;
surfaceMatrix.appendMatrix(attr.matrix);
labelCfg.text = attr.label;
x = centerX + Math.cos(midAngle) * midRho;
y = centerY + Math.sin(midAngle) * midRho;
labelCfg.x = surfaceMatrix.x(x, y);
labelCfg.y = surfaceMatrix.y(x, y);
x = centerX + Math.cos(midAngle) * endRho;
y = centerY + Math.sin(midAngle) * endRho;
labelCfg.calloutStartX = surfaceMatrix.x(x, y);
labelCfg.calloutStartY = surfaceMatrix.y(x, y);
x = centerX + Math.cos(midAngle) * (endRho + 40);
y = centerY + Math.sin(midAngle) * (endRho + 40);
labelCfg.calloutPlaceX = surfaceMatrix.x(x, y);
labelCfg.calloutPlaceY = surfaceMatrix.y(x, y);
labelCfg.rotationRads = (attr.rotateLabels ? midAngle + Math.atan2(surfaceMatrix.y(1, 0) - surfaceMatrix.y(0, 0), surfaceMatrix.x(1, 0) - surfaceMatrix.x(0, 0)) : 0);
labelCfg.calloutColor = me.attr.fillStyle;
labelCfg.globalAlpha = attr.globalAlpha * attr.fillOpacity;
// If a slice is empty, don't display the label.
// This behavior can be overridden by a renderer.
labelCfg.hidden = (attr.startAngle == attr.endAngle);
if (attr.renderer) {
labelCfg.type = 'label';
changes = attr.renderer.call(me, me, labelCfg, me.rendererData, me.rendererIndex);
Ext.apply(labelCfg, changes);
}
me.putMarker('labels', labelCfg, me.attr.attributeId);
labelBox = me.getMarkerBBox('labels', me.attr.attributeId, true);
if (labelBox) {
if (attr.doCallout) {
if (labelTpl.attr.display === 'outside') {
me.putMarker('labels', {callout: 1}, me.attr.attributeId);
} else {
me.putMarker('labels', {callout: 1 - +me.sliceContainsLabel(attr, labelBox)}, me.attr.attributeId);
}
} else {
me.putMarker('labels', {globalAlpha: +me.sliceContainsLabel(attr, labelBox)}, me.attr.attributeId);
}
}
},
sliceContainsLabel: function (attr, bbox) {
var padding = attr.labelOverflowPadding,
middle = (attr.endRho + attr.startRho) / 2,
outer = middle + (bbox.width + padding) / 2,
inner = middle - (bbox.width + padding) / 2,
sliceAngle, l1, l2, l3;
if (padding < 0) {
return 1;
}
if (bbox.width + padding * 2 > (attr.endRho - attr.startRho)) {
return 0;
}
l1 = Math.sqrt(attr.endRho * attr.endRho - outer * outer);
l2 = Math.sqrt(attr.endRho * attr.endRho - inner * inner);
sliceAngle = Math.abs(attr.endAngle - attr.startAngle);
l3 = (sliceAngle > Math.PI/2 ? inner : Math.abs(Math.tan(sliceAngle / 2)) * inner);
if (bbox.height + padding * 2 > Math.min(l1, l2, l3) * 2) {
return 0;
}
return 1;
}
});

View file

@ -0,0 +1,150 @@
/**
* @class Ext.chart.series.sprite.Polar
* @extends Ext.draw.sprite.Sprite
*
* Polar sprite.
*/
Ext.define('Ext.chart.series.sprite.Polar', {
mixins: {
markerHolder: 'Ext.chart.MarkerHolder'
},
extend: 'Ext.draw.sprite.Sprite',
inheritableStatics: {
def: {
processors: {
/**
* @cfg {Number} [dataMinX=0] Data minimum on the x-axis.
*/
dataMinX: 'number',
/**
* @cfg {Number} [dataMaxX=1] Data maximum on the x-axis.
*/
dataMaxX: 'number',
/**
* @cfg {Number} [dataMinY=0] Data minimum on the y-axis.
*/
dataMinY: 'number',
/**
* @cfg {Number} [dataMaxY=2] Data maximum on the y-axis.
*/
dataMaxY: 'number',
/**
* @cfg {Array} Data range derived from all the series bound to the x-axis.
*/
rangeX: 'data',
/**
* @cfg {Array} Data range derived from all the series bound to the y-axis.
*/
rangeY: 'data',
/**
* @cfg {Object} [dataY=null] Data items on the y-axis.
*/
dataY: 'data',
/**
* @cfg {Object} [dataX=null] Data items on the x-axis.
*/
dataX: 'data',
/**
* @cfg {Number} [centerX=0] The central point of the series on the x-axis.
*/
centerX: 'number',
/**
* @cfg {Number} [centerY=0] The central point of the series on the y-axis.
*/
centerY: 'number',
/**
* @cfg {Number} [startAngle=0] The starting angle of the polar series.
*/
startAngle: "number",
/**
* @cfg {Number} [endAngle=Math.PI] The ending angle of the polar series.
*/
endAngle: "number",
/**
* @cfg {Number} [startRho=0] The starting radius of the polar series.
*/
startRho: "number",
/**
* @cfg {Number} [endRho=150] The ending radius of the polar series.
*/
endRho: "number",
/**
* @cfg {Number} [baseRotation=0] The starting rotation of the polar series.
*/
baseRotation: "number",
/**
* @cfg {Object} [labels=null] Labels used in the series.
*/
labels: 'default',
/**
* @cfg {Number} [labelOverflowPadding=10] Padding around labels to determine overlap.
*/
labelOverflowPadding: 'number'
},
defaults: {
dataY: null,
dataX: null,
dataMinX: 0,
dataMaxX: 1,
dataMinY: 0,
dataMaxY: 1,
centerX: 0,
centerY: 0,
startAngle: 0,
endAngle: Math.PI,
startRho: 0,
endRho: 150,
baseRotation: 0,
labels: null,
labelOverflowPadding: 10
},
dirtyTriggers: {
dataX: 'bbox',
dataY: 'bbox',
dataMinX: 'bbox',
dataMaxX: 'bbox',
dataMinY: 'bbox',
dataMaxY: 'bbox',
centerX: "bbox",
centerY: "bbox",
startAngle: "bbox",
endAngle: "bbox",
startRho: "bbox",
endRho: "bbox",
baseRotation: "bbox"
}
}
},
config: {
/**
* @private
* @cfg {Object} store The store that is passed to the renderer.
*/
store: null,
field: null
},
updatePlainBBox: function (plain) {
var attr = this.attr;
plain.x = attr.centerX - attr.endRho;
plain.y = attr.centerY + attr.endRho;
plain.width = attr.endRho * 2;
plain.height = attr.endRho * 2;
}
});

View file

@ -0,0 +1,44 @@
/**
* @class Ext.chart.series.sprite.Radar
* @extends Ext.chart.series.sprite.Polar
*
* Radar series sprite.
*/
Ext.define('Ext.chart.series.sprite.Radar', {
alias: 'sprite.radar',
extend: 'Ext.chart.series.sprite.Polar',
render: function (surface, ctx) {
var me = this,
attr = me.attr,
centerX = attr.centerX,
centerY = attr.centerY,
matrix = attr.matrix,
minX = attr.dataMinX,
maxX = attr.dataMaxX,
maxY = attr.dataMaxY,
dataX = attr.dataX,
dataY = attr.dataY,
rangeY = attr.rangeY,
endRho = attr.endRho,
startRho = attr.startRho,
baseRotation = attr.baseRotation,
i, length = dataX.length,
markerCfg = {},
surfaceMatrix = me.surfaceMatrix,
x, y, r, th;
ctx.beginPath();
for (i = 0; i < length; i++) {
th = (dataX[i] - minX) / (maxX - minX + 1) * 2 * Math.PI + baseRotation;
r = dataY[i] / (rangeY ? rangeY[1] : maxY) * (endRho - startRho) + startRho;
x = matrix.x(centerX + Math.cos(th) * r, centerY + Math.sin(th) * r);
y = matrix.y(centerX + Math.cos(th) * r, centerY + Math.sin(th) * r);
ctx.lineTo(x, y);
markerCfg.translationX = surfaceMatrix.x(x, y);
markerCfg.translationY = surfaceMatrix.y(x, y);
me.putMarker('markers', markerCfg, i, true);
}
ctx.closePath();
ctx.fillStroke(attr);
}
});

View file

@ -0,0 +1,43 @@
/**
* @class Ext.chart.series.sprite.Scatter
* @extends Ext.chart.series.sprite.Cartesian
*
* Scatter series sprite.
*/
Ext.define("Ext.chart.series.sprite.Scatter", {
alias: 'sprite.scatterSeries',
extend: 'Ext.chart.series.sprite.Cartesian',
renderClipped: function (surface, ctx, clip, clipRegion) {
if (this.cleanRedraw) {
return;
}
var attr = this.attr,
dataX = attr.dataX,
dataY = attr.dataY,
matrix = this.attr.matrix,
xx = matrix.getXX(),
yy = matrix.getYY(),
dx = matrix.getDX(),
dy = matrix.getDY(),
markerCfg = {},
left = clipRegion[0] - xx,
right = clipRegion[0] + clipRegion[2] + xx,
top = clipRegion[1] - yy,
bottom = clipRegion[1] + clipRegion[3] + yy,
x, y;
for (var i = 0; i < dataX.length; i++) {
x = dataX[i];
y = dataY[i];
x = x * xx + dx;
y = y * yy + dy;
if (left <= x && x <= right && top <= y && y <= bottom) {
if (attr.renderer) {
attr.renderer.call(this, this, markerCfg, {store:this.getStore()}, i);
}
markerCfg.translationX = x;
markerCfg.translationY = y;
this.putMarker("items", markerCfg, i, !attr.renderer);
}
}
}
});

Some files were not shown because too many files have changed in this diff Show more