D3.js 入门教程 基础 详细 一步步来

码字不易—口水少来–有用请好评-打赏也行喔
为了初学者,本文尽量细致再细致,觉得太啰嗦的大牛绕过—-我膜拜您
需求:完整柱状图
备注:前奏选择器、比例尺、坐标轴等基础知识不在赘叙,下面会有相关链接;
推荐链接:别个的教程 https://blog.csdn.net/qq_34414916/article/details/80029352
正文开始:
本文旨在封装一个基于d3 多端适配的柱状图组件 所以大家看到的会是一个方法;
方法外壳:

MendegBar = (DataObject) => {
        //移动端适配 预计padding以及width、height会通过一个胶着方法,以此判断是否进行适配
        let { dom = "", height, width, padding = { top: 20, left: 20, bottom: 20, right: 20 } } = DataObject;
        if (dom === "") {
            console.log("dom不存在 !");
        }
        //padding:图表分组位置参数
        //没有传入height时便获取dom的宽高
        height ? null : height = d3.select(dom).node().getBoundingClientRect().height;
        width ? null : width = d3.select(dom).node().getBoundingClientRect().width;
    }

首先需要画布,也就是即将展现数据的地方(区域),推荐使用svg

 //新建画布
        let svg = d3
            .select(dom)
            .append("svg")
            .attr("height", height)
            .attr("width", width)
            .style("background", "#fff");

有了画布,我们得为以后的操作流出余地,也就是可能会出现一个画布好几个图表的情况发生,所以需要一个组,用来将我们的一个个图表装起来;

//定义一个装图表的分组并且确定他的位置
        svg.append("g").attr("transform", "translate(" + padding.top + "," + padding.left + ")").attr("background", "skyblue");

数据,为方便学习,此处数据并未提出方法外

 // 数据集
        let data = [100,200,50,20,400,80];

接下来就要考虑比例尺和坐标轴了 首先要明确一个概念 在d3中,比例尺有很多种,具体表现都是通过方法的 推荐一个常用比例尺的网站 https://segmentfault.com/a/1190000011006780

 //为xy轴添加坐标轴 该方法考虑抽出作为独立api d3.scaleBand() 序数比例尺 .domain()输入域 range() 输出域 
        // d3.range(0, 10, 1) 返回一个算数级数组  例如 [0,1,2,3.......9]  (开始,结束,分度)
        //此处为省略了 开始(0) 分度(1) 采取他们的默认值 (0,data.length,1)  d3.range(data.length) data.length为终止数 注意 生成序列并不包括 data.length
        // .rangeRound()设置比例尺的输出范围并四舍五入 
        // d3.scaleBand().domain(d3.range(data.length)).rangeRound([0,width-padding.left-padding.right])  
        // d3.scaleBand()比例尺的输入域是 [0,1,2,...,data,length-1] 输出域是 [0,500-20-20];
        // scaleBand()序数比例尺  scaleLinear()线性比例尺
        let xScale = d3.scaleBand()
            .domain(d3.range(data.length)).rangeRound([0, width - padding.left - padding.right]);
        // y轴输入域 [0,400] 输出域 [500-20-20,0]
        let yScale = d3.scaleLinear()
            .domain([0, d3.max(data)])
            .range([height - padding.top - padding.bottom, 0]);
        // 坐标轴
        //  .axisBottom(canshu) 创建向下的坐标轴 参数是比例尺 axisLeft向左的坐标轴 
        let xAxis = d3.axisBottom(xScale);
        let yAxis = d3.axisLeft(yScale);
        // 到这一步 柱状图的基本架子已经搭起来了,下面需要做的便是怎么把数据呈现了
         //将坐标轴组件加入当前图表分组
        g.append("g")
            .attr("transform", "translate(" + 0 + "," + (height - padding.top - padding.bottom) + ")")
            .call(xAxis);
        g.append("g")
            .attr("transform", "translate(0,0)")
            .call(yAxis);

下面一步便是将数据呈现,那么我们就需要svg里的各种标签组件上手了。

//首先 为每一个数据(一个矩形)创建一个分组组g 这里出现一个概念 enter() 这里的意思是根据数据补全g
        //本来g.selectAll(".rect") 是获取不到东西的 但是 .data(data).enter().append("g")以后 data有多少数据,我就给他补全多少g
        // 题外话:data()将数据绑定到选择集上 
        let g_s = g.selectAll(".rect")
            .data(data)
            .enter()
            .append("g");
        // console.log("神奇的enter",g_s);// 为了效果更明显  [g, g, g, g, g, g]

        // 现在正主来了 为数据画出一片天地 嘎嘎,就是矩形来着
        //科普一下 svg的基础哈 
        /*
            svg 预定义形状元素
            矩形 <rect>
            圆形 <circle>
            椭圆 <ellipse>
            线 <line>
            折线 <polyline>
            多边形 <polygon>
            路径 <path> 高大上 ,就是条线而已 可以设置开始和结束哟
            <text> 元素用于定义文本。
            rect 的属性:      
            rect 元素的 width 和 height 属性可定义矩形的高度和宽度
            style 属性用来定义 CSS 属性
            CSS 的 fill 属性定义矩形的填充颜色(rgb 值、颜色名或者十六进制值)
            CSS 的 stroke-width 属性定义矩形边框的宽度
            CSS 的 stroke 属性定义矩形边框的颜色
            x 属性定义矩形的左侧位置(例如,x="0" 定义矩形到浏览器窗口左侧的距离是 0px) 在这里呢就是坐标轴的位置 咱自己的坐标轴
            y 属性定义矩形的顶端位置(例如,y="0" 定义矩形到浏览器窗口顶端的距离是 0px)
            CSS 的 fill-opacity 属性定义填充颜色透明度(合法的范围是:0 - 1)
            CSS 的 stroke-opacity 属性定义笔触颜色的透明度(合法的范围是:0 - 1)
            CSS 的 opacity 属性定义整个元素的透明值(合法的范围是:0 - 1)

        */
        //这是每个矩形之间的距离
        let rectPadding = 30;
        g_s.append("rect")
            .attr("x", function (d, i) {
                // d 数据 单项数据 i 索引
                return xScale(i) + rectPadding / 2;
                // 这个意思还用我解释吗?还是解释一下吧,嘎嘎,我一定是个好老师
                // 每一个rect "x" 属性的值 都等于 处于x轴的刻度的值(等差数列喔)加上 每个矩形之间的距离的一半喔
                //   xScale(i) 2 78 154 .. 然后第一个的x轴位置是多少呢 那当然是2啦 不过咱们得有间距 所以得加上间距 然后呢还得砍掉一半
                // 别问我为什么,揍你
            })
            .attr("y", function (d) {
                return yScale(d);
                // 参照上面 强调依据 x y 相对于我们自己的坐标轴来的哈
            })
            .attr("width", function () {
                //科普一下哈 xScale.step() 这个得到的是每一个等差刻度的宽喔 这里是 76
                //所以下面为什么会这么return 不用我再多说了吧
                return xScale.step() - rectPadding;
            })
            .attr("height", function (d) {
                console.log(d, yScale(400));
                //这个呢,能看明白不 设置高 算了 为防止一些yt看不明白 小说一下
                //总高度 - 上下空白 -  yScale(d)(数据d时,y轴的输出是多少)
                //回顾y轴比例尺 [height - padding.top - padding.bottom, 0] 倒着来的喔
                // 所以d越大,对应在y轴的值就越小  400 时 yScale(400)//0 
                //明白不,再不明白趴着让我打屁屁就明白了 嘿嘿
                return height - padding.top - padding.bottom - yScale(d);
            })
            .attr("fill", "skyblue");//这个呢就是矩形颜色的干活 (最近看个抗日剧、那剧情......)


        //最后 给每个矩形加上文字 
        /*
            <text> 元素用于定义文本。
            属性:
            主要属性有:x,y,dx,dy,rotate,textLength,lengthAdjust
            x,y表示文本的横纵坐标。
            dx,dy表示移动的横纵坐标。
            rotate表示旋转的度数。
        */
        //下面的运算不在解释
        g_s.append("text")
            .attr("x", function (d, i) {
                return xScale(i) + rectPadding / 2;
            })
            .attr("y", function (d) {
                return yScale(d);
            })
            .attr("dx", function () {
                (xScale.step() - rectPadding) / 2;
            })
            .attr("dy", 20)
            .text(function (d) {
                return d;
            })

至此一个完整的柱状图就已经完成了,下篇文章就是图标交互了,敬请期待。。。。。

猜你喜欢

转载自blog.csdn.net/Mendege/article/details/81703027