123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- define("dojox/charting/axis2d/Invisible", ["dojo/_base/lang", "dojo/_base/declare", "./Base", "../scaler/linear",
- "dojox/gfx", "dojox/lang/utils", "dojox/lang/functional", "dojo/string"],
- function(lang, declare, Base, lin, g, du, df, dstring){
- /*=====
- var Base = dojox.charting.axis2d.Base;
- =====*/
- var merge = du.merge,
- labelGap = 4, // in pixels
- centerAnchorLimit = 45; // in degrees
- return declare("dojox.charting.axis2d.Invisible", Base, {
- // summary:
- // The default axis object used in dojox.charting. See dojox.charting.Chart.addAxis for details.
- //
- // defaultParams: Object
- // The default parameters used to define any axis.
- // optionalParams: Object
- // Any optional parameters needed to define an axis.
- /*
- // TODO: the documentation tools need these to be pre-defined in order to pick them up
- // correctly, but the code here is partially predicated on whether or not the properties
- // actually exist. For now, we will leave these undocumented but in the code for later. -- TRT
- // opt: Object
- // The actual options used to define this axis, created at initialization.
- // scalar: Object
- // The calculated helper object to tell charts how to draw an axis and any data.
- // ticks: Object
- // The calculated tick object that helps a chart draw the scaling on an axis.
- // dirty: Boolean
- // The state of the axis (whether it needs to be redrawn or not)
- // scale: Number
- // The current scale of the axis.
- // offset: Number
- // The current offset of the axis.
- opt: null,
- scalar: null,
- ticks: null,
- dirty: true,
- scale: 1,
- offset: 0,
- */
- defaultParams: {
- vertical: false, // true for vertical axis
- fixUpper: "none", // align the upper on ticks: "major", "minor", "micro", "none"
- fixLower: "none", // align the lower on ticks: "major", "minor", "micro", "none"
- natural: false, // all tick marks should be made on natural numbers
- leftBottom: true, // position of the axis, used with "vertical"
- includeZero: false, // 0 should be included
- fixed: true, // all labels are fixed numbers
- majorLabels: true, // draw major labels
- minorTicks: true, // draw minor ticks
- minorLabels: true, // draw minor labels
- microTicks: false, // draw micro ticks
- rotation: 0 // label rotation angle in degrees
- },
- optionalParams: {
- min: 0, // minimal value on this axis
- max: 1, // maximal value on this axis
- from: 0, // visible from this value
- to: 1, // visible to this value
- majorTickStep: 4, // major tick step
- minorTickStep: 2, // minor tick step
- microTickStep: 1, // micro tick step
- labels: [], // array of labels for major ticks
- // with corresponding numeric values
- // ordered by values
- labelFunc: null, // function to compute label values
- maxLabelSize: 0, // size in px. For use with labelFunc
- maxLabelCharCount: 0, // size in word count.
- trailingSymbol: null
- // TODO: add support for minRange!
- // minRange: 1, // smallest distance from min allowed on the axis
- },
- constructor: function(chart, kwArgs){
- // summary:
- // The constructor for an axis.
- // chart: dojox.charting.Chart
- // The chart the axis belongs to.
- // kwArgs: dojox.charting.axis2d.__AxisCtorArgs?
- // Any optional keyword arguments to be used to define this axis.
- this.opt = lang.clone(this.defaultParams);
- du.updateWithObject(this.opt, kwArgs);
- du.updateWithPattern(this.opt, kwArgs, this.optionalParams);
- },
- dependOnData: function(){
- // summary:
- // Find out whether or not the axis options depend on the data in the axis.
- return !("min" in this.opt) || !("max" in this.opt); // Boolean
- },
- clear: function(){
- // summary:
- // Clear out all calculated properties on this axis;
- // returns: dojox.charting.axis2d.Default
- // The reference to the axis for functional chaining.
- delete this.scaler;
- delete this.ticks;
- this.dirty = true;
- return this; // dojox.charting.axis2d.Default
- },
- initialized: function(){
- // summary:
- // Finds out if this axis has been initialized or not.
- // returns: Boolean
- // Whether a scaler has been calculated and if the axis is not dirty.
- return "scaler" in this && !(this.dirty && this.dependOnData());
- },
- setWindow: function(scale, offset){
- // summary:
- // Set the drawing "window" for the axis.
- // scale: Number
- // The new scale for the axis.
- // offset: Number
- // The new offset for the axis.
- // returns: dojox.charting.axis2d.Default
- // The reference to the axis for functional chaining.
- this.scale = scale;
- this.offset = offset;
- return this.clear(); // dojox.charting.axis2d.Default
- },
- getWindowScale: function(){
- // summary:
- // Get the current windowing scale of the axis.
- return "scale" in this ? this.scale : 1; // Number
- },
- getWindowOffset: function(){
- // summary:
- // Get the current windowing offset for the axis.
- return "offset" in this ? this.offset : 0; // Number
- },
- _groupLabelWidth: function(labels, font, wcLimit){
- if(!labels.length){
- return 0;
- }
- if(lang.isObject(labels[0])){
- labels = df.map(labels, function(label){ return label.text; });
- }
- if (wcLimit) {
- labels = df.map(labels, function(label){
- return lang.trim(label).length == 0 ? "" : label.substring(0, wcLimit) + this.trailingSymbol;
- }, this);
- }
- var s = labels.join("<br>");
- return g._base._getTextBox(s, {font: font}).w || 0;
- },
- calculate: function(min, max, span, labels){
- // summary:
- // Perform all calculations needed to render this axis.
- // min: Number
- // The smallest value represented on this axis.
- // max: Number
- // The largest value represented on this axis.
- // span: Number
- // The span in pixels over which axis calculations are made.
- // labels: String[]
- // Optional list of labels.
- // returns: dojox.charting.axis2d.Default
- // The reference to the axis for functional chaining.
- if(this.initialized()){
- return this;
- }
- var o = this.opt;
- this.labels = "labels" in o ? o.labels : labels;
- this.scaler = lin.buildScaler(min, max, span, o);
- var tsb = this.scaler.bounds;
- if("scale" in this){
- // calculate new range
- o.from = tsb.lower + this.offset;
- o.to = (tsb.upper - tsb.lower) / this.scale + o.from;
- // make sure that bounds are correct
- if( !isFinite(o.from) ||
- isNaN(o.from) ||
- !isFinite(o.to) ||
- isNaN(o.to) ||
- o.to - o.from >= tsb.upper - tsb.lower
- ){
- // any error --- remove from/to bounds
- delete o.from;
- delete o.to;
- delete this.scale;
- delete this.offset;
- }else{
- // shift the window, if we are out of bounds
- if(o.from < tsb.lower){
- o.to += tsb.lower - o.from;
- o.from = tsb.lower;
- }else if(o.to > tsb.upper){
- o.from += tsb.upper - o.to;
- o.to = tsb.upper;
- }
- // update the offset
- this.offset = o.from - tsb.lower;
- }
- // re-calculate the scaler
- this.scaler = lin.buildScaler(min, max, span, o);
- tsb = this.scaler.bounds;
- // cleanup
- if(this.scale == 1 && this.offset == 0){
- delete this.scale;
- delete this.offset;
- }
- }
- var ta = this.chart.theme.axis, labelWidth = 0, rotation = o.rotation % 360,
- // TODO: we use one font --- of major tick, we need to use major and minor fonts
- taFont = o.font || (ta.majorTick && ta.majorTick.font) || (ta.tick && ta.tick.font),
- size = taFont ? g.normalizedLength(g.splitFontString(taFont).size) : 0,
- cosr = Math.abs(Math.cos(rotation * Math.PI / 180)),
- sinr = Math.abs(Math.sin(rotation * Math.PI / 180));
- if(rotation < 0){
- rotation += 360;
- }
- if(size){
- if(this.vertical ? rotation != 0 && rotation != 180 : rotation != 90 && rotation != 270){
- // we need width of all labels
- if(this.labels){
- labelWidth = this._groupLabelWidth(this.labels, taFont, o.maxLabelCharCount);
- }else{
- var labelLength = Math.ceil(
- Math.log(
- Math.max(
- Math.abs(tsb.from),
- Math.abs(tsb.to)
- )
- ) / Math.LN10
- ),
- t = [];
- if(tsb.from < 0 || tsb.to < 0){
- t.push("-");
- }
- t.push(dstring.rep("9", labelLength));
- var precision = Math.floor(
- Math.log( tsb.to - tsb.from ) / Math.LN10
- );
- if(precision > 0){
- t.push(".");
- t.push(dstring.rep("9", precision));
- }
- labelWidth = g._base._getTextBox(
- t.join(""),
- { font: taFont }
- ).w;
- }
- labelWidth = o.maxLabelSize ? Math.min(o.maxLabelSize, labelWidth) : labelWidth;
- }else{
- labelWidth = size;
- }
- switch(rotation){
- case 0:
- case 90:
- case 180:
- case 270:
- // trivial cases: use labelWidth
- break;
- default:
- // rotated labels
- var gap1 = Math.sqrt(labelWidth * labelWidth + size * size), // short labels
- gap2 = this.vertical ? size * cosr + labelWidth * sinr : labelWidth * cosr + size * sinr; // slanted labels
- labelWidth = Math.min(gap1, gap2);
- break;
- }
- }
- this.scaler.minMinorStep = labelWidth + labelGap;
- this.ticks = lin.buildTicks(this.scaler, o);
- return this; // dojox.charting.axis2d.Default
- },
- getScaler: function(){
- // summary:
- // Get the pre-calculated scaler object.
- return this.scaler; // Object
- },
- getTicks: function(){
- // summary:
- // Get the pre-calculated ticks object.
- return this.ticks; // Object
- }
- });
- });
|