1+ /*
2+ * SVG Area Heatmap Plugin
3+ *
4+ * Copyright (c) 2014, Patrick Wied (http://www.patrick-wied.at)
5+ * Dual-licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
6+ * and the Beerware (http://en.wikipedia.org/wiki/Beerware) license.
7+ */
8+ ( function ( ) {
9+ 'use strict' ;
10+
11+ var SvgAreaHeatmap = ( function SvgAreaHeatmapClosure ( ) {
12+
13+ var _getColorPalette = function ( config ) {
14+ var gradientConfig = config . gradient || config . defaultGradient ;
15+ var paletteCanvas = document . createElement ( 'canvas' ) ;
16+ var paletteCtx = paletteCanvas . getContext ( '2d' ) ;
17+
18+ paletteCanvas . width = 256 ;
19+ paletteCanvas . height = 1 ;
20+
21+ var gradient = paletteCtx . createLinearGradient ( 0 , 0 , 256 , 1 ) ;
22+ for ( var key in gradientConfig ) {
23+ gradient . addColorStop ( key , gradientConfig [ key ] ) ;
24+ }
25+
26+ paletteCtx . fillStyle = gradient ;
27+ paletteCtx . fillRect ( 0 , 0 , 256 , 1 ) ;
28+
29+ return paletteCtx . getImageData ( 0 , 0 , 256 , 1 ) . data ;
30+ } ;
31+
32+
33+ function SvgAreaHeatmapStore ( config ) {
34+ this . _coordinator = { } ;
35+ this . _data = { } ;
36+ this . _max = 1 ;
37+ this . _min = 0 ;
38+ } ;
39+
40+ SvgAreaHeatmapStore . prototype = {
41+ setCoordinator : function ( coordinator ) {
42+ this . _coordinator = coordinator ;
43+ } ,
44+ setData : function ( data ) {
45+ this . _max = data . max || this . _max ;
46+ this . _min = data . min || this . _min ;
47+ this . _data = { } ;
48+
49+ var d = data . data ;
50+ var dataLen = d . length ;
51+
52+ while ( dataLen -- ) {
53+ this . _organiseData ( d [ dataLen ] ) ;
54+ }
55+
56+ this . _coordinator . emit ( 'renderall' , this . _getInternalData ( ) ) ;
57+ } ,
58+ addData : function ( data ) {
59+ var organisedEntry = this . _organiseData ( data ) ;
60+ if ( organisedEntry ) {
61+ this . _coordinator . emit ( 'renderpartial' , {
62+ min : this . _min ,
63+ max : this . _max ,
64+ data : [ organisedEntry ]
65+ } ) ;
66+ }
67+ } ,
68+ updateData : function ( data ) {
69+
70+ } ,
71+ removeData : function ( data ) {
72+
73+ } ,
74+ getData : function ( ) {
75+
76+ } ,
77+ setDataMax : function ( max ) {
78+ this . _max = max ;
79+ //this._onExtremaChange();
80+ this . _coordinator . emit ( 'renderall' , this . _getInternalData ( ) ) ;
81+ return this ;
82+ } ,
83+ setDataMin : function ( min ) {
84+ this . _min = min ;
85+ //this._onExtremaChange();
86+ this . _coordinator . emit ( 'renderall' , this . _getInternalData ( ) ) ;
87+ return this ;
88+ } ,
89+ _organiseData : function ( point ) {
90+ if ( this . _data [ point . id ] ) {
91+ this . _data [ point . id ] += point . value ;
92+
93+ } else {
94+ this . _data [ point . id ] = point . value ;
95+ }
96+
97+ if ( this . _data [ point . id ] > this . _max ) {
98+ this . setDataMax ( this . _data [ point . id ] ) ;
99+ }
100+ if ( this . _data [ point . id ] < this . _min ) {
101+ this . setDataMin ( this . _data [ point . id ] ) ;
102+ }
103+ return point ;
104+ } ,
105+ _getInternalData : function ( ) {
106+ return {
107+ max : this . _max ,
108+ min : this . _min ,
109+ data : this . _data ,
110+ } ;
111+ }
112+ } ;
113+
114+
115+ function SvgAreaHeatmapRenderer ( config ) {
116+ // initialization
117+ var container = config . container ;
118+ var svgUrl = config . svgUrl ;
119+ this . renderQueue = [ ] ;
120+
121+
122+ var svgObj = document . createElement ( 'object' ) ;
123+ svgObj . type = 'image/svg+xml' ;
124+ svgObj . id = 'svgHeatmap' ;
125+ svgObj . data = svgUrl ;
126+
127+ var that = this ;
128+
129+ svgObj . onload = function ( ) {
130+ that . svgDoc = this . getSVGDocument ( ) ;
131+ that . $ = function ( selector ) {
132+ return that . svgDoc . querySelector ( selector ) ;
133+ } ;
134+
135+ that . _processQueue ( ) ;
136+ }
137+
138+ container . appendChild ( svgObj ) ;
139+
140+ this . _palette = _getColorPalette ( config ) ;
141+
142+ } ;
143+
144+ SvgAreaHeatmapRenderer . prototype = {
145+ renderPartial : function ( data ) {
146+ var point = data . data [ 0 ] ;
147+ this . max = data . max ;
148+ this . min = data . min ;
149+ this . _colorize ( point . id , point . value ) ;
150+ } ,
151+ renderAll : function ( data ) {
152+ var points = data . data ;
153+ this . max = data . max ;
154+ this . min = data . min ;
155+ for ( var key in points ) {
156+ this . _colorize ( key , points [ key ] ) ;
157+ }
158+ } ,
159+ _colorize : function ( key , value ) {
160+
161+ if ( ! this . svgDoc ) {
162+ this . renderQueue . push ( [ key , value ] ) ;
163+ } else {
164+ var node = this . $ ( '#' + key ) ;
165+ var color ;
166+ var max = this . max ;
167+ var min = this . min ;
168+ var colorIndex = ( ( ( value / ( Math . abs ( max - min ) ) * 255 ) >> 0 ) * 4 ) ;
169+
170+ var r = this . _palette [ colorIndex ] ;
171+ var g = this . _palette [ colorIndex + 1 ] ;
172+ var b = this . _palette [ colorIndex + 2 ] ;
173+
174+ node . style . fill = [ 'rgb(' , r , ',' , g , ',' , b , ')' ] . join ( '' ) ;
175+ }
176+ } ,
177+ _processQueue : function ( ) {
178+ var renderElement = this . renderQueue . pop ( ) ;
179+ if ( ! renderElement ) {
180+ return ;
181+ }
182+ this . _colorize . apply ( this , renderElement ) ;
183+ this . _processQueue ( ) ;
184+ }
185+ } ;
186+
187+ return {
188+ store : SvgAreaHeatmapStore ,
189+ renderer : SvgAreaHeatmapRenderer
190+ }
191+ } ( ) ) ;
192+
193+ h337 . register ( 'SvgAreaHeatmap' , SvgAreaHeatmap ) ;
194+
195+ } ( ) ) ;
0 commit comments