src/Plot.ts

   1/**

   2 * Abstract base class for plots.

   3 */

   4

   5/** */

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

   7export type Vnode = typeof m.Vnode;

   8import { SVGElem,

   9         TextElem,

  10         TextHAlign,

  11         TextVAlign }   from './SVGElem';

  12import { Data, 

  13         DataRow }      from 'hsdatab';

  14import { XYScale }      from './AxesTypes';

  15import { Series, 

  16         SeriesStyle,

  17         SeriesDef }    from './Series';

  18import { round }        from 'hsutil';

  19

  20export abstract class Plot extends SVGElem {

  21    drawLine(clipID:string, data:DataRow[], x:number, y:number, scales:XYScale, sStyle:SeriesStyle, title?:string) {

  22        const style = `stroke: ${sStyle.line.color}; stroke-width:${sStyle.line.width};`;

  23        return !sStyle.line.visible? m('.invisible-line','') : this.polyline(data, x, y, scales, clipID, style, title);

  24    }

  25

  26    drawMarker(clipID:string, data:DataRow[], x:number, y:number, scales:XYScale, sStyle:SeriesStyle, title?:string) {

  27        const mrk = Series.marker;

  28        let style = `fill:${sStyle.marker.color}`;

  29        return !sStyle.marker.visible? m('.invisible-marker','') : m('svg', {class:'hs-graph-series-markers'},

  30            data.map((p:number[]) => {

  31                const cx = scales.x.convert(p[x]);

  32                const cy = scales.y.convert(p[y]);

  33                const r  = sStyle.marker.size;

  34                switch (sStyle.marker.shape) {

  35                    case mrk.circle: 

  36                        return this.circle({x:cx, y:cy}, r, style, title);

  37                    case mrk.square: 

  38                        return this.rect({x:cx-r, y:cy-r}, {w:2*r, h:2*r}, style, title);

  39                    case mrk.diamond: 

  40                        return this.shape([[cx-r, cy], [cx, cy+r], [cx+r, cy], [cx, cy-r]], undefined, style, title);

  41                    case mrk.upTriangle: 

  42                        return this.shape([[cx-r, cy+r], [cx+r, cy+r], [cx, cy-r]], undefined, style, title);

  43                    case mrk.downTriangle: 

  44                        return this.shape([[cx-r, cy-r], [cx+r, cy-r], [cx, cy+r]], undefined, style, title);

  45                }

  46                return m(`.unkown-marker-${sStyle.marker.shape}`,'');

  47            })

  48        );

  49    }

  50

  51    drawLabel(clipID:string, data:DataRow[], x:number, y:number, lbl:number, scales:XYScale, sDef:SeriesDef) {

  52        const sStyle = sDef.style;

  53        const cfg:TextElem = {

  54            text:       ''

  55            cssClass:   ``,

  56            style:      `fill:${sStyle.label.color}`,

  57            xpos:       TextHAlign.middle,

  58            ypos:       TextVAlign.center,

  59            hOffset:    sDef.hOffset,

  60            vOffset:    sDef.vOffset

  61        };

  62        return !sStyle.marker.visible? m('.invisible-marker','') : m('svg', {class:'hs-graph-series-labels'},

  63            data.map((p:DataRow) => {

  64                cfg.x = ''+scales.x.convert(p[x]);

  65                cfg.y = ''+scales.y.convert(p[y]);

  66                return this.text(cfg, round(p[lbl], 3));

  67            })

  68        );

  69    }

  70

  71    drawArea(clipID:string, data:DataRow[], x:number, yFore:number, yBack:number, scales:XYScale, sStyle:SeriesStyle, title:string) {

  72        if (sStyle.fill.visible) {

  73            const style = `fill: ${sStyle.fill.color};`;

  74            const drawFore = data;

  75            const drawBack = data.slice().reverse();

  76            return this.polygon(drawFore, drawBack, x, yFore, yBack, scales, clipID, style, title);

  77        } else {

  78            m('.invisible-line','');

  79        }

  80    }

  81

  82    abstract plot(data:Data, series:SeriesDef, scales:XYScale, i:number, clipID:string): Vnode[];

  83

  84    setDefaults(data:Data, series:SeriesDef, scales:XYScale) {

  85    }

  86

  87

  88

  89

  90