码迷,mamicode.com
首页 > 其他好文 > 详细

d3 基础折现图和饼图

时间:2019-06-13 00:57:13      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:add   set   pre   join   dom   onload   img   range   lin   

折线图

折现图可以使用svg折线元素polyline来定义一组相连的直线段,但是更推荐使用d3.line()path元素组合使用,这样更加灵活。

  • d3.line()构造一个新的线生成器,使用默认的.x.y设置x,y访问器函数。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>

    <body>
        <div id="test-svg">
        </div>
    </body>
    <script src="https://d3js.org/d3.v5.js"></script>
    <script>
        window.onload = function() {

            // 数据
            var data = [{
                date: new Date(2019, 3, 24),
                value: 23.24
            }, {
                date: new Date(2019, 3, 25),
                value: 72.15
            }, {
                date: new Date(2019, 3, 26),
                value: 38.84
            }, {
                date: new Date(2019, 3, 27),
                value: 58.62
            }, {
                date: new Date(2019, 3, 30),
                value: 10.80
            }, {
                date: new Date(2019, 4, 1),
                value: 85.47
            }];
            
            var width = 800,
                height = 400,
                padding = {
                    top: 40,
                    right: 40,
                    bottom: 40,
                    left: 40
                };
            var colors = d3.schemeSet2;
            var svg = d3.select("#test-svg")
                .append('svg')
                .attr('width', width + 'px')
                .attr('height', height + 'px');

            // x轴:时间轴
            var xScale = d3.scaleTime()
                .domain(d3.extent(data, function(d) {
                    return d.date;
                }))
                .range([padding.left, width - padding.right]);
            var xAxis = d3.axisBottom()
                .scale(xScale)
                .tickSize(10);
            svg.append('g')
                .call(xAxis)
                .attr("transform", "translate(0," + (height - padding.bottom) + ")")
                .selectAll("text")
                .attr("font-size", "10px")
                .attr("dx", "50px");

            // y轴
            var yScale = d3.scaleLinear()
                .domain([0, d3.max(data, function(d) {
                    return d.value;
                })])
                .range([height - padding.bottom, padding.top]);
            var yAxis = d3.axisLeft()
                .scale(yScale)
                .ticks(10);
            svg.append('g')
                .call(yAxis)
                .attr("transform", "translate(" + padding.left + ",0)");

            var line = d3.line()
                .x(function(d) {
                    return xScale(d.date);
                })
                .y(function(d) {
                    return yScale(d.value);
                });

            // 生成折线
            svg.append("path")
                .datum(data)
                .attr("fill", "none")
                .attr("stroke", "steelblue")
                .attr("stroke-width", 1.5)
                .attr("stroke-linejoin", "round")
                .attr("stroke-linecap", "round")
                .attr("d", line);
        }
    </script>

</html>

技术图片

stroke-linecap

  • 路径两端的形状。

  • 属性值:butt | round | square | inherit

技术图片

stroke-linejoin

  • 路径的转角处使用的形状

  • 属性值:miter | round | bevel | inherit

技术图片

饼图

  • 饼图一般使用饼布局d3.pie()和弧线生成器d3.arc()来绘制。

饼布局d3.pie()


 // 生成饼布局
            var pie = d3.pie().value(function(d) {
                return d.value;
            })(data);
  • startAngle:弧起始角度(角度跨度默认为2π ≈6.283185307179586)

  • endAngle:弧结束角度

  • padAngle:弧之间的间隔

  • value:数值

技术图片

弧线生成器d3.arc()

一般来说有四种情况:

1) 圆形:内圆半径为0,外圆半径大于0,且圆的弧度大于等于2π。会生成一个以外圆半径为半径的圆

2) 扇形:内圆半径为0,外圆半径大于0,且圆的弧度小于2π。会生成一个以外圆半径为半径的扇形

3) 环形:内圆半径大于0,外圆半径大于0,且圆的弧度大于等于2π。会生成一个环形

4) 环形扇区:内圆半径大于0,外圆半径大于0,且圆的弧度小于2π。会生成一个环形扇区

圆形饼图


<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>

    <body>
        <div id="test-svg">
        </div>
    </body>
    <script src="https://d3js.org/d3.v5.js"></script>
    <script>
        window.onload = function() {

            // 数据
            var data = [{
                value: 335,
                name: '直接访问'
            }, {
                value: 310,
                name: '邮件营销'
            }, {
                value: 234,
                name: '联盟广告'
            }, {
                value: 135,
                name: '视频广告'
            }, {
                value: 1548,
                name: '搜索引擎'
            }];
            var width = 400,
                height = 400,
                padding = {
                    top: 40,
                    right: 40,
                    bottom: 40,
                    left: 40
                };
                
            var colors = d3.schemeSet2;
            var svg = d3.select("#test-svg")
                .append('svg')
                .attr('width', (width * 2) + 'px')
                .attr('height', (height * 2) + 'px');
                
            // 生成饼布局
            var pie = d3.pie().value(function(d) {
                return d.value;
            })(data);

            var radius = Math.min(width, height);
            
            /*
             * 弧线生成器
             * .innerRadius 内圆半径
             * .outerRadius 外圆半径
             * .centroid 计算弧的中心
             */
            var arc = d3.arc()
                .innerRadius(0)
                .outerRadius(radius / 2);
            
            // 一个更大的圆弧,用来获取标注线外圈的坐标
            var outArc = d3.arc()
                .innerRadius(radius / 2)
                .outerRadius(radius);
                
            var line = d3.line()
                .x(function(d) {
                    return d[0];
                })
                .y(function(d) {
                    return d[1];
                });
            
            // 获取标注线的点数据
            var getLabelLine = function(d, type) {
                var startPos = d.startAngle + (d.endAngle - d.startAngle) / 2;
                var data = [];
                var ra = (type === "text") ? 2.5 : 1;
                data.push(arc.centroid(d));
                data.push(outArc.centroid(d));
                data.push({
                    0: outArc.centroid(d)[0] + (40 * (startPos < Math.PI ? 1 : -ra)),
                    1: outArc.centroid(d)[1]
                });

                return data;
            }
            
            var containers = svg.append("g")
                .attr("transform", "translate(" + height + "," + height + ")");
                
            var container = containers.selectAll("g")
                .data(pie)
                .join("g");
            
            // 绘制饼图
            container.append("path")
                .attr("stroke", "white")
                .attr("d", arc)
                .attr("fill", function(d, i) {
                    return colors[i];
                });
            
            // 绘制标注线
            container.append("path")
                .datum(function(d) {
                    return getLabelLine(d, "path");
                })
                .attr("class", "tips")
                .attr("fill", "none")
                .attr("stroke", "steelblue")
                .attr("stroke-width", 1)
                .attr("stroke-linejoin", "round")
                .attr("stroke-linecap", "round")
                .attr("d", line);
            
            // 绘制标注线上文字
            container.append("text")
                .datum(function(d) {
                    d.pos = getLabelLine(d, "text")[2];
                    return d;
                })
                .text(function(d) {
                    return d.data.name;
                })
                .attr("dx", function(d) {
                    return d.pos[0]
                })
                .attr("dy", function(d) {
                    return d.pos[1]
                });
        }
    </script>

</html>

技术图片

扇形饼图


var pie = d3.pie().startAngle(0).endAngle(Math.PI).value(function(d) {
                return d.value;
            })(data);

            var radius = Math.min(width, height);
            
            var arc = d3.arc()
                .innerRadius(0)
                .outerRadius(radius / 2);

技术图片

环形饼图


var pie = d3.pie().value(function(d) {
                return d.value;
            })(data);

            var radius = Math.min(width, height);
            
            var arc = d3.arc()
                .innerRadius(radius / 4)
                .outerRadius(radius / 2);

技术图片

环形扇区饼图


var pie = d3.pie().startAngle(0).endAngle(Math.PI).value(function(d) {
                return d.value;
            })(data);

            var radius = Math.min(width, height);
            
            var arc = d3.arc()
                .innerRadius(radius / 4)
                .outerRadius(radius / 2);

技术图片

d3 基础折现图和饼图

标签:add   set   pre   join   dom   onload   img   range   lin   

原文地址:https://www.cnblogs.com/chenjy1225/p/11013474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!