correct num_labels if smaller than data range
[MojoFacets.git] / public / facet_graph.js
1 var data = {
2         x: {
3                 min: Number.MAX_VALUE,
4                 max: Number.MIN_VALUE,
5                 range: 0,
6                 inc: 0,
7                 inc_bar: 0,
8                 inc_px: 0,
9                 data: [],
10                 px: [],
11                 num_labels: 0,
12                 label_spacing: 30,
13         },
14         y: {
15                 min: Number.MAX_VALUE,
16                 max: Number.MIN_VALUE,
17                 range: 0,
18                 data: [],
19                 inc: 0,
20                 num_labels: 0,
21                 labels: [],
22                 num_labels: 0,
23                 label_spacing: 25,
24         },
25         width: 600,
26         height: 400,
27 };
28
29 var ul = $('ul#facet');
30
31 ul.find('li label').each( function(){
32         var v = parseFloat( $(this).text() );
33         if ( isNaN(v) ) v = 0;
34         if ( v > data.x.max ) data.x.max = v;
35         if ( v < data.x.min ) data.x.min = v;
36         data.x.data.push( v );
37 });
38
39 ul.find('li span.count').each( function(){
40         var v = parseFloat( $(this).text() ); // FIXME not numeric!
41         if ( isNaN(v) ) v = 0;
42         if ( v > data.y.max ) data.y.max = v;
43         if ( v < data.y.min ) data.y.min = v;
44         data.y.data.push( v );
45 });
46
47 data.y.min = 0; // XXX force to 0, because it's count
48
49 data.x.range = data.x.max - data.x.min;
50 data.y.range = data.y.max - data.y.min;
51
52
53
54 data.numeric = $('span#numeric').length;
55 data.x.inc_bar = data.numeric
56         ? Math.round( data.width / data.x.range )
57         : data.width / data.x.data.length
58         ;
59
60 var canvas = $('<canvas/>');
61
62 canvas.attr({
63         width: data.width,
64         height: data.height,
65 });
66
67 var canvasContain = $('<div class="chart"></div>')
68         .css({ width: data.width, height: data.height })
69         .append( canvas )
70         .insertBefore( ul );
71
72 var ctx = canvas[0].getContext('2d');
73 ctx.translate( 0, data.height ); // start at bottom left
74 ctx.lineWidth = 2;
75 ctx.strokeStyle = '#ff8800';
76 ctx.fillStyle = '#ffcc88';
77
78 ctx.moveTo( 0, 0 );
79 ctx.beginPath();
80
81 for( var i in data.x.data ) {
82         var x = data.x.data[i];
83         if ( data.numeric ) x = Math.ceil( ( x - data.x.min ) / data.x.range * data.width  );
84         var y = Math.ceil( ( data.y.data[i] - data.y.min ) / data.y.range * data.height );
85         if ( data.numeric ) {
86                 ctx.lineTo( x, -y );
87                 data.x.px.push( x );
88         } else {
89                 var x_px = i * data.x.inc_bar;
90                 console.debug( x_px, y );
91                 ctx.fillRect( x_px, 0, data.x.inc_bar, -y );
92                 ctx.strokeRect( x_px, 0, data.x.inc_bar, -y );
93         }
94 }
95
96 ctx.stroke();
97 ctx.closePath();
98
99 function draw_labels(class_name,axis,size,css_pos,last_css_pos) {
100
101         var labels = $('<ul class="'+class_name+'"></ul>')
102                 .css({ width: data.width, height: data.height, position: 'absolute' });
103
104         axis.num_labels = Math.round( size / axis.label_spacing );
105         if ( axis.num_labels > axis.range ) axis.num_labels = axis.range;
106         axis.inc = Math.ceil( axis.range / axis.num_labels );
107         axis.inc_px = Math.ceil( size / axis.num_labels );
108
109         var pos = 0;
110         for( var val = axis.min; val < axis.max ; val += axis.inc ) {
111                 $('<li style="'+css_pos+': '+pos+'px"><span class="line"></span><span class="label">' + val + '</span></li>')
112                         .appendTo(labels);
113                 pos += axis.inc_px;
114         }
115
116         $('<li style="'+last_css_pos+'"><span class="line"></span><span class="label">' + axis.max + '</span></li>')
117                 .appendTo(labels);
118
119         labels.appendTo(canvasContain);
120
121 }
122
123 if ( data.numeric )  draw_labels( 'labels-x', data.x, data.width, 'left', 'right:0px' );
124
125 draw_labels( 'labels-y', data.y, data.height, 'bottom', 'bottom:'+data.height+'px' );
126
127
128 console.debug( 'data', data );
129