D3画完整柱状图(带坐标轴、标签)

Wesley13
• 阅读 508

   昨天晚上本来打算花一点时间把之前学的柱状图改一下,用CSV文件来替换自定义数据。这一替换可不得了,一晚上就搭进去了,还好今早找到了问题的所在,原因在于我的数据引用出了问题。

现在就来讲解一下如何画一个柱状图吧:

  柱状图的画法和折线图其实很类似,只要掌握了比例尺的用法和坐标轴的画法,我们只要在此基础上添加“rect”元素添加矩形就可以了,但这其中也有一些要点,我会在其中标出,希望对你有用。

  对于d3不同版本带来的代码不适用的解决办法:1)、下载对应的v3或者v4版本加到代码引用里可以解决。

                       2)、对于我博客的代码,只要你确保网络畅通,应该不会出错

<!DOCTYPE html>
<html>
  <head>  <meta charset="utf-8">
  <title>文档的标题</title>
</head>
<body>
<script src="https://cdn.bootcss.com/d3/3.5.15/d3.js"></script>//网页引用d3库
</body>
</html>

好了,接下来就是完整代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>绘制图形</title>
    </head>
    <style>
        /* 给body添加大小 */
        body,
        html {
            height: 100%;
        }

            {
            padding: 0;
            margin: 0;
        }

        .axis path,
        .axis line {
            fill: none;
            stroke: black;
            shape-rendering: crispEdges;
        }

        .axis text {
            font-family: sans-serif;
            font-size: 11px;
        }

        .MyRect {
            fill: palevioletred;
        }

        .MyText {
            fill: black;
            text-anchor: middle;
            font-size: 10px;
        }
    </style>
    <body>
        <script src="https://cdn.bootcss.com/d3/3.5.15/d3.js"></script>
        <script>
            var width = 500;
            var height = 500;
            var svg = d3.select("body")
                .append("svg")
                .attr("width", width)
                .attr("height", height);
            var padding = {
                left: 30,
                right: 30,
                top: 20,
                bottom: 20
            };
            ////http://blog.sina.com.cn/s/blog_ad72a03a0102v1nx.html  含解释


            d3.csv("../bardata.csv", function(error, data, i) {
                if (error) {
                    console.log(error);
                }

                console.log(data);

                var datavalue = []
                for (let i = 0; i < data.length; i++) {
                    datavalue.push(data[i].value)
                }                   // var xp = d3.scale.ordinal()
                //         // .domain(d3.range(dataset.length))
                //         // 使用map来输入data数组中的字符
                //         .domain(data.map(function(d,i){
                //         //    console.log(d.items)
                //     return d.items
                // }))
                // .rangeRoundBands([0,width-padding.left-padding.right]);


                // var xp = d3.scale.ordinal()
                //     .domain(data.map(function(d){ return d.items;}))
                //     .rangeBands([0,width-padding.left-padding.right]);//以上定义xp(即xscale)横坐标序数比例尺的方法都可以试一下,会有不同的体验
                var xp = d3.scale.ordinal()
                    .domain(data.map(function(d) {
                        return d.items;
                    }))
                    .rangeRoundBands([0, width - padding.left - padding.right], 0.1);

                var yp = d3.scale.linear()
                    .domain([0, d3.max(datavalue)])
                    .range([height - padding.top - padding.bottom, 0]) //反过来?为什么呢(之前似乎讲过哦0w0)

                var xAxis = d3.svg.axis()
                    .scale(xp)
                    .orient("bottom");

                var yAxis = d3.svg.axis()
                    .scale(yp)
                    .orient("left");

                var rectPadding = 4;

                var rects = svg.selectAll(".MyRect")
                    .data(data)
                    .enter()
                    .append("rect")
                    .attr("class", "MyRect")
                    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
                    .attr("x", function(d, i) {
                       return xp(d.items);
                    })
                    .attr("y", function(d) {
                        return yp(d.value);
                    })
                    .attr("width", xp.rangeBand() - rectPadding)
                    .attr("height", function(d) {
                        return height - padding.top - padding.bottom - yp(d.value);
                    })
                    .on("mouseover", function(d, i) {
                        d3.select(this)
                            .style("fill", "aliceblue");
                    })
                    .on("mouseout", function(d, i) {
                        d3.select(this)
                            .style("fill", "greenyellow");
                        // 使用style替换attr才会有交互的效果
                    });
                var texts = svg.selectAll(".MyText")
                    .data(data) //害我出错的就是这儿了,我之前写的是.data(datavalue),datavalue又是哪儿来的呢?为什么引用错误,会导致tips的位置错乱呢?
                    .enter()
                    .append("text")
                    .attr("class", "MyText")
                    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
                    .attr("x", function(d) {
                        return xp(d.items);//上面问题的答案都在这儿,d=》data,数据的意思,那data是哪儿来的呢?当然是我们传进来的,那为什么data不会出错,而datavalue会错呢?//是由于xp()是我们之前定义的序数比例尺,我们如果想要使用就必须传入适合的数据(包含x,y),如果只是传入datavalue就只有y值,而我们并没有将x传入。
                    })
                    .attr("y", function(d) {
                        return yp(d.value);
                    })
                    .attr("dx", function() {
                        return (xp.rangeBand() - rectPadding) / 2;
                    })
                    .attr("dy", function(d) {
                        return 15;
                    })
                    .text(function(d) {
                        return d.value;
                    });

                svg.append("g")
                    .attr("class", "axis")
                    .attr("transform", "translate(" + padding.left + "," + (height - padding.bottom) + ")")
                    .call(xAxis);

                svg.append("g")
                    .attr("class", "axis")
                    .attr("transform", "translate(" + padding.left + "," + padding.top + ")")
                    .call(yAxis);
            })
        </script>
    </body>
</html>

老样子,好货沉底

javascript和D3

———————————————————————————————————————————————————————————————————

修改:由于浏览器的沙箱机制导致直接复制代码是没法直接运行的,所以贴出原码外加数据

链接:https://pan.baidu.com/s/13RhuYM9pz0WiFya0IcOrJQ
提取码:069a

一、最简单的方法是下载HbuiderX,然后导入文件,打开。(二不用看了)

二、在此如果你没有安装任何服务器,直接想用文件启动网页的化,你可以这样做:

1)、确保你的电脑上安装了Python(二或者三的版本都可以)

2)、 D3画完整柱状图(带坐标轴、标签)

在文件路径下打开cmd(上图最简,打开文件,输入cmd,回车ok)

3)、键入命令

Python2用这个

D3画完整柱状图(带坐标轴、标签)

4)、启动服务器

D3画完整柱状图(带坐标轴、标签)

5)、浏览器中输入:

D3画完整柱状图(带坐标轴、标签)

打开文件,结束。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Karen110 Karen110
3年前
​一篇文章总结一下Python库中关于时间的常见操作
前言本次来总结一下关于Python时间的相关操作,有一个有趣的问题。如果你的业务用不到时间相关的操作,你的业务基本上会一直用不到。但是如果你的业务一旦用到了时间操作,你就会发现,淦,到处都是时间操作。。。所以思来想去,还是总结一下吧,本次会采用类型注解方式。time包importtime时间戳从1970年1月1日00:00:00标准时区诞生到现在
Stella981 Stella981
3年前
JS 苹果手机日期显示NaN问题
问题描述newDate("2019122910:30:00")在IOS下显示为NaN原因分析带的日期IOS下存在兼容问题解决方法字符串替换letdateStr"2019122910:30:00";datedateStr.repl
Stella981 Stella981
3年前
Python之time模块的时间戳、时间字符串格式化与转换
Python处理时间和时间戳的内置模块就有time,和datetime两个,本文先说time模块。关于时间戳的几个概念时间戳,根据1970年1月1日00:00:00开始按秒计算的偏移量。时间元组(struct_time),包含9个元素。 time.struct_time(tm_y
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这