@@ -7,23 +7,30 @@ import { assignPalettes } from './palettes';
77
88const DEFAULT_OPTIONS = {
99 rowHeight : 24 ,
10- rowAlternatingBackground : '#eee' ,
1110 padding : 5 ,
1211 geomPadding : 1.5 ,
13- geomStroke : '#555' ,
1412 columnRotate : 30 ,
1513 midpoint : 0.8 ,
1614 legendFontSize : 12 ,
1715 legendTicks : [ 0 , 0.2 , 0.4 , 0.6 , 0.8 , 1 ] ,
1816 labelGroupsAbc : false ,
19- colorByRank : false
17+ colorByRank : false ,
18+ theme : {
19+ oddRowBackground : 'white' ,
20+ evenRowBackground : '#eee' ,
21+ textColor : 'black' ,
22+ strokeColor : '#555' ,
23+ headerColor : 'white' ,
24+ hoverColor : '#1385cb'
25+ }
2026} ;
2127
2228const GEOMS = {
2329 text : ( value , _ , __ , O ) => {
2430 const el = d3 . create ( 'svg:text' )
2531 . attr ( 'dominant-baseline' , 'middle' )
2632 . attr ( 'y' , O . rowHeight / 2 )
33+ . style ( 'fill' , O . theme . textColor )
2734 . text ( value ) ;
2835 if ( O . fontSize ) {
2936 el . attr ( 'font-size' , O . fontSize ) ;
@@ -40,7 +47,7 @@ const GEOMS = {
4047 . attr ( 'y' , O . geomPadding )
4148 . attr ( 'width' , width )
4249 . attr ( 'height' , O . geomSize )
43- . style ( 'stroke' , O . geomStroke )
50+ . style ( 'stroke' , O . theme . strokeColor )
4451 . style ( 'stroke-width' , 1 )
4552 . style ( 'fill' , fill ) ;
4653 } ,
@@ -49,7 +56,7 @@ const GEOMS = {
4956 const fill = column . palette ( colorValue ) ;
5057 value = column . scale ( value ) ;
5158 return d3 . create ( 'svg:circle' )
52- . style ( 'stroke' , O . geomStroke )
59+ . style ( 'stroke' , O . theme . strokeColor )
5360 . style ( 'stroke-width' , 1 )
5461 . style ( 'fill' , fill )
5562 . attr ( 'cx' , O . rowHeight / 2 )
@@ -67,7 +74,7 @@ const GEOMS = {
6774 . domain ( [ column . min , column . min + column . range * O . midpoint ] ) ( value ) ;
6875 const radius = ( value * 0.9 + 0.12 ) * O . geomSize - O . geomPadding ; // 0.5 for stroke
6976 return d3 . create ( 'svg:circle' )
70- . style ( 'stroke' , O . geomStroke )
77+ . style ( 'stroke' , O . theme . strokeColor )
7178 . style ( 'stroke-width' , 1 )
7279 . style ( 'fill' , fill )
7380 . attr ( 'cx' , O . rowHeight / 2 )
@@ -81,7 +88,7 @@ const GEOMS = {
8188 . domain ( [ column . min + column . range * O . midpoint , column . max ] ) ( value ) ;
8289 const cornerSize = ( 0.9 - 0.8 * value ) * O . geomSize ;
8390 return d3 . create ( 'svg:rect' )
84- . style ( 'stroke' , O . geomStroke )
91+ . style ( 'stroke' , O . theme . strokeColor )
8592 . style ( 'stroke-width' , 1 )
8693 . style ( 'fill' , fill )
8794 . attr ( 'x' , O . geomPadding )
@@ -99,7 +106,7 @@ class FHeatmap {
99106 this . columnInfo = columnInfo ;
100107 this . columnGroups = d3 . index ( columnGroups , group => group . group ) ;
101108 this . palettes = palettes ;
102- this . options = { ... DEFAULT_OPTIONS , ... options } ;
109+ this . options = _ . merge ( DEFAULT_OPTIONS , options ) ;
103110 this . calculateOptions ( ) ;
104111 this . svg = svg ;
105112 }
@@ -116,7 +123,7 @@ class FHeatmap {
116123 . attr ( 'height' , O . rowHeight )
117124 . attr ( 'x' , 0 )
118125 . attr ( 'y' , i * O . rowHeight )
119- . attr ( 'fill' , i % 2 === 0 ? O . rowAlternatingBackground : 'white' ) ;
126+ . attr ( 'fill' , i % 2 === 0 ? O . theme . evenRowBackground : O . theme . oddRowBackground ) ;
120127 } ) ;
121128 }
122129
@@ -169,7 +176,7 @@ class FHeatmap {
169176 . attr ( 'x2' , offset + maxWidth )
170177 . attr ( 'y1' , 0 )
171178 . attr ( 'y2' , O . bodyHeight )
172- . attr ( 'stroke' , O . geomStroke )
179+ . attr ( 'stroke' , O . theme . strokeColor )
173180 . attr ( 'stroke-dasharray' , '5 5' )
174181 . attr ( 'opacity' , 0.5 ) ;
175182 }
@@ -222,7 +229,7 @@ class FHeatmap {
222229 . attr ( 'y' , O . rowHeight / 2 )
223230 . attr ( 'text-anchor' , 'middle' )
224231 . attr ( 'dominant-baseline' , 'central' )
225- . attr ( 'fill' , 'white' )
232+ . attr ( 'fill' , O . theme . headerColor )
226233 . text ( groupInfo . name ) ;
227234 if ( O . fontSize ) {
228235 text . attr ( 'font-size' , O . fontSize ) ;
@@ -233,7 +240,7 @@ class FHeatmap {
233240 . attr ( 'x' , groupStart + O . padding )
234241 . attr ( 'y' , O . rowHeight / 2 )
235242 . attr ( 'dominant-baseline' , 'central' )
236- . attr ( 'fill' , 'white' )
243+ . attr ( 'fill' , O . theme . headerColor )
237244 . text ( `${ letter } )` ) ;
238245 if ( O . fontSize ) {
239246 text . attr ( 'font-size' , O . fontSize ) ;
@@ -243,20 +250,24 @@ class FHeatmap {
243250 } ) ;
244251
245252 this . columnInfo . forEach ( column => {
246- const el = labels . append ( "g" )
247- . attr ( " transform" , `rotate(${ - O . columnRotate } )` )
253+ const el = labels . append ( 'g' )
254+ . attr ( ' transform' , `rotate(${ - O . columnRotate } )` )
248255 . classed ( `column-${ column . id } ` , true ) ;
249- el . append ( " text" )
250- . attr ( "x" , 0 )
251- . attr ( "y" , 0 )
256+ el . append ( ' text' )
257+ . attr ( 'x' , 0 )
258+ . attr ( 'y' , 0 )
252259 . attr ( 'font-size' , O . fontSize )
260+ . style ( 'fill' , O . theme . textColor )
253261 . style ( 'cursor' , 'pointer' )
254262 . datum ( column )
255263 . on ( 'click' , this . onColumnClick . bind ( this ) )
256264 . on ( 'mouseenter' , ( ) => {
257- el . style ( 'text-decoration' , 'underline dashed' ) . style ( 'fill' , '#1385cb' )
265+ el . style ( 'text-decoration' , 'underline dashed' )
266+ . style ( 'fill' , O . theme . hoverColor )
267+ } )
268+ . on ( 'mouseleave' , ( ) => {
269+ el . style ( 'text-decoration' , '' ) . style ( 'fill' , O . theme . textColor )
258270 } )
259- . on ( 'mouseleave' , ( ) => el . style ( 'text-decoration' , '' ) . style ( 'fill' , '' ) )
260271 . text ( column . name ) ;
261272 const nativeWidth = el . node ( ) . getBBox ( ) . width ;
262273 if ( ! nonZeroRotate && nativeWidth < column . width - 2 * O . padding ) {
@@ -290,7 +301,7 @@ class FHeatmap {
290301 . attr ( 'x2' , center )
291302 . attr ( 'y1' , headerHeight - 2 )
292303 . attr ( 'y2' , headerHeight - 2 - O . padding )
293- . attr ( 'stroke' , O . geomStroke ) ;
304+ . attr ( 'stroke' , O . theme . strokeColor ) ;
294305 }
295306 } ) ;
296307 this . options . width = bodyWidth ;
@@ -314,6 +325,7 @@ class FHeatmap {
314325 . attr ( 'x' , offset + O . geomSize / 2 )
315326 . attr ( 'y' , O . rowHeight + O . padding )
316327 . attr ( 'font-size' , O . legendFontSize )
328+ . style ( 'fill' , O . theme . textColor )
317329 . text ( 'Score:' ) ;
318330
319331 const column = new Column ( {
@@ -332,7 +344,7 @@ class FHeatmap {
332344 `translate(${ offset } , ${ 1.5 * O . rowHeight - height / 2 } )`
333345 ) ;
334346 if ( O . colorByRank ) {
335- el . style ( 'fill' , 'white' ) ;
347+ el . style ( 'fill' , O . theme . oddRowBackground ) ;
336348 }
337349 let tick = parseFloat ( i . toFixed ( 3 ) ) ;
338350 if ( O . legendTicks . indexOf ( tick ) > - 1 ) {
@@ -349,6 +361,7 @@ class FHeatmap {
349361 . attr ( 'font-size' , O . legendFontSize )
350362 . attr ( 'text-anchor' , 'middle' )
351363 . attr ( 'dominant-baseline' , 'text-top' )
364+ . style ( 'fill' , O . theme . textColor )
352365 . text ( tick ) ;
353366 }
354367 offset += width + 4 * O . geomPadding ;
@@ -381,7 +394,7 @@ class FHeatmap {
381394 . style ( "border" , "solid" )
382395 . style ( "border-width" , "1px" )
383396 . style ( "border-radius" , "5px" )
384- . style ( "padding" , "10px " )
397+ . style ( "padding" , "8px 5px " )
385398 . style ( "display" , "none" ) ;
386399 }
387400
@@ -430,7 +443,7 @@ class FHeatmap {
430443 if ( this . sortIndicator === undefined ) {
431444 this . sortIndicator = this . header . append ( "text" )
432445 . attr ( 'font-size' , 12 )
433- . attr ( 'fill' , '#1385cb' ) ;
446+ . attr ( 'fill' , O . theme . hoverColor ) ;
434447 }
435448 if ( column . sortState === "asc" ) {
436449 this . sortIndicator . text ( '↑' ) ;
@@ -506,7 +519,7 @@ function funkyheatmap(
506519 colAnnotOffset ,
507520 addAbc ,
508521 scaleColumn = true ,
509- options
522+ options = { }
510523) {
511524 [ data , columnInfo , columnGroups ] = maybeConvertDataframe ( data , columnInfo , columnGroups ) ;
512525 columnInfo = buildColumnInfo ( data , columns , columnInfo , scaleColumn , options . colorByRank ) ;
0 commit comments