Recharts: Struggling with font and font sizes in YAxis , XAxis, Legend etc.

Created on 15 Apr 2017  路  3Comments  路  Source: recharts/recharts

Most likely this is pilot error but I have tried many different ways and have been unsuccessful at modifying fonts and their characteristics in Recharts (nonetheless it is a great library and thanks for creating it) . I am using the most recent build and have example code that, no matter how I try, cannot modify the fonts used in the line charts. The code is below with two custom elements trying two differing ways to modify fonts...

Here is the code that i have tried (at least the most recent attempts) :

import React from 'react';

import { LineChart, Line, XAxis, YAxis,  Tooltip, Legend, Brush } from 'recharts';

//
// This font fetching code below is usually placed in the index.html file but I included it here for completeness
//

 var WebFontConfig = {
        google: { families: [ 'Roboto:300,400,500,700:latin' ] }
      };
      (function() {
        var wf = document.createElement('script');
        wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
        wf.type = 'text/javascript';
        wf.async = 'true';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(wf, s);
      })();

//
// The data to be rendered
//

const data = [
  { name: 'Page A', uv: 1000, pv: 2400,  amt:  260,     minV: 400,  maxV:  60,      xv: 200,  xmt:  20,         yv: 240,  ymt:  26 ,  zuv:   20  }
, { name: 'Page B', uv:  300, pv: 4567,  amt:  430,     minV: 567,  maxV:  30,      xv: 467,  xmt:  40,         yv: 456,  ymt:  43 ,  zuv:  210  }
, { name: 'Page C', uv:  280, pv: 1398,  amt:  130,     minV: 398,  maxV:  30,      xv: 198,  xmt:  10,         yv: 139,  ymt:  13 ,  zuv:  220  }
, { name: 'Page D', uv:  200, pv: 9800,  amt: 2600,     minV: 800,  maxV: 200,      xv: 900,  xmt: 260,         yv: 980,  ymt: 260 ,  zuv:  212  }
, { name: 'Page E', uv:  278, pv: 3908,  amt: 4300,     minV: 908,  maxV: 400,      xv: 308,  xmt: 430,         yv: 390,  ymt: 430 ,  zuv:  278  }
, { name: 'Page F', uv:  189, pv: 4800,  amt: 1300,     minV: 800,  maxV: 100,      xv: 400,  xmt: 130,         yv: 480,  ymt: 130 ,  zuv:  289  }
, { name: 'Page G', uv:  189, pv: 4800,  amt: 2400,     minV: 800,  maxV: 200,      xv: 400,  xmt: 240,         yv: 480,  ymt: 240 ,  zuv:  289  }
, { name: 'Page H', uv:  189, pv: 4800,  amt:  226,     minV: 800,  maxV:  26,      xv: 400,  xmt:  26,         yv: 480,  ymt:  22 ,  zuv:  289  }
, { name: 'Page I', uv:  189, pv: 4800,  amt:  243,     minV: 800,  maxV:  43,      xv: 400,  xmt:  23,         yv: 480,  ymt:  24 ,  zuv:  289  }
, { name: 'Page J', uv:  189, pv: 4800,  amt:  213,     minV: 800,  maxV:  13,      xv: 400,  xmt:  23,         yv: 480,  ymt:  21 ,  zuv:  289  }
];

//
// tool tip element (in theory)
//

 const renderTooltip =    props =>( <text  style={{  color: '#00bcd4' , fontFamily: 'Roboto', fontSize: 8  }}>{props.value}</text>)

//
// label element (almost!)
//

 const CustomizedLabel =  props =>( <text fill={props.stroke} fontFamily={'Arial'}  fontSize={8} textAnchor="middle">{props.value}</text>)

 // 
//your example updated to => syntax
//

export default props =>( 
    <div>
        <LineChart width={600} height={200} data={data} syncId="anyId"  margin={{top: 10, right: 10, left: 0, bottom: 0}}>
          <XAxis dataKey="name" stroke="#8884d8"/>
          <YAxis stroke="#8884d8" label={<CustomizedLabel />}/>
          <Tooltip content={renderTooltip}  />
          <Line type='monotone' dataKey='uv' stroke="#8884d8"  dot={false} fill='#8884d8' />
          <Line type='monotone' dataKey='xv' stroke="#8884d8"  dot={false} fill='#8884d8' />
          <Line type='monotone' dataKey='yv' stroke="#8884d8"  dot={false} fill='#8884d8' />
        </LineChart>
        <LineChart width={600} height={200} data={data} syncId="anyId"  margin={{top: 10, right: 10, left: 0, bottom: 0}}>
          <XAxis dataKey="name"/>
          <YAxis/>
          <Tooltip/>
          <Line type='monotone' dataKey='pv' stroke='#82ca9d' dot={false} fill='#82ca9d' />
        </LineChart>
        <LineChart width={600} height={200} data={data} syncId="anyId"   margin={{top: 10, right: 10, left: 0, bottom: 0}}>
          <XAxis dataKey="amt"/>
          <YAxis/>
          <Tooltip/>
          <Line type='monotone' dataKey='amt' stroke='#82ca9d' dot={false} fill='#82ca9d' />
        </LineChart>
        <LineChart width={600} height={200} data={data} syncId="anyId"   margin={{top: 10, right: 10, left: 0, bottom: 0}}>
          <XAxis dataKey="minV"/>
          <YAxis/>
          <Tooltip />
          <Line type='monotone' dataKey='minV' stroke='#82ca9d' dot={false} fill='#82ca9d' />
        <Brush />    
        </LineChart>
      </div>
  )

Any help with controlling the font and font size would be greatly appreciated
thanks

Most helpful comment

Could be done just with css for example:

svg.recharts-surface tspan {
    font-size: 0.8rem !important;
    color: black !important;
    font-family:  Arial;
}

All 3 comments

Always fun to figure things out... This solution is derived from the Recharts demo website plus a few hours of hacking.

import React ,{PropTypes}from 'react';

import { LineChart, Line, XAxis, YAxis,  Tooltip, Legend, Brush } from 'recharts';
 var WebFontConfig = {
        google: { families: [ 'Roboto:300,400,500,700:latin' ] }
      };
      (function() {
        var wf = document.createElement('script');
        wf.src = 'https://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
        wf.type = 'text/javascript';
        wf.async = 'true';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(wf, s);
      })();

const data = [
  { name: 'Page A', uv: 1000, pv: 2400,  amt:  260,     minV: 400,  maxV:  60,      xv: 200,  xmt:  20,         yv: 240,  ymt:  26 ,  zuv:   20  }
, { name: 'Page B', uv:  300, pv: 4567,  amt:  430,     minV: 567,  maxV:  30,      xv: 467,  xmt:  40,         yv: 456,  ymt:  43 ,  zuv:  210  }
, { name: 'Page C', uv:  280, pv: 1398,  amt:  130,     minV: 398,  maxV:  30,      xv: 198,  xmt:  10,         yv: 139,  ymt:  13 ,  zuv:  220  }
, { name: 'Page D', uv:  200, pv: 9800,  amt: 2600,     minV: 800,  maxV: 200,      xv: 900,  xmt: 260,         yv: 980,  ymt: 260 ,  zuv:  212  }
, { name: 'Page E', uv:  278, pv: 3908,  amt: 4300,     minV: 908,  maxV: 400,      xv: 308,  xmt: 430,         yv: 390,  ymt: 430 ,  zuv:  278  }
, { name: 'Page F', uv:  189, pv: 4800,  amt: 1300,     minV: 800,  maxV: 100,      xv: 400,  xmt: 130,         yv: 480,  ymt: 130 ,  zuv:  289  }
, { name: 'Page G', uv:  189, pv: 4800,  amt: 2400,     minV: 800,  maxV: 200,      xv: 400,  xmt: 240,         yv: 480,  ymt: 240 ,  zuv:  289  }
, { name: 'Page H', uv:  189, pv: 4800,  amt:  226,     minV: 800,  maxV:  26,      xv: 400,  xmt:  26,         yv: 480,  ymt:  22 ,  zuv:  289  }
, { name: 'Page I', uv:  189, pv: 4800,  amt:  243,     minV: 800,  maxV:  43,      xv: 400,  xmt:  23,         yv: 480,  ymt:  24 ,  zuv:  289  }
, { name: 'Page J', uv:  189, pv: 4800,  amt:  213,     minV: 800,  maxV:  13,      xv: 400,  xmt:  23,         yv: 480,  ymt:  21 ,  zuv:  289  }
];

 const Toolip = props =>  (! props.active) ? null :  ( <div style={{ fontFamily: 'Roboto',  color : '#00b4cd',  fontSize: '10px' }} >
                                                                        {props.payload.map(v => <p>{v.value}</p>)}
                                                                        <p>{ props.label }</p>
                                                       </div> )

  const NotAxisTickButLabel = props=> ( <g transform={  "translate( " + props.x + "," + props.y + " )" }><text x={0} y={0} dy={16}  fontFamily="Roboto"  fontSize="10px"  textAnchor="end"  fill={props.color || "#8884d8" } transform={"rotate(" + props.angle + ")" } >{props.payload.value}</text></g>   )


export default props =>( 
    <div>
        <LineChart width={600} height={200} data={data} syncId="anyId"  margin={{top: 10, right: 10, left: 0, bottom: 10}}>
          <XAxis stroke="#00b4cd" tick={<NotAxisTickButLabel angle={-90}/>} dataKey="name" />
          <YAxis stroke="#00b4cd" tick={<NotAxisTickButLabel angle={  0}/>}/>
          <Tooltip content={<Toolip/>}  />
          <Line type='monotone' dataKey='uv' stroke="#8884d8"  dot={false} fill='#8884d8' />
          <Line type='monotone' dataKey='xv' stroke="#8884d8"  dot={false} fill='#8884d8' />
          <Line type='monotone' dataKey='yv' stroke="#8884d8"  dot={false} fill='#8884d8' />
        </LineChart>
        <LineChart width={600} height={200} data={data} syncId="anyId"  margin={{top: 5, right: 10, left: 0, bottom: 10}}>
          <XAxis stroke="#00b4cd"  tick={<NotAxisTickButLabel angle={-90} color={"#00b4cd"}  />} dataKey="name" />
          <YAxis stroke="#00b4cd"  tick={<NotAxisTickButLabel angle={  0} color={"#00b4cd"}  />}/>
          <Tooltip content={<Toolip/>} />
          <Line type='monotone' dataKey='pv' stroke='#82ca9d' dot={false} fill='#82ca9d' />
        </LineChart>
        <LineChart width={600} height={200} data={data} syncId="anyId"   margin={{top: 5, right: 10, left: 0, bottom: 10}}>
          <XAxis stroke="#00b4cd" tick={<NotAxisTickButLabel angle={-90}/> }  dataKey="amt" />
          <YAxis stroke="#00b4cd" tick={<NotAxisTickButLabel angle={  0}/>}/>
          <Tooltip content={<Toolip/>} />
          <Line type='monotone' dataKey='amt' stroke='#82ca9d' dot={false} fill='#82ca9d' />
        </LineChart>
        <LineChart width={600} height={200} data={data} syncId="anyId"   margin={{top: 5, right: 10, left: 0, bottom: 10}}>
          <XAxis stroke="#00b4cd"  tick={<NotAxisTickButLabel angle={-90}/>}  dataKey="minV" />
          <YAxis stroke="#00b4cd"  tick={<NotAxisTickButLabel angle={  0}/>}/>
          <Tooltip  content={<Toolip/>} />
          <Line type='monotone' dataKey='minV' stroke='#82ca9d' dot={false} fill='#82ca9d' />
        <Brush />    
        </LineChart>
      </div>
  ) 

Could be done just with css for example:

svg.recharts-surface tspan {
    font-size: 0.8rem !important;
    color: black !important;
    font-family:  Arial;
}

It shows how the world has changed. Back when i wrote this note conventional react wisdom (due mainly to react native) was to avoid css. Now it is back with a vengeance. Performance of css and jss are substantially faster than inline styles. So rather than go against the grain I have put most of my static style into a class method I call styler (for each component they are slightly different.) that i call in the constructor. This is inline like (locally controlled and therefore more convenient to change) yet it benefits from css performance advantages).

Here is an example (sorry about the wide lines. I figure that i pay for the entire 4k monitor i might as well use it! )

        styler     =  props =>{    if(!! document.getElementById('styler' )  )   return
                                    let style = document.createElement('style')
                                        , css =   ' .elcaromen        { background-color : #ffffff ; color : #00b4dc;    font-family : Roboto ; font-size: 12  ; border-radius: 3px;  margin: 4;  padding :8; margin-bottom : 8 ;} '
                                        +         ' .elcaromen:hover  {  border-bottom: 3px inset  rgba(  0,188, 212, .5) ;  border-right:  2px inset  rgba(0  ,188, 212, .4) ; } '  
                                        +         ' .selstyle:hover   {  border-bottom: 3px inset  rgba(0,188, 212, .5) ;   border-right:  2px inset  rgba(0,188, 212, .4) ; fill:  #00b4dc ; }  '
                                        +         ' .unselstyle:hover {  border-bottom: 2px inset  rgba(255,64, 127,.4) ;   border-right:  1px inset  rgba(255,64, 127,.3) ; fill:  #ff4081 ; }  '  
                                        +         ' .popx1anch        {  position : fixed ; height : 100% ; width: 100% ; background-color : rgba(9, 90, 166,0.01) ; top: 0 ; left: 0 ;  z-index : 9999;  overflow-x: hidden; overflow-y: visible ; } '
                                        +         ' .popx2menu        {  position : absolute ;  background-color : #ffffff ;   overflow :  hidden ;  }  '
                                        +         ' .popx3hedr        {  position : relative ; height : 24 ; width :  100% ; }  '
                                        +         ' .pop4svg          {  position : absolute ; height : 24 ; top: 0 ; left:  0  ; width :  24  ;  margin : 0  ; fill :   #7f7f7f     ;        }  '
                                        +         ' .pop5div          {  position : absolute ; height : 24 ; top: 0 ; left: 25  ; right :  25  ;  background-color: rgba(127,127,127, 0.3) ;  }  '
                                        +         ' .pop6svg          {  position : absolute ; height : 24 ; top: 0 ; right: 0  ; width :  24  ;  margin : 0  ; fill :   #7f7f7f   ;          }  '
                                        +         ' .pop5div:hover    {  border-bottom: 3px inset  rgba(0,188, 212, .5) ;   border-right:  2px inset  rgba(0,188, 212, .4) ; fill:  #00b4dc ; }  '
                                        +         ' .pop4svg:hover    {  border-bottom: 3px inset  rgba(0,188, 212, .5) ;   border-right:  2px inset  rgba(0,188, 212, .4) ; fill:  #00b4dc ; }  '
                                        +         ' .pop6svg:hover    {  border-bottom: 3px inset  rgba(0,188, 212, .5) ;   border-right:  2px inset  rgba(0,188, 212, .4) ; fill:  #00b4dc ; }  '  
                                      style.type   = 'text/css' 
                                      style.id     = 'styler' 
                                      style.appendChild(document.createTextNode(css)) 
                                      document.head.appendChild(style) 
        }
Was this page helpful?
0 / 5 - 0 ratings