<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://cdn.jsdelivr.net/npm/d3@5.9.2/dist/d3.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.15.0/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/tooltip.js@1.3.2/dist/umd/tooltip.min.js"></script>
</head>
<body>
<!--
Shapes (d3-shape)
可视化基本图元
Arcs
圆形或环形,在饼图或者环形图中用到
d3.arc - 创建一个环生成器.
arc - 根据指定的数据生成环.
arc.centroid - 计算环的中心点.
arc.innerRadius - 设置环的内半径.
arc.outerRadius - 设置环的外半径.
arc.cornerRadius - 设置拐角半径.
arc.startAngle - 设置起始角度.
arc.endAngle - 设置终止角度.
arc.padAngle - 设置相邻两个环之间的间隙角度.
arc.padRadius - 设置半径间隔.
arc.context - 设置渲染上下文.
Pies
将一组表格数据转换成生成饼图或者环形图需要的数据
d3.pie - 创建一个新的饼图生成器.
pie - 根据指定的数据计算每条数据对应环形的角度.
pie.value - 设置值访问器.
pie.sort - 设置排序比较器.
pie.sortValues - 设置排序比较器.
pie.startAngle - 设置所有环形的起始角度.
pie.endAngle - 设置所有环形的终止角度.
pie.padAngle - 设置相邻两个环之间的间隙角度.
Lines
曲线或折线,在折线图中使用.
d3.line - 创建一个新的线条生成器.
line - 根据指定的数据集生成一条线.
line.x - 设置线条生成器的 x-访问器.
line.y - 设置线条生成器的 y-访问器.
line.defined - 设置 defined(缺省) 访问器.
line.curve - 设置插值方式.
line.context - 设置渲染上下文.
d3.radialLine - 创建一个新的放射线条生成器.
radialLine - 根据指定的数据集生成一条线.
radialLine.angle - 设置角度访问器.
radialLine.radius - 设置半径访问器.
radialLine.defined - 设置 defined(缺省) 访问器.
radialLine.curve - 设置插值方式.
radialLine.context - 设置渲染上下文.
Areas
由基线和顶线围成的一块区域,在面积图中使用.
d3.area - 创建一个新的区域生成器.
area - 根据指定的数据集生成一个区域.
area.x - 设置 x0 和 x1 访问器.
area.x0 - 设置基线 x 访问器.
area.x1 - 设置顶线 x 访问器.
area.y - 设置 y0 和 y1 访问器.
area.y0 - 设置基线 y 访问器.
area.y1 - 设置顶线 y 访问器.
area.defined - 设置 defined(缺省) 访问器.
area.curve - 设置曲线插值方式.
area.context - 设置渲染上下文.
area.lineX0 - 派生出一条区域左侧边界线条生成器.
area.lineX1 - 派生出一条区域右侧边界线条生成器.
area.lineY0 - 派生出一条区域顶部边界线条生成器.
area.lineY1 - 派生出一条区域底部边界线条生成器.
d3.radialArea - 创建一个新的径向区域生成器.
radialArea - 根据指定的数据集生成一个区域.
radialArea.angle - 设置起止角度访问器.
radialArea.startAngle - 设置起始角度访问器.
radialArea.endAngle - 设置终止角度访问器.
radialArea.radius - 设置内外半径访问器.
radialArea.innerRadius - 设置内半径访问器.
radialArea.outerRadius - 设置外半径访问器.
radialArea.defined - 设置 defined 访问器.
radialArea.curve - 设置插值方式.
radialArea.context - 设置渲染上下文.
radialArea.lineStartAngle - 派生出一条区域起始角度边界线条生成器.
radialArea.lineEndAngle - 派生出一条区域终止角度边界线条生成器.
radialArea.lineInnerRadius - 派生出一条区域内半径边界线条生成器.
radialArea.lineOuterRadius - 派生出一条区域外半径边界线条生成器.
Curves
在一系列点之间进行插值,形成一条连续的线.
d3.curveBasis - 三次 basis 曲线.
d3.curveBasisClosed - 闭合的三次 basis 曲线.
d3.curveBasisOpen - 三次 basis 曲线.
d3.curveBundle - 可设置张力的三次 basis 曲线.
bundle.beta - 设置三次 basis 曲线的张力 beta.
d3.curveCardinal - 三次 cardinal 曲线.
d3.curveCardinalClosed - 闭合的三次 cardinal 曲线.
d3.curveCardinalOpen - 三次 cardinal 曲线.
cardinal.tension - 设置三次 cardinal 曲线的张力系数.
d3.curveCatmullRom - 三次 Catmull–Rom 曲线.
d3.curveCatmullRomClosed - 三次 Catmull–Rom 曲线.
d3.curveCatmullRomOpen - 三次 Catmull–Rom 曲线.
catmullRom.alpha - 设置三次 Catmull–Rom 曲线的 alpha 参数.
d3.curveLinear - 折线.
d3.curveLinearClosed - 闭合的折线.
d3.curveMonotoneX - 保持 x 单调性的三次曲线.
d3.curveMonotoneY - 保持 y 单调性的三次曲线.
d3.curveNatural - 自然三次样条曲线.
d3.curveStep - 分段常数函数.
d3.curveStepAfter - 分段常数函数.
d3.curveStepBefore - 分段常数函数.
curve.areaStart - 开始一个新的区域段.
curve.areaEnd - 结束当前的区域段.
curve.lineStart - 开始一个新的线段.
curve.lineEnd - 结束当前的线段end the current line segment.
curve.point - 为当前的线段中添加一个点.
Links
源点到目标点之间的圆滑三次 Bézier 曲线.
d3.linkVertical - 创建一个新的垂直 link 生成器.
d3.linkHorizontal - 创建一个新的水平的 link 生成器.
link - 生成一个 link.
link.source - 设置源点访问器.
link.target - 设置目标点访问器.
link.x - 设置点的 x-访问器.
link.y - 设置点的 y-访问器.
d3.linkRadial - 创建一个新的径向 link 生成器.
radialLink.angle - 设置点的 angle 访问器.
radialLink.radius - 设置点的 radius 访问器.
Symbols
分类形状编码,应用于散点图等场景中.
d3.symbol - 创建一个新的符号生成器.
symbol - 根据指定的数据生成一个符号.
symbol.type - 设置符号的类型.
symbol.size - 以平方像素为单位设置符号的大小.
symbol.context - 设置渲染上下文.
d3.symbols - 返回内置的符号类型数组.
d3.symbolCircle - 圆.
d3.symbolCross - 十字.
d3.symbolDiamond - 菱形.
d3.symbolSquare - 正方形.
d3.symbolStar - 五角星.
d3.symbolTriangle - 上三角.
d3.symbolWye - Y 符号.
symbolType.draw - 将符号绘制到指定的上下文中.
Stacks
堆叠图,堆叠面积、堆叠柱状图等.
d3.stack - 创建一个新的堆叠生成器.
stack - 根据给定数据集计算其堆叠图需要的各个属性.
stack.keys - 设置 keys 访问器.
stack.value - 设置 value 访问器.
stack.order - 设置排序访问器.
stack.offset - 设置偏移访问器.
d3.stackOrderAscending - 将和最小的值的序列放在底部.
d3.stackOrderDescending - 将和最大的值的序列放在底部.
d3.stackOrderInsideOut - 和越大越靠近中间.
d3.stackOrderNone - 使用原始数据的顺序不进行顺序调整.
d3.stackOrderReverse - 将原始数据顺序逆转.
d3.stackOffsetExpand - 将基线设置为 0 并且顶线为 1.
d3.stackOffsetDiverging - 正值在 0 之上,负值在 0 之下.
d3.stackOffsetNone - 使用 0 基线.
d3.stackOffsetSilhouette - 将流图以 0 为中心居中.
d3.stackOffsetWiggle - 最小化流图的摆动.
-->
<!--
d3.path - 创建一个新的路径序列化.
path.moveTo - 移动到指定的点.
path.closePath - 闭合当前子路径.
path.lineTo - 绘制直线.
path.quadraticCurveTo - 绘制二次 Bézier 曲线.
path.bezierCurveTo - 绘制三次 Bézier 曲线.
path.arcTo - 绘制弧线段.
path.arc - 绘制弧线段.
path.rect - 绘制矩形.
path.toString - 序列化为 SVG 路径字符串.
-->
<script>
/*圆形或环形,在饼图或者环形图中用到
d3.arc - 创建一个环生成器.
arc - 根据指定的数据生成环.
arc.centroid - 计算环的中心点.
arc.innerRadius - 设置环的内半径.
arc.outerRadius - 设置环的外半径.
arc.cornerRadius - 设置拐角半径.
arc.startAngle - 设置起始角度.
arc.endAngle - 设置终止角度.
arc.padAngle - 设置相邻两个环之间的间隙角度.
arc.padRadius - 设置半径间隔.
arc.context - 设置渲染上下文.*/
function drawCircle(context) {
var arc = d3.arc().innerRadius(10).outerRadius(100).startAngle(0).endAngle(Math.PI* 2).context(context);
if (context) {
context.beginPath();
context.translate(250,250);
context.fillStyle = '#0f0';
arc();
context.fill();
}
return arc;
}
function drawPie2(context) {
var colors=['red','green','blue']
var arcs=d3.pie()([1,2,3]);
var arc = d3.arc()
.outerRadius(100)
.innerRadius(0)
.context(context);
if (context) {
context.translate(250,250);
arcs.forEach(function(v,i){
context.beginPath();
context.fillStyle =colors[i];
arc(v)
context.fill();
});
}
}
/*
Pies
将一组表格数据转换成生成饼图或者环形图需要的数据
d3.pie - 创建一个新的饼图生成器.
pie - 根据指定的数据计算每条数据对应环形的角度.
pie.value - 设置值访问器.
pie.sort - 设置排序比较器.
pie.sortValues - 设置排序比较器.
pie.startAngle - 设置所有环形的起始角度.
pie.endAngle - 设置所有环形的终止角度.
pie.padAngle - 设置相邻两个环之间的间隙角度.*/
function drawPie(x, y, radius, context) {
var data = [1, 1, 2, 3, 5, 8, 13];
var colors = [
"#1f77b4", "#ff7f0e", "#2ca02c", "#d62728", "#9467bd",
"#8c564b", "#e377c2", "#7f7f7f", "#bcbd22", "#17becf"
];
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0)
.context(context);
var dot = d3.symbol()
.context(context);
var pie = d3.pie();
var arcs = pie(data);
context.translate(x, y);
context.globalAlpha = 0.5;
arcs.forEach(function (d, i) {
context.beginPath();
arc(d);
context.fillStyle = colors[i];
context.fill();
});
context.globalAlpha = 1;
context.beginPath();
arcs.forEach(arc);
context.lineWidth = 1.5;
context.stroke();
context.beginPath();
arcs.forEach(function (d) {
var c = arc.centroid(d);
context.save();
context.translate(c[0], c[1]);
dot();
context.restore();
});
context.fillStyle = "#000";
context.fill();
}
function drawRect() {
var arc = d3.arc()
.innerRadius(0)
.outerRadius(100)
.startAngle(0)
.endAngle(Math.PI / 2);
}
function renderToCanvas() {
var canvas = d3.select('body').append('canvas').attr('width', 500).attr('height', 500)
var ctx = canvas.node().getContext('2d');
drawCircle(ctx);
// drawPie(250,250,150,ctx)
}
function pathToCanvasRender() {
var canvas = d3.select('body').append('canvas').attr('width', 500).attr('height', 500)
var ctx = canvas.node().getContext('2d');
ctx.beginPath();
ctx.fillStyle = 'red';
var path = d3.path();
//drawCircle(path);
path.rect(100, 100, 100, 100)
var p = new Path2D(path.toString());
ctx.fill(p);
}
function pathToSvgRender() {
var svg = d3.select('body').append('svg').attr('width', 500).attr('height', 500)
var path = d3.path();
//drawCircle(path);
path.rect(100, 100, 100, 100)
svg.append('path').attr('d', path.toString()).attr('fill', 'red')
}
function drawLine() {
var data = d3.range(40).map(function (i) {
return i % 5 ? { x: i / 39, y: (Math.sin(i / 3) + 2) / 4 } : null;
});
var margin = { top: 40, right: 40, bottom: 40, left: 40 },
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scaleLinear()
.range([0, width]);
var y = d3.scaleLinear()
.range([height, 0]);
var line = d3.line()
.defined(function (d) { return d; })
.x(function (d) { return x(d.x); })
.y(function (d) { return y(d.y); });
var svg = d3.select("body").append("svg")
.datum(data)
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
svg.append("g")
.attr("class", "axis axis--y")
.call(d3.axisLeft(y));
svg.append("path")
.attr("class", "line")
.attr("d", line);
svg.selectAll(".dot")
.data(data.filter(function (d) { return d; }))
.enter().append("circle")
.attr("class", "dot")
.attr("cx", line.x())
.attr("cy", line.y())
.attr("r", 3.5);
}
/**
* Symbols
分类形状编码,应用于散点图等场景中.
d3.symbol - 创建一个新的符号生成器.
symbol - 根据指定的数据生成一个符号.
symbol.type - 设置符号的类型.
symbol.size - 以平方像素为单位设置符号的大小.
symbol.context - 设置渲染上下文.
d3.symbols - 返回内置的符号类型数组.
d3.symbolCircle - 圆.
d3.symbolCross - 十字.
d3.symbolDiamond - 菱形.
d3.symbolSquare - 正方形.
d3.symbolStar - 五角星.
d3.symbolTriangle - 上三角.
d3.symbolWye - Y 符号.
symbolType.draw - 将符号绘制到指定的上下文中.
*/
function drawSymbol(context){
var b=d3.symbol().type(d3.symbolStar).size(200).context(context);
context.save();
context.translate(250,250);
context.beginPath();
context.fillStyle='red';
b();
// context.rect(0,0,50,50)
context.stroke();
context.fill();
context.restore();
}
function MathCosPaths(n,sx,sy,width,height,MathFn){
var points=[],yR=100,p=360*n;
for(var i=0;i<p;i+=1){
var x=sx+i*(width/p);
var y=sy+yR*MathFn(i/180*Math.PI);
points.push([x,y])
}
return points
}
function drawLine(ctx){
Math.csc = function csc(x) { if(x===0){ return 0} return 1 / Math.sin(x); } // 余割
Math.sec = function sec(x) { return 1 / Math.cos(x); } //正割
Math.cot = function cot(x) { if(x===0){ return 0;} return 1 / Math.tan(x); }// 余切
var line=d3.line().context(ctx);
line.x(function(v){
return v[0]
});
line.y(function(v){
return v[1];
})
line.defined(function(v){
return true;
});
var pw=0;
function draw(fn,i){
var color=d3.schemeCategory10[i];
var data=MathCosPaths(4,0,250,500,500,fn)
ctx.beginPath();
ctx.font='14px';
//ctx.textAlign = "left" || "right" || "center" || "start" || "end";
ctx.textAlign='left';
//ctx.textBaseline = "top" || "hanging" || "middle" || "alphabetic" || "ideographic" || "bottom";
ctx.textBaseline='middle';
//ctx.direction = "ltr" || "rtl" || "inherit";
ctx.direction='ltr';
var text=ctx.measureText(fn.name),tw=text.width;
ctx.fillStyle=color;
ctx.rect(pw,5,5,5)
ctx.fillText(fn.name,pw+8,5);
ctx.fill();
ctx.beginPath();
ctx.strokeStyle=color
line(data)
ctx.stroke();
pw+=tw+15;
}
[Math.sin,Math.cos,Math.tan,Math.sec,Math.csc,Math.cot].forEach(draw);
}
function drawlineRadial(ctx){
var data=drawlineRadial.data;
ctx.translate(250,250)
var lineRadial=d3.lineRadial();
lineRadial.context(ctx);
lineRadial.angle(function(d){
return d[0]
});
lineRadial.radius(function(d){
return d[1]
})
ctx.beginPath();
lineRadial(data);
ctx.closePath();
ctx.stroke();
}
// drawlineRadial.data=d3.zip(d3.range(0,Math.PI*2,Math.PI*2/36),d3.range(0,100,100/36).map(function(){
// return 50;
// }));
drawlineRadial.data=d3.zip(d3.ticks(0,Math.PI*2,3),d3.ticks(0,Math.PI*2,3).map(function(){
return 50;
}));
// drawlineRadial.data=[[0,100],[Math.PI/6,100],[Math.PI/5,100],[Math.PI/4,100],[Math.PI/3,100],[Math.PI/2,100],[Math.PI,100]];
drawlineRadial.svg=function(svg){
var data=drawlineRadial.data;
var lineRadial=d3.lineRadial();
lineRadial.angle(function(d){
return d[0]
});
lineRadial.radius(function(d){
return d[1]
})
svg.append('g').attr('transform','translate(250,250)').append('path').attr('fill','none').attr('stroke','#000').attr('d',lineRadial(data))
}
// 顺序从x1 y1 再倒序从x y
function drawArea(ctx){
var area=d3.area().context(ctx);
var x=area.x(function(v){
return v[2];
})
var y= area.y(function(v){
return v[3];
});
var x2=area.x1(function(v){
return v[0];
})
var y2= area.y1(function(v){
return v[1];
});
var data=[[100,100,200,150],[200,100,100,150]];
ctx.beginPath();
ctx.fillStyle='red';
// 当前存
area(data);
ctx.stroke();
// ctx.fill();
}
function drawAreaRadial(ctx){
var area=d3.areaRadial().context(ctx);
var x=area.startAngle(function(v){
return v[2];
})
var y= area.innerRadius(function(v){
return v[0];
});
var x2=area.endAngle(function(v){
return v[3];
})
var y2= area.outerRadius(function(v){
return v[1];
});
var data=d3.range(0,360,60).map(function(v,i,d){
// console.log(v)
return [10,100,0,i]
})
ctx.translate(250,250);
ctx.beginPath();
ctx.fillStyle='red';
// 当前存
area(data);
ctx.stroke();
//ctx.fill();
}
function drawCurves(ctx){
var line = d3.line().context(ctx)
.x(function(d) { return d[0]; })
.y(function(d) { return d[1]; });
function useCurve(){
var curve=d3.curveBasis(ctx);
curve.lineStart();
drawCurves.data.forEach(function(d){
curve.point(d[0],d[1])
})
curve.lineEnd();
}
function useCurve2(){
line.curve(d3.curveBasis)
line(drawCurves.data);
}
if(ctx instanceof CanvasRenderingContext2D){
// ctx.translate(0.5,0.5)
ctx.beginPath();
ctx.strokeStyle='#000';
ctx.lineWidth=1.5;
// line(drawCurves.data);
//useCurve();
useCurve2()
ctx.stroke();
}
return line;
}
drawCurves.data=[[0,250],[250,100],[500,250]];
drawCurves.svg=function(svg){
var line = d3.line().curve(d3.curveBundle.beta(0.5))
.x(function(d) { return d[0]; })
.y(function(d) { return d[1]; })
var data=drawCurves.data;
svg.append('g').append('path').attr('d',line(data)).attr('fill','none').attr('stroke','#000').attr('stroke-width',1)
}
function drawlinkVertical(ctx){
var data=drawlinkVertical.data;
var linkVertical=d3.linkVertical();
linkVertical.context(ctx);
linkVertical.x(function(d,i){
return d[0]
})
linkVertical.y(function(d,i){
return d[1]
})
ctx.beginPath();
linkVertical(data)
ctx.stroke();
}
drawlinkVertical.data={
source:[50,250],
target:[300,100]
}
drawlinkVertical.svg=function(svg){
var data=drawlinkVertical.data;
var linkVertical=d3.linkVertical();
linkVertical.x(function(d){
return d[0]
})
linkVertical.y(function(d){
return d[1];
})
svg.append('g').append('path').attr('d',linkVertical(data)).attr('fill','none').attr('stroke','#000').attr('stroke-width',1)
}
function drawStack(ctx){
}
drawStack.svg=function(svg){
var data=drawStack.data;
var names=["apples", "bananas", "cherries", "dates"]
var stack=d3.stack();
stack.keys(names)
.order(d3.stackOrderNone)
.offset(d3.stackOffsetNone);
var series=stack(data);
var months= data.map(d=>d.month);
var margin={bottom:50,top:20,left:20,right:20}
var width=500,height=500;
var colors = d3.scaleOrdinal()
.domain(series.map(d => d.key))
.range(d3.quantize(t => d3.interpolateSpectral(t * 0.8 + 0.1), series.length).reverse())
.unknown("#ccc")
function xAxis(ctx){
var g=ctx.append('g');
var scaleLinear=d3.scaleTime(); //d3.scaleLinear();
scaleLinear.domain([months[0],months[3]]);
//scaleLinear.range([30,width-30]);
scaleLinear.range([30,width-30])
var axisBottom=d3.axisBottom(scaleLinear);
// axisBottom.ticks(d3.timeMonth)
// axisBottom.ticks(months.length);
// axisBottom.ticks(function(v){
// console.log('tick',v);
// })
// axisBottom.tickValues(d3.timeDay.range(new Date(2019,5,1),new Date(),5));
axisBottom.tickValues(months);
axisBottom.tickFormat(function(v){
console.log(v)
return d3.timeFormat('%Y-%m-%d')(v);
// return d3.timeFormat('%Y-%m-%d')(months[v]);
});
g.attr("transform", `translate(0,${height - margin.bottom})`)
.call(axisBottom);
var seriesWrap=g.append('g');
seriesWrap.selectAll('g').data(series).join().append('g').selectAll('rect').data(function(d){
return d;
}).enter().append('rect').attr('width',10).attr('x',function(d){
return scaleLinear(d.data.month);
}).attr('height',function(d){
return d[1]/100;
}).attr('fill',function(){
return 'red'
})
}
var x,y;
function xAxis2(svg){
x = d3.scaleBand()
.domain(data.map(d => d.month))
.range([margin.left, width - margin.right])
.padding(0.1);
var g=svg.append('g')
g.attr("transform", `translate(0,${height - margin.bottom})`)
.call(d3.axisBottom(x).tickFormat(d3.timeFormat('%Y-%m-%d')).tickSizeOuter(0))
}
function yAxis(svg){
y = d3.scaleLinear()
.domain([0, d3.max(series, d => d3.max(d, d => d[1]))])
.rangeRound([height - margin.bottom, margin.top]);
var g=svg.append('g')
g.attr("transform", `translate(${margin.left},0)`)
.call(d3.axisLeft(y).ticks(null, "s"));
// .call(g => g.selectAll(".domain").remove())
}
var tooltip;
svg.call(xAxis2);
svg.call(yAxis);
svg.append("g")
.selectAll("g")
.data(series)
.join("g")
.attr("fill", d => colors(d.key))
.selectAll("rect")
.data(d => {
return d.map(i=>{
i.name=d.key;
return i;
});
})
.join("rect")
.attr("x", (d, i) =>{
// console.log(d3.timeFormat('%Y-%m-%d')(d.data.month))
return x(d.data.month)
})
.attr("y", d => y(d[1]))
.attr("height", d => y(d[0]) - y(d[1]))
.attr("width", x.bandwidth()).on('mouseenter',function(d,i){
var e=d3.event;
tooltip=new Tooltip(this, {
container:document.body
})
console.log(i);
tooltip.updateTitleContent("name:"+d.name+',日期:'+d3.timeFormat('%Y-%m-%d')(d.data.month))
tooltip.show();
}).on('mouseleave',function(){
tooltip.hide();
});
}
drawStack.data=[
{month: new Date(2019, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400},
{month: new Date(2019, 1, 1), apples: 1600, bananas: 1440, cherries: 960, dates: 400},
{month: new Date(2019, 2, 1), apples: 640, bananas: 960, cherries: 640, dates: 400},
{month: new Date(2019, 3, 1), apples: 320, bananas: 480, cherries: 640, dates: 400}
];
function renderCanvasByFn(fn,title=''){
var container = d3.select('body').append('div').style('display','inline-block').style('margin','5px')
container.append('h3').style('text-align','center').text(title)
var canvas=container.append('canvas').style('border','solid 1px #ddd').attr('width', 500).attr('height', 500)
var ctx = canvas.node().getContext('2d');
if(fn.svg){
renderSvgByFn(fn,title+'-svg')
}
fn(ctx);
}
function renderSvgByFn(fn,title=''){
var container = d3.select('body').append('div').style('display','inline-block').style('margin','5px')
container.append('h3').style('text-align','center').text(title)
var svg=container.append('svg').style('border','solid 1px #ddd').attr('width', 500).attr('height', 500)
if(fn.svg){
fn.svg(svg)
return;
}
svg.append('g').attr('transform','translate(250,250)').append('path').attr('d',fn()).attr('fill','red')
}
renderCanvasByFn(drawPie2,'pie')
renderCanvasByFn(drawCircle,'circle')
renderSvgByFn(drawCircle,'circle-svg')
renderCanvasByFn(drawSymbol,'symbol');
renderCanvasByFn(drawLine,'line')
renderCanvasByFn(drawlineRadial,'lineRadial')
renderCanvasByFn(drawArea,'area')
renderCanvasByFn(drawAreaRadial,'AreaRadial');
renderCanvasByFn(drawCurves,'Curves');
renderCanvasByFn(drawlinkVertical,'linkVertical')
renderCanvasByFn(drawStack,'stack')
</script>
</body>
</html>