src/Chart.ts

   1/**

   2 * # Chart

   3 * renders the chart background and title.

   4 * 

   5 * ### Attributes

   6 * The `Chart` class is called by {@link Graph.Graph `Graph`} as 

   7 * `m(Chart, { cfg:cfg.chart, plotArea:plotArea })`

   8 * with the following attributes:

   9 * - cfg: a {@link Chart.ChartConfig ChartConfig} object

  10 * - plotArea: a {@link SVGElem.Rect Rect } object for plotting the chart background

  11 * 

  12 * ### Configurations and Defaults

  13 * See {@link Chart.Chart.defaultConfig Chart.defaultConfig}

  14 */

  15

  16 /** */

  17 export const m = require("mithril");

  18 export type Vnode = typeof m.Vnode;

  19 import { Config, 

  20         LabelCfg,

  21         VisibleCfg }       from './Graph';

  22import { SVGElem,  Rect }   from './SVGElem';

  23

  24

  25/** Defines configurable settings. */

  26export interface ChartConfig extends VisibleCfg {

  27    /** the title text and positioning  */

  28    title:  LabelCfg;

  29};

  30

  31/**

  32 * Renders the chart background and title.

  33 */

  34export class Chart extends SVGElem { 

  35    /** 

  36     * Defines default values for display elements in `Chart`

  37     * See {@link Graph.Graph.makeConfig Graph.makeConfig} for the sequence of initializations.

  38     * 

  39     * ### Configurations and Defaults

  40     * ```

  41     *  cfg.chart = {@link Chart.ChartConfig }{

  42     *     visible: true,         // Chart area is visible

  43     *     title:  {              // the chart title

  44     *        visible: true,      // Chart title is visible

  45     *        text:'',            // the sting to display

  46     *        hOffset: 0,         // horizontal label offset in 'em'

  47     *        vOffset: -1.5,      // vertical label offset in 'em'

  48     *        xpos:'middle',      // start | middle | end; hor. title position: 0-100%, rel. to Chart

  49     *        ypos:'top'          // top | center | bottom ver. title position: 0-100%, rel. to Chart

  50     *     }   

  51     *  } 

  52     * ``` 

  53     * @param cfg the configuration object, containing default settings for all 

  54     * previously configured components.

  55     */

  56    static defaultConfig(cfg:Config) {

  57        cfg.chart = {

  58            visible: true,          // Chart area is visible

  59            title:  {     // the chart title

  60                visible: true,      // Chart title is visible

  61                text:'',            // the sting to display

  62                hOffset: 0,         // horizontal label offset in 'em'

  63                vOffset: -1.5,      // vertical label offset in 'em'

  64                xpos:'middle',      // hor. title position: 0-100%, rel. to Chart

  65                ypos:'top'          // ver. title position: 0-100%, rel. to Chart

  66            }

  67        };

  68    return cfg;

  69    }

  70

  71    /**

  72     * Makes adjustments to cfg based on current settings

  73     * @param cfg the configuration object, containing default settings for all components

  74     */

  75    static adjustConfig(cfg:Config) {        

  76    }

  77    

  78    static clientWidth:number;

  79    static clientHeight:number;

  80

  81    onupdate(node?: Vnode) { 

  82        this.updateTitleSize(node);

  83//                m.redraw();

  84    }

  85

  86    updateTitleSize(node: Vnode) {

  87        // get clientWidth /Height of title

  88        if (node.dom) {

  89            const c = node.dom.lastChild;

  90            if (c && c.clientWidth>0) {

  91                if (Chart.clientWidth !== c.clientWidth) {

  92                    Chart.clientWidth = c.clientWidth;

  93                    Chart.clientHeight = c.clientHeight;

  94                }

  95            }

  96        }

  97    }

  98

  99    drawBackground(plotArea:Rect) {

 100        const tl = plotArea.tl;

 101        const br = plotArea.br;

 102        return this.rect({x:tl.x, y:tl.y}, {w: br.x-tl.x, h: br.y-tl.y},'');

 103    }

 104

 105    drawTitle(plotArea:Rect, cfg:ChartConfig) {

 106        const tl = plotArea.tl;

 107        const br = plotArea.br;

 108        cfg.title.cssClass = 'hs-graph-chart-title';

 109        switch(cfg.title.xpos) {

 110            case 'start':   cfg.title.x = tl.x+'';   break;

 111            case 'middle':  cfg.title.x = (tl.x+br.x)/2+'';  break;

 112            case 'end':     cfg.title.x = br.x+''; break;

 113        }

 114        switch(cfg.title.ypos) {

 115            case 'top':     cfg.title.y = tl.y+'';   break;

 116            case 'center':  cfg.title.y = (tl.y+br.y)/2+'';  break;

 117            case 'bottom':  cfg.title.y = br.y+''; break;

 118        }

 119        return !cfg.title.visible? undefined : this.text(cfg.title, cfg.title.text);

 120    }

 121

 122    view(node?: Vnode): Vnode {

 123        const cfg:ChartConfig = node.attrs.cfg;

 124        const plotArea:Rect = node.attrs.plotArea;

 125        return m('svg', { class:'hs-graph-chart'}, [

 126            this.drawBackground(plotArea),

 127            this.drawTitle(plotArea, cfg)

 128        ]);

 129    }

 130}

 131

 132