5 Handles laying out data on to a virtual canvas square canvas between 0.0
6 and 1.0. If you want to add new chart/plot types such as point plots,
7 you need to add them here.
11 Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
12 For use under the BSD license. <http://www.liquidx.net/plotkit>
17 if (typeof(PlotKit
.Base
) == 'undefined')
23 throw "PlotKit.Layout depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.Base"
26 // --------------------------------------------------------------------
27 // Start of Layout definition
28 // --------------------------------------------------------------------
30 if (typeof(PlotKit
.Layout
) == 'undefined') {
34 PlotKit
.Layout
.NAME
= "PlotKit.Layout";
35 PlotKit
.Layout
.VERSION
= PlotKit
.VERSION
;
37 PlotKit
.Layout
.__repr__
= function() {
38 return "[" + this.NAME
+ " " + this.VERSION
+ "]";
41 PlotKit
.Layout
.toString
= function() {
42 return this.__repr__();
45 // --------------------------------------------------------------------
46 // Start of Layout definition
47 // --------------------------------------------------------------------
49 PlotKit
.Layout
= function(style
, options
) {
52 "xOriginIsZero": true,
53 "yOriginIsZero": true,
54 "xAxis": null, // [xmin, xmax]
55 "yAxis": null, // [ymin, ymax]
56 "xTicks": null, // [{label: "somelabel", v: value}, ..] (label opt.)
57 "yTicks": null, // [{label: "somelabel", v: value}, ..] (label opt.)
60 // valid external options : TODO: input verification
62 MochiKit
.Base
.update(this.options
, options
? options
: {});
66 this.xscale
= null; // val -> pos factor (eg, xval * xscale = xpos)
72 this.points
= new Array(); // array of points to plot for line plots
74 this.xticks
= new Array();
75 this.yticks
= new Array();
78 this.datasets
= new Array();
84 // --------------------------------------------------------------------
85 // Dataset Manipulation
86 // --------------------------------------------------------------------
89 PlotKit
.Layout
.prototype.addDataset
= function(setname
, set_xy
) {
90 this.datasets
[setname
] = set_xy
;
93 // --------------------------------------------------------------------
94 // Evaluates the layout for the current data and style.
95 // --------------------------------------------------------------------
97 PlotKit
.Layout
.prototype.evaluate
= function() {
98 this._evaluateLimits();
99 this._evaluateLineCharts();
100 this._evaluateLineTicks();
104 // --------------------------------------------------------------------
105 // START Internal Functions
106 // --------------------------------------------------------------------
108 PlotKit
.Layout
.prototype._evaluateLimits
= function() {
109 // take all values from all datasets and find max and min
110 var map
= PlotKit
.Base
.map
;
111 var items
= PlotKit
.Base
.items
;
112 var itemgetter
= MochiKit
.Base
.itemgetter
;
113 var collapse
= PlotKit
.Base
.collapse
;
114 var listMin
= MochiKit
.Base
.listMin
;
115 var listMax
= MochiKit
.Base
.listMax
;
116 var isNil
= MochiKit
.Base
.isUndefinedOrNull
;
118 var all
= collapse(map(itemgetter(1), items(this.datasets
)));
119 this.minxval
= listMin(map(parseFloat
, map(itemgetter(0), all
)));
120 this.maxxval
= listMax(map(parseFloat
, map(itemgetter(0), all
)));
121 this.xrange
= this.maxxval
- this.minxval
;
122 this.xscale
= (this.xrange
!= 0 ? 1/this.xrange
: 1.0);
124 this.minyval
= this.options
.yAxis
[0];
125 this.maxyval
= this.options
.yAxis
[1];
126 this.yrange
= this.maxyval
- this.minyval
;
127 this.yscale
= (this.yrange
!= 0 ? 1/this.yrange
: 1.0);
130 // Create the line charts
131 PlotKit
.Layout
.prototype._evaluateLineCharts
= function() {
132 var items
= PlotKit
.Base
.items
;
134 var setCount
= items(this.datasets
).length
;
137 this.points
= new Array();
139 for (var setName
in this.datasets
) {
140 var dataset
= this.datasets
[setName
];
141 if (PlotKit
.Base
.isFuncLike(dataset
)) continue;
142 dataset
.sort(function(a
, b
) { return compare(parseFloat(a
[0]), parseFloat(b
[0])); });
143 for (var j
= 0; j
< dataset
.length
; j
++) {
144 var item
= dataset
[j
];
146 x
: ((parseFloat(item
[0]) - this.minxval
) * this.xscale
),
147 y
: 1.0 - ((parseFloat(item
[1]) - this.minyval
) * this.yscale
),
148 xval
: parseFloat(item
[0]),
149 yval
: parseFloat(item
[1]),
153 // limit the x, y values so they do not overdraw
154 if (point
.y
<= 0.0) {
157 if (point
.y
>= 1.0) {
160 if ((point
.x
>= 0.0) && (point
.x
<= 1.0)) {
161 this.points
.push(point
);
169 PlotKit
.Layout
.prototype._evaluateLineTicksForXAxis
= function() {
170 var isNil
= MochiKit
.Base
.isUndefinedOrNull
;
172 this.xticks
= new Array();
173 var makeTicks
= function(tick
) {
174 var label
= tick
.label
;
176 label
= tick
.v
.toString();
177 var pos
= this.xscale
* (tick
.v
- this.minxval
);
178 if ((pos
>= 0.0) && (pos
<= 1.0)) {
179 this.xticks
.push([pos
, label
]);
182 MochiKit
.Iter
.forEach(this.options
.xTicks
, bind(makeTicks
, this));
185 PlotKit
.Layout
.prototype._evaluateLineTicksForYAxis
= function() {
186 var isNil
= MochiKit
.Base
.isUndefinedOrNull
;
188 this.yticks
= new Array();
189 var makeTicks
= function(tick
) {
190 var label
= tick
.label
;
192 label
= tick
.v
.toString();
193 var pos
= 1.0 - (this.yscale
* (tick
.v
- this.minyval
));
194 if ((pos
>= 0.0) && (pos
<= 1.0)) {
195 this.yticks
.push([pos
, label
]);
198 MochiKit
.Iter
.forEach(this.options
.yTicks
, bind(makeTicks
, this));
201 PlotKit
.Layout
.prototype._evaluateLineTicks
= function() {
202 this._evaluateLineTicksForXAxis();
203 this._evaluateLineTicksForYAxis();
207 // --------------------------------------------------------------------
208 // END Internal Functions
209 // --------------------------------------------------------------------
212 // Namespace Iniitialisation
214 PlotKit
.LayoutModule
= {};
215 PlotKit
.LayoutModule
.Layout
= PlotKit
.Layout
;
217 PlotKit
.LayoutModule
.EXPORT
= [
221 PlotKit
.LayoutModule
.EXPORT_OK
= [];
223 PlotKit
.LayoutModule
.__new__
= function() {
224 var m
= MochiKit
.Base
;
226 m
.nameFunctions(this);
229 ":common": this.EXPORT
,
230 ":all": m
.concat(this.EXPORT
, this.EXPORT_OK
)
234 PlotKit
.LayoutModule
.__new__();
235 MochiKit
.Base
._exportSymbols(this, PlotKit
.LayoutModule
);