交互式操作

第十一课 交互式操作

链接 原作者用的是d3.js v3版本写的,我在学习的过程中用的是v4版的库 ,所以把原作者的代码中涉及v3的部分替换为了v4的API。在这里非常感谢原作者十二月的咖啡馆无私的分享!

与图表的交互,指在图形元素上设置一个或多个监听器,当事件发生时,做出相应的反应。

image

什么是交互

交互,指的是用户输入了某种指令,程序接受到指令之后必须做出某种响应。对可视化图表来说,交互能使图表更加生动,能表现更多内容。例如,拖动图表中某些图形、鼠标滑到图形上出现提示框、用触屏放大或缩小图形等等。

用户用于交互的工具一般有三种:鼠标、键盘、触屏。

如何添加交互

对某一元素添加交互操作十分简单,代码如下:

var circle = svg.append("circle");

circle.on("click", function(){
    //在这里添加交互内容
});

这段代码在 SVG 中添加了一个圆,然后添加了一个监听器,是通过 on() 添加的。在 D3 中,每一个选择集都有 on() 函数,用于添加事件监听器。

on() 的第一个参数是监听的事件,第二个参数是监听到事件后响应的内容,第二个参数是一个函数。

鼠标常用的事件有:

  • click - 鼠标单击某元素时,相当于 mousedown 和 mouseup 组合在一起。
  • mouseover - 光标放在某元素上。
  • mouseout - 光标从某元素上移出来时。
  • mousemove - 鼠标被移动的时候。
  • mousedown - 鼠标按钮被按下。
  • mouseup - 鼠标按钮被松开。

注意:没有 dblclick 双击事件,要实现的话需要用click + 延迟判定 来模拟

键盘常用的事件有三个:

  • keydown - 当用户按下任意键时触发,按住不放会重复触发此事件。该事件不会区分字母的大小写,例如“A”和“a”被视为一致。
  • keypress - 当用户按下字符键(大小写字母、数字、加号、等号、回车等)时触发,按住不放会重复触发此事件。该事件区分字母的大小写。
  • keyup - 当用户释放键时触发,不区分字母的大小写。

触屏常用的事件有三个:

  • touchstart - 当触摸点被放在触摸屏上时。
  • touchmove - 当触摸点在触摸屏上移动时。
  • touchend - 当触摸点从触摸屏上拿开时。

当某个事件被监听到时,D3 会把当前的事件存到 d3.event 对象,里面保存了当前事件的各种参数,请大家好好参详。如果需要监听到事件后立刻输出该事件,可以添加一行代码:

circle.on("click", function(){
    console.log(d3.event);
});

带有交互的柱形图

第八课的部分代码修改成如下代码。

var rects = svg.selectAll(".MyRect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("class","MyRect")   //把类里的 fill 属性清空
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .attr("x", function(d,i){
            return xScale(i) + rectPadding/2;
        } )
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("width", xScale.rangeBand() - rectPadding )
        .attr("height", function(d){
            return height - padding.top - padding.bottom - yScale(d);
        })
        .attr("fill","steelblue")       //填充颜色不要写在CSS里
        .on("mouseover",function(d,i){
            d3.select(this)
                .attr("fill","yellow");
        })
        .on("mouseout",function(d,i){
            d3.select(this)
                .transition()
                .duration(500)
                .attr("fill","steelblue");
        });

这段代码添加了鼠标移入(mouseover),鼠标移出(mouseout)两个事件的监听器。监听器函数中都使用了 d3.select(this),表示选择当前的元素,this 是当前的元素,要改变响应事件的元素时这么写就好。

mouseover 监听器函数的内容为:将当前元素变为黄色

mouseout 监听器函数的内容为:缓慢地将元素变为原来的颜色(蓝色)

完整代码

<html>
<head>
    <meta charset="utf-8">
    <title>完整的柱形图</title>
</head>

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

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

    .MyRect {
    }

    .MyText {
        fill: white;
        text-anchor: middle;
    }
</style>

<body>
<script src="d3.js"></script>
<script>

    //画布大小
    var width = 400;
    var height = 400;

    //在 body 里添加一个 SVG 画布
    var svg = d3.select("body")
        .append("svg")
        .attr("width", width)
        .attr("height", height);

    //画布周边的空白
    var padding = {left:30, right:30, top:20, bottom:20};

    //定义一个数组
    var dataset = [10, 20, 30, 40, 33, 24, 12, 5];

    //x轴的比例尺
    var xScale = d3.scaleBand()
        .domain(d3.range(dataset.length))
        .range([0, width - padding.left - padding.right]);

    //y轴的比例尺
    var yScale = d3.scaleLinear()
        .domain([0,d3.max(dataset)])
        .range([height - padding.top - padding.bottom, 0]);

    //定义x轴
    var xAxis = d3.axisBottom(xScale);

    //定义y轴
    var yAxis = d3.axisLeft(yScale);

    //矩形之间的空白
    var rectPadding = 4;

    //添加矩形元素
    var rects = svg.selectAll(".MyRect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("class","MyRect")   //把类里的 fill 属性清空
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .attr("x", function(d,i){
            return xScale(i) + rectPadding/2;
        } )
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("width", xScale.bandwidth() - rectPadding )
        .attr("height", function(d){
            return height - padding.top - padding.bottom - yScale(d);
        })
        .attr("fill","#ff0f99")       //填充颜色不要写在CSS里
        .on("mouseover",function(d,i){
            console.log("MouseOver");
            d3.select(this)
                .attr("fill","yellow");
        })
        .on("click",function (d,i) {
            console.log("Click!");
        })
        .on("mouseout",function(d,i){
            console.log("MouseOut")
            d3.select(this)
                .transition()
                .duration(500)
                .attr("fill","#ff0f99");
        });


    //添加文字元素
    var texts = svg.selectAll(".MyText")
        .data(dataset)
        .enter()
        .append("text")
        .attr("class","MyText")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .attr("x", function(d,i){
            return xScale(i) + rectPadding/2;
        } )
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("dx",function(){
            return (xScale.bandwidth()- rectPadding)/2;
        })
        .attr("dy",function(d){
            return 20;
        })
        .text(function(d){
            return d;
        })
        .attr("y",function(d){
            var min = yScale.domain()[0];
            return yScale(min);
        })
        .transition()
        .delay(function(d,i){
            return i * 200;
        })
        .duration(2000)
        .ease(d3.easeBounce)
        .attr("y",function(d){
            return yScale(d);
        });

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

    //添加y轴
    svg.append("g")
        .attr("class","axis")
        .attr("transform","translate(" + padding.left + "," + padding.top + ")")
        .call(yAxis);

</script>
</body>
</html>
图片.png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  •   JavaScript 与 HTML 之间的交互是通过事件实现的。   事件,就是文档或浏览器窗口中发生的一些特...
    霜天晓阅读 8,922评论 1 11
  • 本节介绍各种常见的浏览器事件。 鼠标事件 鼠标事件指与鼠标相关的事件,主要有以下一些。 click 事件,dblc...
    许先生__阅读 7,662评论 0 4
  • 第3章 基本概念 3.1 语法 3.2 关键字和保留字 3.3 变量 3.4 数据类型 5种简单数据类型:Unde...
    RickCole阅读 10,734评论 0 21
  • 对集合的操作 关于d3.attr 一个可以处理很多情况的函数,当只传入一个参数时,如果是string,则返回该属性...
    陈坚生阅读 7,550评论 0 2

友情链接更多精彩内容