1) 面对可视化需求, 应该选择canvas还是svg?
答: canvas是基于HTMLCanvasElement, 图形是调用api绘制的, 主要是写js。不过, 对于复杂的path,比svg的path稍微步骤多一点, svg只要用字母数字组成string即可。
svg是类似于HTML的, 元素用html拼成, 主要是写html。svg更合适写需要互动的图片, 更方便写交互。
有时候, 我们也会使用div做热力图, 好处是tooltip等很方便。
2) 如何自适应高度和宽度
svg很方便做成自适应的高宽,viewport='x y width height" width相当于把页面等分成width份。
canvas需要用js计算需要的宽度。 例如:
const container = <HTMLCanvasElement>document.getElementByTagName('canvas');
container.width = body.clientWidth;
// sreen.width>screen.availWidth>window.outerWidth>window.innerWidth>body.clientWidth (body.clientWidth是页面显示的宽度, 而body.offsetWidth是页面总的高度)(滚动条的宽度 = window.innerWidth - body.clientWidth)
const colors = ['red'];
const ctx = container.getContext('2d');
const DrawChart = (options) => {
this.options = options;
this.ctx = options.ctx;
this.colors = options.colors;
this.draw = () => {
this.ctx.save();
this.ctx.strokeStyle = this.colors[0];
this.ctx.strokeRect(0,0,10,10);
this.ctx.strokeText('Hello world', 5,5);
this.ctx.restore();
}
this.clear = () => {
this.ctx.save();
this.ctx.clearRect(0,0,10,10);
this.ctx.restore();
}
}
const drawChart = new DrawChart({ctx, colors});
3) 如何加入tooltip?
a. canvas: 其实canvas加入tooltip不是很方便,需要计算监听mouseover/mouseOut的事件, 事件处理是判断计算元素进入范围, 如果进入范围,需要draw这个图形元素。
//e:MouseEvent
const clickX = e.pageX - canvas.offsetLeft;
const clickY = e.pageY - canvas.offsetTop;
const distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2)+ Math.pow(circle.y - clickY, 2))
// 判断这个点是否在圆圈中
if (distanceFromCenter <= circle.radius) {
tooltip();
}
b. 在angular需要处处插值, 插元素, 所以可以使用directive, 插入canvas
@Directive({selector: 'appTooltip'})
class TooltipDirective {
@HostBinder('mouseOver', 'event.target')
public onMouseOver(event) {
const canvas = document.createElement('canvas');
event.appendChild(canvas);
canvas.id = 'myCanvas';
canvas.width = '300';
canvas.height = '300';
const chart = this.drawchart();
chart.draw();
}
private drawchart(){
const ctx = document.getElementById('myCanvas').getContext('2d');
const Circle = (options) =>{
this.ctx = options.ctx;
this.draw = () => {
this.ctx.save();
this.ctx.fillRect(0,0,100,100);
this.ctx.restore();
}
}
const circle = new Circle({ctx});
return circle;
}
}
c. <div title='ss'></div>
4) 如何加入动画?
react automation
浙公网安备 33010602011771号