Giter VIP home page Giter VIP logo

jmgraph's Introduction

jmGraph

Latest NPM release Build Status

基于CANVAS的简单画图组件
让你用类似于dom的方式,在canvas上画图,感觉会不会很爽。

基于它的图表应用:https://github.com/jiamao/jmchart

安装

直接从github下载包或npm安装。 如需要构建,直接在项目录下执行npm run build即可。

npm install jmgraph
yarn add jmgraph

入门

es5引用办法

下载dist/jmgraph.min.js代码,并引用到你的html中。

<script type="text/javascript" src="../dist/jmgraph.min.js"></script>	

也可以用commonjsrequirejs等模块化库。

requirejs
<script type="text/javascript" src="js/require.js"></script>
<script>
    require(['../dist/jmgraph.js'], function(m) {
        var g = new m.jmGraph();
    });
</script>
es6模块引用

也可以直接用es6中的import来引用

<script type="module">
  // import jmGraph from "../dist/jmgraph.es6.js";
  // import jmGraph from "./node_modules/jmgraph/index.js";
  import jmGraph from "jmgraph";
  var container = document.getElementById('mycanvas_container');		
  var g = new jmGraph(container, {
    width: 800,
    height: 600,
    autoRefresh: true, // 是否自动刷新变化
    style: {
      fill: '#000'
    }
  });
</script>

在dom中添加一个div或canvas,然后初始化jmGraph。

<div id="mycanvas_container"></div>
<script type="text/javascript">	
    //也可以是一个dom对象或一个jquery对象 
    //例如:$('#mycanvas_container') || document.getElementById('mycanvas_container')
    var container = 'mycanvas_container';
    
    var g = jmGraph.create(container, {
        width: 800,
        height: 600,
        //样式,规则请参照样式说明
        style: {
            fill: '#000' //指定背景色
        }
    });
</script>

在画布上画一个方块

function init(g){
    var style = {
        stroke:'#46BF86',
        lineWidth: 2
    };
    style.shadow = '0,0,10,#fff';//阴影
    //style.opacity = 0.2;			
    //style.lineCap = 'round';

    //创建一个方块
    var rect = g.createShape('rect',{
        style:style,
        position: {x:100,y:100}, //左上角坐标
        width:100,
        height:100
    });
    g.children.add(rect);

    //绘制,可以用requestAnimationFrame动态刷新
    function update() {
        g.redraw();
        //requestAnimationFrame(update);
    }
    update();
}

样式

样式可以直接用canvas支持的名称,也可以用本组件简化后的。

样式一览

简化名称 原生名称 说明
fill fillStyle 用于填充绘画的颜色、渐变或模式
stroke strokeStyle 用于笔触的颜色、渐变或模式
shadow 没有对应的 最终会解析成以下几个属性,格式:'0,0,10,#fff'或g.createShadow(0,0,20,'#000');
shadow.blur shadowBlur 用于阴影的模糊级别
shadow.x shadowOffsetX 阴影距形状的水平距离
shadow.y shadowOffsetY 阴影距形状的垂直距离
shadow.color shadowColor 阴影颜色,格式:'#000'、'#46BF86'、'rgb(255,255,255)'或'rgba(39,72,188,0.5)'
lineWidth lineWidth 当前的线条宽度
miterLimit miterLimit 最大斜接长度
font font 请使用下面的 fontSize 和 fontFamily
fontSize font 字体大小
fontFamily font 字体
opacity globalAlpha 绘图的当前 alpha 或透明值
textAlign textAlign 文本内容的当前对齐方式
textBaseline textBaseline 在绘制文本时使用的当前文本基线
lineJoin lineJoin 两条线相交时,所创建的拐角类型:miter(默认,尖角),bevel(斜角),round(圆角)
lineCap lineCap 线条的结束端点样式:butt(默认,平),round(圆),square(方)

事件

事件的绑定函数:bind/unbind
示例:

//创建一条线
var line = graph.createLine({x:10,y:200},{x:80,y:120},style);
//鼠标移到上面显示不同的样式			
line.bind('mouseover',function(evt) {
    this.style.stroke = 'rgba(39,72,188,0.5)';
    this.cursor('pointer');
    this.neadUpdate = true; //需要刷新
});

如果要某个控件不响用操作事件,设置其interactivefalse即可。

事件一览

名称 说明 回调参数
mousedown 鼠标按下时触发 -
mousemove 鼠标在对象上移动时触发 {target:当前元素,position: 当前位置}
mouseover 鼠标从某元素移开 {target:当前元素}
mouseleave 某个鼠标按键被松开 -
mouseup 某个鼠标按键被松开 -
dblclick 鼠标双击某个对象 -
click 鼠标点击某个对象 -
touchstart 触控开始 position: 当前位置
touchmove 触控移动手指 position: 当前位置
touchend 触控结束 position: 当前位置

控件

Path

path是多数图形的基类,可以指定一个points数组来绘制一个路径。
在线示例

var path = graph.createPath(null, style);
path.points.push({x:10,y:10});
path.points.push({x:10,y:60});
path.points.push({x:80,y:20});
path.points.push({x:90,y:80});
path.points.push({x:80,y:80});

arc可以创建椭圆、圆弧和圆,circle调用的是原生的arc函数绘制,harc可以绘制一个圆环。 具体请参考示例。 在线示例

//创建一个椭圆,指定不同的宽高就为椭圆。如果相同或指定半径则为圆。
var arc1 = g.createShape('arc', {
    style: style,
    center: {x:100, y:150},
    width: 120,
    height: 80
});		

箭头

arrow为创建一个箭头, Arrowline是一条带箭头的直线。
具体请参考示例。 在线示例

//带箭头的直线
var shape = g.createShape('Arrowline', {
    style:style,
    start: {x:100,y:100},
    end: {x: 200, y: 350}
});	
//一起结束点和一个角度angle可以决定一个箭头,如果不填angle,则会用start和end来计算角度
var arrow = g.createShape('arrow', {
    style:style,
    start: {x:150, y:120},
    end: {x: 160, y: 150}
    //angle: Math.PI/2, //箭头角度  可以不填
    //offsetX: 5, //箭头X偏移量
    //offsetY: 8 //箭头Y偏移量
});	

贝塞尔曲线

bezier可以指定无数个控制点,绘制复杂的曲线。 具体请参考示例。 在线示例

//一个固定的bezier曲线
var bezier = g.createShape('bezier', { style: style, points: [p0, p1, p2, p3, p4] });

图片

img是用来承载一张图片的控件,可以用style.src来指定图片url。 具体请参考示例。 在线示例

var style = {
    src: 'http://mat1.gtimg.com/www/qq2018/imgs/qq_logo_2018x2.png'
};
style.shadow = '0,0,10,#fff';
//style.opacity = 0.2;		

//创建一个image
var img = g.createShape('image',{
    style:style,
    position: {x:100,y:100}
});	
//设置图片可以用鼠标移动		
img.canMove(true);

文字

label可以用来绘制文字,通过style指定样式。 具体请参考示例。 在线示例

var style = {
    stroke: '#effaaa',
    fill: '#fff',
    textAlign: 'center', //水平居中
    textBaseline: 'middle', //垂直居中
    fontSize: 24,
    fontFamily: 'Arial',
    border: {
        left:1,
        top:1,
        right:1,
        bottom:1,
        //边框样式
        style: {
            stroke: 'red' //颜色
        }
    }, //边框
    shadow: '0,0,10,#fff'
};
//style.opacity = 0.2;		

//创建一个label
var label = g.createShape('label',{
    style:style,
    position:{x:200,y:150},
    text:'test label',
    width:120,
    height:80
});		

棱形

prismatic
具体请参考示例。 在线示例

var prismatic = g.createShape('prismatic',{
    style:style,
    center:{x:200,y:150},
    width:120,
    height:80
});		

可缩放控件

resize 可以自由放大缩小的控件。 具体请参考示例。 在线示例

var style = {
    stroke: 'red',
    fill: 'yellow',
    lineWidth: 2, //边线宽
    //小方块样式
    rectStyle: {
        stroke: 'green', //小方块边颜色
        fill: 'transparent',//小方块填充色
        lineWidth: 1, //小方块线宽
        close: true
    }
};
//style.opacity = 0.2;		

//创建一个resize
var resize = g.createShape('resize', {
    style: style,
    position: {x:200, y:150},
    width: 120,
    height: 80
});	
//大小改变事件
resize.on('resize', function() {
    console.log(arguments);
});	

自定义控件

大多数控件直接继承jmPath即可,然后通过实现initPoints来绘制当前控件。
当需要从某点重新开始画时,给点指定m属性为true,表示移到当前点。

继承这里需要用到es6的模块,所以当你用的是script标签时,记得给type="module"。 或写一个class的js文件,构建成es5的。

示例

来画一个X
在线示例:http://jiamao.github.io/jmgraph/example/controls/test.html

import {jmGraph} from "../../src/jmGraph.js";
import {jmPath} from "../../src/shapes/jmPath.js";
/**
 * 测试
 */
class jmTest extends jmPath {
    constructor(params) {
        if(!params) params = {};
        super(params);
        this.center = params.center || {x:0, y:0};
        this.radius = params.radius || 0;
    }   

    //定义属性 
    /**
     * 中心点
     * point格式:{x:0,y:0,m:true}
     * @property center
     * @type {point}
     */
    get center() {
        return this.property('center');
    }
    set center(v) {
        return this.property('center', v);
    }
    /**
    * 半径
    * @property radius
    * @type {number}
    */
    get radius() {
        return this.property('radius');
    }
    set radius(v) {
        return this.property('radius', v);
    }

    /**
    * 初始化图形点
    * 控件都是由点形成
    * 
    * @method initPoint
    * @private
    * @for jmArc
    */
    initPoints() {
        //可以获取当前控件的左上坐标,可以用来画相对位置
        var location = this.getLocation();//获取位置参数
        
        var cx = location.center.x ;
        var cy = location.center.y ;
    
        this.points = [];

        //简单的画一个X

        //根据半径计算x,y偏移量
        //由于是圆,偏移量相同
        var offw = Math.sqrt(location.radius * location.radius / 2);
        //左上角到右下角对角线
        this.points.push({x:cx - offw, y:cy-offw}, {x:cx + offw, y:cy+offw});

        //左下角到右上角对角线
        //画完上面的线后,需要重新移到这条线的起点,指定m:true即可
        this.points.push({x:cx - offw, y:cy+offw, m:true}, {x:cx + offw, y:cy-offw});

        return this.points;
    }
} 

微信小程序支持

线上体验小程序: 截图

源码:https://github.com/jiamao/mini-jmchart

微信小程序稍有差别,因为无需压缩,请直接把dist中的jmgraph.js合并后的文件引用到你的小程序中。

示例

wxml

<canvas style="width: 400px; height: 600px;background:#000;" 
    canvas-id="mycanvas" 
    bindtouchstart="canvastouchstart" 
    bindtouchmove="canvastouchmove" 
    bindtouchend="canvastouchend" 
    bindtouchcancel="canvastouchcancel">
</canvas>

javascript

/**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {
    
    //这里引用jmgraph
    let jmGraph = require('../../utils/jmgraph');

    var self = this;

    var g = jmGraph.create('mycanvas', {
        style: {
          fill: '#000'
        },
        width: 400,
        height: 600
      });
    init(g);

    function init(g) {
      //g.style.fill = '#000'; //画布背景
      var style = {
        stroke: '#46BF86',
        fill: '#556662',
        lineWidth: 2
      };
      style.shadow = '0,0,10,#fff';
      //style.opacity = 0.2;			
      //style.lineCap = 'round';

      //创建一个方块
      var rect = g.createShape('rect', {
        style: style,
        position: { x: 100, y: 100 },
        width: 100,
        height: 100
      });
      rect.canMove(true);
      g.children.add(rect);

      function update() {
        if (g.needUpdate) g.redraw();
        setTimeout(update, 20);
      }

      update();

      //初始化jmGraph事件
      //把小程序中的canvas事件交给jmGraph处理
      this.canvastouchstart = function (...arg) {
        return g.eventHandler.touchStart(...arg);
      }
      this.canvastouchmove = function (...arg) {
        return g.eventHandler.touchMove(...arg);
      }
      this.canvastouchend = function (...arg) {
        return g.eventHandler.touchEnd(...arg);
      }
      this.canvastouchcancel = function (...arg) {
        return g.eventHandler.touchCancel(...arg);
      }
    }
  }

jmgraph's People

Contributors

fefeding avatar

Stargazers

苗大 avatar Neo Lee avatar 穷屌丝 avatar momo avatar  avatar Yutao Zhou avatar Bi8bo avatar Song avatar 叶俊青 avatar Mr.Q avatar kaiwen avatar Meway avatar  avatar Jiaqi Shao avatar qianyu avatar okevinok avatar liuyiyi avatar  avatar 觉·白 avatar  avatar  avatar  avatar tan-zhuo avatar  avatar  avatar cuixf avatar Yu avatar Liu avatar No-coke avatar Wang Chengyu avatar 木木大叔 avatar Richard avatar  avatar 白若水 avatar 小宅 avatar iaminvictus avatar  avatar xiaoyu avatar 归去来xi~~ avatar Yige avatar wlei avatar  avatar  avatar Bohan Zhang avatar  avatar mengxi avatar Cuixiping avatar Arjun avatar Airing avatar  avatar CalosChen avatar Sanjay Rajashekhar avatar Steven Cai avatar Dionlan Alves avatar  avatar pyttok avatar MelodyMS avatar hester avatar Wang WenHua  avatar jackieLin avatar  avatar LYF avatar  avatar  avatar ZhouYing avatar  avatar  avatar luwei avatar  avatar Scott Wong avatar bugXiao avatar  avatar ANT avatar  avatar  avatar  avatar frank avatar bred avatar ace avatar Jasonsjiang avatar y109 avatar lumix avatar Fonkie Chen avatar  avatar Xu avatar

Watchers

helight avatar James Cloos avatar  avatar web5 avatar  avatar Richard avatar  avatar  avatar  avatar

jmgraph's Issues

在高分辨率屏幕下,电脑设置屏幕缩放200%,节点定位问题

屏幕分辨率:3200x2000
屏幕尺寸:15 寸
屏幕缩放:200%

设置画布宽度900,高度400
实际显示宽度900,高度400,查看画布属性 宽度1800,高度800

使用getBounds(),getAbsoluteBounds() 获取节点定位数据,发现top和left数据都被放大2倍,猜测和屏幕缩放200%有关系

基于 canvas 的滚动

大佬你好~
很高兴找到这个库,之前一直苦恼于 canvas 相对于 dom 来说。写法比较 “笨拙”,想着可以跟 dom 一样简洁高效,类似的库也不少,比如:konva,easycanvas 等
但这些库都没有涉及一个问题:如何做类似于 dom 上的滚动效果,且有着「虚拟列表」特性;
举个例子:长列表中只渲染一部分数据,等滚动到特定位置后才渲染特定部分。
有考虑做这种功能吗?或者有什么比较好的思路呢?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.