summaryrefslogtreecommitdiff
path: root/js/dojo/dojox/charting/BidiSupport.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/dojo/dojox/charting/BidiSupport.js')
-rw-r--r--js/dojo/dojox/charting/BidiSupport.js265
1 files changed, 265 insertions, 0 deletions
diff --git a/js/dojo/dojox/charting/BidiSupport.js b/js/dojo/dojox/charting/BidiSupport.js
new file mode 100644
index 0000000..cc0dcec
--- /dev/null
+++ b/js/dojo/dojox/charting/BidiSupport.js
@@ -0,0 +1,265 @@
+//>>built
+define("dojox/charting/BidiSupport", ["dojo/_base/lang", "dojo/_base/html", "dojo/_base/array", "dojo/_base/sniff",
+ "dojo/dom","dojo/dom-construct",
+ "dojox/gfx", "dojox/gfx/_gfxBidiSupport", "./Chart", "./axis2d/common", "dojox/string/BidiEngine", "dojox/lang/functional"],
+ function(lang, html, arr, has, dom, domConstruct, g, gBidi, Chart, da, BidiEngine, df){
+
+ var bidiEngine = new BidiEngine();
+
+ lang.extend(Chart, {
+ // summary:
+ // Add support for bidi scripts.
+ // description:
+ // Bidi stands for support for languages with a bidirectional script.
+ // There's a special need for displaying BIDI text in rtl direction
+ // in ltr GUI, sometimes needed auto support.
+ // dojox.charting does not support control over base text direction provided in Dojo.
+
+ // textDir: String
+ // Bi-directional support, the main variable which is responsible for the direction of the text.
+ // The text direction can be different than the GUI direction by using this parameter.
+ // Allowed values:
+ // 1. "ltr"
+ // 2. "rtl"
+ // 3. "auto" - contextual the direction of a text defined by first strong letter.
+ // By default is as the page direction.
+ textDir:"",
+
+ getTextDir: function(/*String*/text){
+ // summary:
+ // Return direction of the text.
+ // description:
+ // If textDir is ltr or rtl returns the value.
+ // If it's auto, calls to another function that responsible
+ // for checking the value, and defining the direction.
+ // text:
+ // Used in case textDir is "auto", this case the direction is according to the first
+ // strong (directionally - which direction is strong defined) letter.
+ // tags:
+ // protected.
+ var textDir = this.textDir == "auto" ? bidiEngine.checkContextual(text) : this.textDir;
+ // providing default value
+ if(!textDir){
+ textDir = html.style(this.node,"direction");
+ }
+ return textDir;
+ },
+
+ postscript: function(node,args){
+ // summary:
+ // Kicks off chart instantiation.
+ // description:
+ // Used for setting the textDir of the chart.
+ // tags:
+ // private
+
+ // validate textDir
+ var textDir = args ? (args["textDir"] ? validateTextDir(args["textDir"]) : "") : "";
+ // if textDir wasn't defined or was defined wrong, apply default value
+ textDir = textDir ? textDir : html.style(this.node,"direction");
+ this.textDir = textDir;
+
+ this.surface.textDir = textDir;
+
+ // two data structures, used for storing data for further enablement to change
+ // textDir dynamically
+ this.htmlElementsRegistry = [];
+ this.truncatedLabelsRegistry = [];
+ },
+
+ setTextDir: function(/*String*/ newTextDir, obj){
+ // summary:
+ // Setter for the textDir attribute.
+ // description:
+ // Allows dynamically set the textDir, goes over all the text-children and
+ // updates their base text direction.
+ // tags:
+ // public
+
+ if(newTextDir == this.textDir){
+ return this;
+ }
+ if(validateTextDir(newTextDir) != null){
+ this.textDir = newTextDir;
+
+ // set automatically all the gfx objects that were created by this surface
+ // (groups, text objects)
+ this.surface.setTextDir(newTextDir);
+
+ // truncated labels that were created with gfx creator need to recalculate dir
+ // for case like: "111111A" (A stands for bidi character) and the truncation
+ // is "111..." If the textDir is auto, the display should be: "...111" but in gfx
+ // case we will get "111...". Because this.surface.setTextDir will calculate the dir of truncated
+ // label, which value is "111..." but th real is "111111A".
+ // each time we created a gfx truncated label we stored it in the truncatedLabelsRegistry, so update now
+ // the registry.
+ if(this.truncatedLabelsRegistry && newTextDir == "auto"){
+ arr.forEach(this.truncatedLabelsRegistry, function(elem){
+ var tDir = this.getTextDir(elem["label"]);
+ if(elem["element"].textDir != tDir){
+ elem["element"].setShape({textDir: tDir});
+ }
+ }, this);
+ }
+
+ // re-render axes with html labels. for recalculation of the labels
+ // positions etc.
+ // create array of keys for all the axis in chart
+ var axesKeyArr = df.keys(this.axes);
+ if(axesKeyArr.length > 0){
+ // iterate over the axes, and for each that have html labels render it.
+ arr.forEach(axesKeyArr, function(key, index, arr){
+ // get the axis
+ var axis = this.axes[key];
+ // if the axis has html labels
+ if(axis.htmlElements[0]){
+ axis.dirty = true;
+ axis.render(this.dim, this.offsets);
+ }
+ },this);
+
+ // recreate title
+ if(this.title){
+ var forceHtmlLabels = (g.renderer == "canvas"),
+ labelType = forceHtmlLabels || !has("ie") && !has("opera") ? "html" : "gfx",
+ tsize = g.normalizedLength(g.splitFontString(this.titleFont).size);
+ // remove the title
+ domConstruct.destroy(this.chartTitle);
+ this.chartTitle =null;
+ // create the new title
+ this.chartTitle = da.createText[labelType](
+ this,
+ this.surface,
+ this.dim.width/2,
+ this.titlePos=="top" ? tsize + this.margins.t : this.dim.height - this.margins.b,
+ "middle",
+ this.title,
+ this.titleFont,
+ this.titleFontColor
+ );
+ }
+ }else{
+ // case of pies, spiders etc.
+ arr.forEach(this.htmlElementsRegistry, function(elem, index, arr){
+ var tDir = newTextDir == "auto" ? this.getTextDir(elem[4]) : newTextDir;
+ if(elem[0].children[0] && elem[0].children[0].dir != tDir){
+ dom.destroy(elem[0].children[0]);
+ elem[0].children[0] = da.createText["html"]
+ (this, this.surface, elem[1], elem[2], elem[3], elem[4], elem[5], elem[6]).children[0];
+ }
+ },this);
+ }
+ }
+ },
+
+ truncateBidi: function(elem, label, labelType){
+ // summary:
+ // Enables bidi support for truncated labels.
+ // description:
+ // Can be two types of labels: html or gfx.
+ // gfx labels:
+ // Need to be stored in registry to be used when the textDir will be set dynamically.
+ // Additional work on truncated labels is needed for case as 111111A (A stands for "bidi" character rtl directioned).
+ // let say in this case the truncation is "111..." If the textDir is auto, the display should be: "...111" but in gfx
+ // case we will get "111...". Because this.surface.setTextDir will calculate the dir of truncated
+ // label, which value is "111..." but th real is "111111A".
+ // each time we created a gfx truncated label we store it in the truncatedLabelsRegistry.
+ // html labels:
+ // no need for repository (stored in another place). Here we only need to update the current dir according to textDir.
+ // tags:
+ // private
+
+ if(labelType == "gfx"){
+ // store truncated gfx labels in the data structure.
+ this.truncatedLabelsRegistry.push({element: elem, label: label});
+ if(this.textDir == "auto"){
+ elem.setShape({textDir: this.getTextDir(label)});
+ }
+ }
+ if(labelType == "html" && this.textDir == "auto"){
+ elem.children[0].dir = this.getTextDir(label);
+ }
+ }
+ });
+
+ var extendMethod = function(obj, method, bundleByPrototype, before, after){
+ // Some helper function. Used for extending method of obj.
+ // obj: Object
+ // The obj we overriding it's method.
+ // method: String
+ // The method that is extended, the original method is called before or after
+ // functions that passed to extendMethod.
+ // bundleByPrototype: boolean
+ // There's two methods to extend, using prototype or not.
+ // before: function
+ // If defined this function will be executed before the original method.
+ // after: function
+ // If defined this function will be executed after the original method.
+ if(bundleByPrototype){
+ var old = obj.prototype[method];
+ obj.prototype[method] =
+ function(){
+ var rBefore;
+ if (before){
+ rBefore = before.apply(this, arguments);
+ }
+ var r = old.apply(this, rBefore);
+ if (after){
+ r = after.call(this, r, arguments);
+ }
+ return r;
+ };
+ }else{
+ var old = lang.clone(obj[method]);
+ obj[method] =
+ function(){
+ var rBefore;
+ if (before){
+ rBefore = before.apply(this, arguments);
+ }
+ var r = old.apply(this, arguments);
+ if (after){
+ after(r, arguments);
+ }
+ return r;
+ };
+ }
+ };
+
+ var labelPreprocess = function(elem, chart, label, truncatedLabel, font, elemType){
+ // aditional preprocessing of the labels, needed for rtl base text direction in LTR
+ // GUI, or for ltr base text direction for RTL GUI.
+
+ var isChartDirectionRtl = (html.style(chart.node,"direction") == "rtl");
+ var isBaseTextDirRtl = (chart.getTextDir(label) == "rtl");
+
+ if(isBaseTextDirRtl && !isChartDirectionRtl){
+ label = "<span dir='rtl'>" + label +"</span>";
+ }
+ if(!isBaseTextDirRtl && isChartDirectionRtl){
+ label = "<span dir='ltr'>" + label +"</span>";
+ }
+
+ return arguments;
+ };
+
+ // connect labelPreprocess to run before labelTooltip.
+ // patch it only is available
+ if(dojox.charting.axis2d && dojox.charting.axis2d.Default){
+ extendMethod(dojox.charting.axis2d.Default,"labelTooltip",true, labelPreprocess, null);
+ //extendMethod(dijit,"showTooltip",false, labelPreprocess, null);
+ }
+
+ function htmlCreateText(r, agumentsArr){
+ // function to register HTML elements that created by html.createText, this array
+ // needed for allowing to change textDir dynamically.
+ agumentsArr[0].htmlElementsRegistry.push([r, agumentsArr[2], agumentsArr[3], agumentsArr[4], agumentsArr[5], agumentsArr[6], agumentsArr[7]]);
+ }
+
+ extendMethod(da.createText,"html", false, null, htmlCreateText);
+
+ function validateTextDir(textDir){
+ return /^(ltr|rtl|auto)$/.test(textDir) ? textDir : null;
+ }
+
+});