Home Reference Source Test

packages/causality-log/src/Vivid/vivid.js

import * as d3 from 'd3';
import { platform } from 'causal-net.utils';
import { default as LineChartMixins } from './line.chart.mixins';
import { default as ScatterChartMixins } from './scatter.chart.mixins';
import { default as VividWebMixins } from './vivid.mixins.web';
import { default as VividNodeMixins } from './vivid.mixins.node';
class BasePlot{
    constructor(){

    }
    connect(){
        throw Error('implement require');
    }
}
class Vivid extends platform.mixWith(BasePlot, 
        { node: [VividNodeMixins, ScatterChartMixins, LineChartMixins],
           web: [VividWebMixins, ScatterChartMixins, LineChartMixins]}){
    constructor(d3){
        super();
        this.d3 = d3;
        this.DefaultWidth = 900;
        this.DefaultHeight = 600;
        this.defaultStyle = { svg:  {font: '10px sans-serif' },
                              '.label': {'fill': 'white'},
                              '.axis path, .axis line': { fill: 'none',
                                    'stroke': '#000; shape-rendering: crispEdges' },
                              '.dot' : { 'stroke': '#000' } };
    }

    png({data, width, height, title, plotId}){
        let canvas = this.makeCanvasNode({width, height});
        let context = canvas.getContext?canvas.getContext('2d'):canvas.node().getContext("2d");
        let imagedata = context.createImageData(width, height);
        for (var x=0; x<width; x++) {
            for (var y=0; y<height; y++) {
                var pixelindex = (y * width + x) * 4;
                imagedata.data[pixelindex]   = data[pixelindex];
                imagedata.data[pixelindex+1] = data[pixelindex+1];
                imagedata.data[pixelindex+2] = data[pixelindex+2];
                imagedata.data[pixelindex+3] = data[pixelindex+3];
            }
        }
        context.putImageData(imagedata, 0, 0);
        title = title?title:'unname';
        plotId = plotId?plotId:title.replace(/\s/g,'_') + '.png';
        return plotId;
    }

    basePlot({kwdata, width, height, xLabel, yLabel, style}){
        const d3 = this.d3;
        style = style!==undefined?style:{};
        style = Object.assign({}, this.defaultStyle, style);
        let cssStyle = this.json2css(style);
        width  = width?width : this.DefaultWidth;
        height = height?height : this.DefaultHeight;
        const plotMargin = {top: 20, right: 20, bottom: 30, left: 40},
              plotWidth  = width - plotMargin.left - plotMargin.right,
              plotHeight = height - plotMargin.top - plotMargin.bottom;
        
        
        var svg = this.makeSVGnode({width, height, styles: cssStyle});
        
        svg = svg.append("g")
                    .attr("transform", 
                          "translate(" + plotMargin.left + "," + plotMargin.top + ")");
        let xDomain = d3.extent(kwdata, ([xPoint, yPoint, name])=>xPoint);
        let yDomain = d3.extent(kwdata, ([xPoint, yPoint, name])=>yPoint);
        
        var xMap = d3.scaleLinear().range([0, plotWidth]).domain(xDomain);
        var yMap = d3.scaleLinear().range([plotHeight, 0]).domain(yDomain);
        
        var xAxis = d3.axisBottom(xMap);
        var yAxis = d3.axisLeft(yMap);
        var color = d3.scaleOrdinal(d3.schemeCategory10);
        kwdata.map(([x,y,name])=>color(name));
        xLabel = xLabel?xLabel:'x axis';
        yLabel = yLabel?yLabel:'y axis';
        svg.append("g").attr("class", "x axis")
            .attr("transform", "translate(0," + plotHeight + ")").call(xAxis)
            .append("text").attr("class", "label")
            .attr("x", plotWidth).attr("y", 0).style('fill','white')
            .style("text-anchor", "end").text(xLabel);
        svg.append("g").attr("class", "y axis").call(yAxis)
            .append("text").attr("class", "label")
            .attr("transform", "rotate(-90)")
            .attr("y", 6).attr("dy", ".91em").style('fill','white')
            .style("text-anchor", "end").text(yLabel);
        
        var legend = svg.selectAll(".legend")
            .data(color.domain()).enter()
            .append("g").attr("class", "legend")
            .attr("transform", (d,i)=>"translate(0," + i * 20 + ")");

        legend.append("rect").attr("x", plotWidth - 18).attr("width", 18)
            .attr("height", 18).style("fill", color);

        legend.append("text").attr("x", plotWidth - 24).attr("y", 9)
            .attr("dy", ".35em").style("text-anchor", "end").text(d=>d);
        this.plotStyle = cssStyle;
        return  { svg, xMap, yMap, color };
    }
}
let vivid = new Vivid(d3);
export default vivid;