# d3画布

第一个图

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			*{margin:0;padding:0}
			#k{
				border:1px solid red
			}
		</style>
		 <script src="https://d3js.org/d3.v6.min.js"></script>  
	</head>
	<body>
		
		<div id="k"></div>
		<script type="text/javascript">
			let k=d3.select("#k")
			let svg=k.append("svg")
			.attr("width",300)
			.attr("height",300)
			.append("g")
			.attr("transform","translate(10,10)")
			.append("rect")
			.attr("x",50)
			.attr("width",20)
			.attr("height",30)
		console.log(svg)
		</script>
	</body>
</html>

# 使用d3绘制圆+矩形+椭圆+文字

  • 圆:圆心坐标(cx,cy),半径r
  • 矩形:起点坐标(x,y) 宽width 高height rx控制(border-radius)
  • 椭圆:椭圆中心坐标(cx,cy) x轴半径rx y轴半径ry
  • 文字: 起点坐标(x,y) 偏移dx 偏移dy
  • 直线:x1 y1 x2 y2
  • 多边形: points
	let svg =d3.select("body").append("svg")
		.attr("width",300)
		.attr("height",300)
		.style("border","1px solid red")
		
	svg.append("circle")
		.attr("cx",20)
		.attr("cy",20)
		.attr("r",20)
		.style("fill",'red')
	
	svg.append("rect")
		.attr("x",50)
		.attr("y",10)
		.attr("width",50)
		.attr("height",30)
		.style("fill",'purple')
	
	svg.append("ellipse")
		.attr("cx",200)
		.attr("cy",100)
		.attr("rx",50)
		.attr("ry",20)
		.style("fill",'orange')
		
	svg.append("text")
	 .text(d=>d)
	 .style("font-size",30)
	 .attr("x",(x,i)=>{
			console.log(x,i)
			return i*60+10
		})
	  .attr("y",y=>y)
	  .attr("dy",10)
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Simple Shapes</title>
    <link rel="stylesheet" type="text/css" href="../../css/styles.css"/>
    <script type = "text/javascript" src = "https://d3js.org/d3.v6.min.js"></script>

    <style>
        svg line{
            stroke: grey;
            stroke-width: 2;
        }

        svg circle{
            stroke: red;
            fill: none;
            stroke-width: 2;
        }

        svg rect{
            stroke: steelblue;
            fill: none;
            stroke-width: 2;
        }

        svg polygon{
            stroke: green;
            fill: none;
            stroke-width: 2;
        }
    </style>
</head>

<body>

<script type="text/javascript">
    var width = 600,
        height = 500;
        
    var svg = d3.select("body").append("svg");
    
    svg.attr("height", height)
        .attr("width", width);    
        
    svg.append("line") // <-A
        .attr("x1", 0)
        .attr("y1", 200)
        .attr("x2", 100)
        .attr("y2", 100);
        
    svg.append("circle") // <-B
        .attr("cx", 200)
        .attr("cy", 150)
        .attr("r", 50);
        
    svg.append("rect")
        .attr("x", 300) // <-C
        .attr("y", 100)
        .attr("width", 100) // <-D
        .attr("height", 100)
        .attr("rx", 5); // <-E
        
    svg.append("polygon")
        .attr("points", "450,200 500,100 550,200"); // <-F
</script>

</body>

</html>

# d3.area区域生成器

d3.area().x([x]).y0([y]).y1([y])

d3.area 可以生成一个图形生成器,输入一个数组数据,将返回值传入 path 元素的 d 属性就可以渲染出对应的 area 图形。

注意:data需要是二维数组,如果不是写成[data]这种形式作为参数

	svg.append("path")
	  .data(data)
	  .attr("fill", "#cce5df")
	  .attr("stroke", "#69b3a2")
	  .attr("stroke-width", 1.5)
	  .attr("d", d3.area()
	    .x(function(d) { return funx(d.date) })
	    .y0(y(0))
	    .y1(function(d) { return funy(d.value) })
	   )
	   //funx和funy是两个方向的比例尺
  var area = d3.area() // <-C
            .x(function(d) { return x(d.x); }) // <-D
            .y0(y(0)) // <-E
            .y1(function(d) { return y(d.y); }); // <-F
            
	svg.selectAll("path.area") // <-G
			.data([data])
		.enter()
			.append("path")
			.attr("class", "area")
			.style("fill","green")
			.attr("d", function(d){return area(d);})
				

# d3.area 断面曲线

同d3.line的curve曲线一样,tension也一样

  var area = d3.area()
            .x(function(d) { return x(d.x); })
            .y0(y(0))
            .y1(function(d) { return y(d.y); })
            .curve(d3.curveCardinal.tension(1)); // <-B

# d3.symbol创建散点图

	
  let _data = [];
	
  _symbolTypes = d3.scaleOrdinal() // <-A
          .range([d3.symbolCircle,
               d3.symbolCross,
               d3.symbolDiamond,
              d3.symbolSquare,
              d3.symbolStar,
              d3.symbolTriangle,
              d3.symbolWye
          ]);

  function renderSymbols() { // <-B
            _data.forEach(function (list, i) {
                var symbols = _bodyG.selectAll("path._" + i)
                        .data(list);

                symbols.enter()
                        .append("path")
                    .merge(symbols)
                        .attr("class", "symbol _" + i)
                        .classed(_symbolTypes(i), true)
                    .transition() // <-C
                        .attr("transform", function(d){
                            return "translate(" // <-D
                                    + _x(d.x)
                                    + ","
                                    + _y(d.y)
                                    + ")";
                        })
                        .attr("d",
                            d3.symbol() // <-E
                                .type(_symbolTypes(i))
                        );
            });
        }

# d3.stack堆栈图

var stack = d3.stack() // <-A
                .keys(['value1', 'value2', 'value3'])
                .offset(d3.stackOffsetNone);
		
		console.log(_data)
        var series = stack(_data); //<-B
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Stacked Area Chart</title>
    <link rel="stylesheet" type="text/css" href="../../css/styles.css"/>
    <script type = "text/javascript" src = "https://d3js.org/d3.v6.min.js"></script>
</head>

<body>

<script type="text/javascript">
function stackedAreaChart() {
    var _chart = {};

    var _width = 900, _height = 450,
            _margins = {top: 30, left: 30, right: 30, bottom: 30},
            _x, _y,
            _data = [],
            _colors = d3.scaleOrdinal(d3.schemeCategory10),
            _svg,
            _bodyG,
            _line;

    _chart.render = function () {
        if (!_svg) {
            _svg = d3.select("body").append("svg")
                    .attr("height", _height)
                    .attr("width", _width);

            renderAxes(_svg);

            defineBodyClip(_svg);
        }

        renderBody(_svg);
    };

    function renderAxes(svg) {
        var axesG = svg.append("g")
                .attr("class", "axes");

        renderXAxis(axesG);

        renderYAxis(axesG);
    }

    function renderXAxis(axesG) {
        var xAxis = d3.axisBottom()
                .scale(_x.range([0, quadrantWidth()]));

        axesG.append("g")
                .attr("class", "x axis")
                .attr("transform", function () {
                    return "translate(" + xStart() + "," + yStart() + ")";
                })
                .call(xAxis);

        d3.selectAll("g.x g.tick")
                .append("line")
                .classed("grid-line", true)
                .attr("x1", 0)
                .attr("y1", 0)
                .attr("x2", 0)
                .attr("y2", -quadrantHeight());
    }

    function renderYAxis(axesG) {
        var yAxis = d3.axisLeft()
                .scale(_y.range([quadrantHeight(), 0]));

        axesG.append("g")
                .attr("class", "y axis")
                .attr("transform", function () {
                    return "translate(" + xStart() + "," + yEnd() + ")";
                })
                .call(yAxis);

        d3.selectAll("g.y g.tick")
                .append("line")
                .classed("grid-line", true)
                .attr("x1", 0)
                .attr("y1", 0)
                .attr("x2", quadrantWidth())
                .attr("y2", 0);
    }

    function defineBodyClip(svg) {
        var padding = 5;

        svg.append("defs")
                .append("clipPath")
                .attr("id", "body-clip")
                .append("rect")
                .attr("x", 0 - padding)
                .attr("y", 0)
                .attr("width", quadrantWidth() + 2 * padding)
                .attr("height", quadrantHeight());
    }

    function renderBody(svg) {
        if (!_bodyG)
            _bodyG = svg.append("g")
                    .attr("class", "body")
                    .attr("transform", "translate("
                            + xStart() + ","
                            + yEnd() + ")")
                    .attr("clip-path", "url(#body-clip)");
		console.log(d3.stackOffsetNone)
        var stack = d3.stack() // <-A
                .keys(['value1', 'value2', 'value3'])
                .offset(d3.stackOffsetNone);
		
		console.log(_data)
        var series = stack(_data); //<-B
		console.log(series)
        renderLines(series);

        renderAreas(series);
    }

    function renderLines(series) {
        _line = d3.line()
                .x(function (d, i) {
                    return _x(i); //<-C
                })
                .y(function (d) {
                    return _y(d[1]); //<-D
                });

        var linePaths = _bodyG.selectAll("path.line")
                .data(series);

        linePaths.enter()
                .append("path")
            .merge(linePaths)
                .style("stroke", function (d, i) {
                    return _colors(i);
                })
                .attr("class", "line")
            .transition()
                .attr("d", function (d) {
                    return _line(d);
                });
    }

    function renderAreas(series) {
		console.log(series)
        var area = d3.area()
                .x(function (d, i) {
                    return _x(i); //<-E
                })
                .y0(function(d){return _y(d[0]);}) //<-F
                .y1(function (d) {
                    return _y(d[1]); //<-G
                });

        var areaPaths = _bodyG.selectAll("path.area")
                .data(series);

        areaPaths.enter()
                .append("path")
            .merge(areaPaths)
                .style("fill", function (d, i) {
                    return _colors(i);
                })
                .attr("class", "area")
            .transition()
                .attr("d", function (d) {
                    return area(d);
                });
    }

    function xStart() {
        return _margins.left;
    }

    function yStart() {
        return _height - _margins.bottom;
    }

    function xEnd() {
        return _width - _margins.right;
    }

    function yEnd() {
        return _margins.top;
    }

    function quadrantWidth() {
        return _width - _margins.left - _margins.right;
    }

    function quadrantHeight() {
        return _height - _margins.top - _margins.bottom;
    }

    _chart.width = function (w) {
        if (!arguments.length) return _width;
        _width = w;
        return _chart;
    };

    _chart.height = function (h) {
        if (!arguments.length) return _height;
        _height = h;
        return _chart;
    };

    _chart.margins = function (m) {
        if (!arguments.length) return _margins;
        _margins = m;
        return _chart;
    };

    _chart.colors = function (c) {
        if (!arguments.length) return _colors;
        _colors = c;
        return _chart;
    };

    _chart.x = function (x) {
        if (!arguments.length) return _x;
        _x = x;
        return _chart;
    };

    _chart.y = function (y) {
        if (!arguments.length) return _y;
        _y = y;
        return _chart;
    };

    _chart.data = function (data) {
        if (!arguments.length) return _data;
        _data = data;
        return _chart;
    };

    return _chart;
}

function randomData() {
    return Math.random() * 9;
}

function update() {
    data = d3.range(numberOfDataPoint).map(function (i) {
        return {value1: randomData(), value2: randomData(), value3: randomData()};
    });

    chart.data(data).render();
}

var numberOfDataPoint = 51,
        data = [];

var chart = stackedAreaChart()
        .x(d3.scaleLinear().domain([0, numberOfDataPoint - 1]))
        .y(d3.scaleLinear().domain([0, 26]));

update();
</script>

<div class="control-group">
    <button onclick="update()">Update</button>
</div>

</body>

</html>
最后更新: 2/25/2021, 4:50:50 PM