d3.js——给柱形图添加事件出现的问题总结

首先做出一个动态的柱形图(这儿用的d3.js的版本是v3,用v4的话有些函数会发生变化)

效果图:

代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>histogramTransitionEvent</title>
    <style>
        .axis path,
        .axis line{
            fill: none;
            stroke: black;
            shape-rendering: crispEdges;
        }

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

        .MyText {
            fill: white;
            text-anchor: middle;
        }
    </style>
</head>
<body>
<script src="d3.js"></script>
<script>
    //添加svg画布
    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.scale.ordinal()
    // 使用了d3.scale.ordinal() 它支持范围分档。与定量比例尺(如d3.scale.linear())返回连续的范围值不同,序数比例尺使用的是离散范围值,也就是输出值是事先就确定好的。
    // 映射范围时,可以使用range(),也可以使用rangeBands()。后者接收一个最小值和一个最大值,然后根据输入值域的长度自动将其切分成相等的块或“档”。0.2也就是档间距为每一档宽度的20%。
        .domain(d3.range(dataset.length))
        .rangeRoundBands([0,width-padding.left-padding.right]);
    //y轴的比例尺
    var yScale = d3.scale.linear()
        .domain([0,d3.max(dataset)])
        .range([height-padding.top-padding.bottom,0]);

    //定义坐标轴
    //定义x轴
    var xAxis = d3.svg.axis()
        .scale(xScale)
        .orient("bottom");
    //定义y轴
    var yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("left");

    //添加矩形和文字元素
    var rectPadding = 4;
    var rects = svg.selectAll(".MyRect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("class","MyRect")
        .attr("transform","translate("+padding.left+","+padding.top+")")
        .attr("x",function(d,i){
            return xScale(i)+rectPadding/2;
        })
        .attr("width",xScale.rangeBand()-rectPadding)
        .attr("y",function(d){
            var min = yScale.domain()[0];
            return yScale(min);
        })
        .attr("height", function(d){
            return 0;
        })
        .transition()
        .delay(function(d,i){
            return i * 200;
        })
        .duration(2000)
        .ease("bounce")
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("height",function(d){
            return height-padding.top-padding.bottom-yScale(d);
        })//console.log(width-padding.left-padding.right);
    //添加文字元素
    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){
            var min = yScale.domain()[0];
           // console.log(yScale(min));
            return yScale(min);
        })
        .transition()
        .delay(function(d,i){
            return i*200;
        })
        .duration(2000)
        .ease("bounce")
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("dx",function(){
            return (xScale.rangeBand()-rectPadding)/2;
        })
        .attr("dy",function(){
            return 20;
        })
        .text(function(d){
            return 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>

现在像个这个动态的柱形图添加mouseover和mouseout事件。

做法:

1.去掉style样式中的.MyText类,直接在添加矩形的时候添加颜色属性

2.在添加矩形的时候添加事件

...

//添加矩形和文字元素
    var rectPadding = 4;
    var rects = svg.selectAll(".MyRect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("class","MyRect")
        .attr("transform","translate("+padding.left+","+padding.top+")")
        .attr("x",function(d,i){
            return xScale(i)+rectPadding/2;
        })
        .attr("width",xScale.rangeBand()-rectPadding)

        .attr("y",function(d){
            var min = yScale.domain()[0];
            return yScale(min);
        })
        .attr("height", function(d){
            return 0;
        })
        .transition()
        .delay(function(d,i){
            return i * 200;
        })
        .duration(2000)
        .ease("bounce")
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("height",function(d){
            return height-padding.top-padding.bottom-yScale(d);
        })
        .attr("fill","steelblue")
        //添加事件
        .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");
        });

...

但是这样会报错,会显示on不是一个函数

后来知道应该把on事件放在transition()之前,但是为啥这么做可以现在还不知道

 ...

//添加矩形和文字元素
    var rectPadding = 4;
    var rects = svg.selectAll(".MyRect")
        .data(dataset)
        .enter()
        .append("rect")
        .attr("class","MyRect")
        .attr("transform","translate("+padding.left+","+padding.top+")")
        .attr("x",function(d,i){
            return xScale(i)+rectPadding/2;
        })
        .attr("width",xScale.rangeBand()-rectPadding)
        //添加事件在 transition()之前
        .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");
        })
        .attr("y",function(d){
            var min = yScale.domain()[0];
            return yScale(min);
        })
        .attr("height", function(d){
            return 0;
        })
        .transition()
        .delay(function(d,i){
            return i * 200;
        })
        .duration(2000)
        .ease("bounce")
        .attr("y",function(d){
            return yScale(d);
        })
        .attr("height",function(d){
            return height-padding.top-padding.bottom-yScale(d);
        })
        .attr("fill","steelblue");

...

最终效果图:

这里面矩形图的教程来源:http://d3.decembercafe.org/pages/lessons/9.html

时间: 2024-08-25 18:10:49

d3.js——给柱形图添加事件出现的问题总结的相关文章

[5] D3.js中如何添加坐标轴

本人的个人博客为: www.ourd3js.com csdn博客为: blog.csdn.net/lzhlzz 转载请注明出处,谢谢.      第3节中做了一个图标,但没有为它添加一个相应的坐标轴,这样不知道每一个柱形到底有多长.这一节做一个坐标轴. D3中的坐标轴都是以 svg 图的形式出现的,这也是为什么在第3节中要使用 svg 的方法做柱形图的原因.第4节里我们讲解了 scale (比例)的用法,在做坐标轴的时候也需要用到比例.第4节中,我们说到scale 是一个函数,这一节中的坐标轴也

原生js为元素添加事件

1.行间事件 onclick="函数名()"; <div id="div1" onmouseover="over('400px','400px','green')" onmouseout="over('200px','200px','red')" onclick="show()"></div> 2.js中加事件  设置函数,发生事件时才触发 匿名函数 obj.onmouseout=f

js 动态加载事件的几种方法总结

本篇文章主要是对js 动态加载事件的几种方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 有些时候需要动态加载javascript事件的一些方法往往我们需要在 JS 中动态添加事件,这就涉及到浏览器兼容性问题了,以下谈及的几种方法,我们也常常混合使用. 方法一.setAttributevar obj = document.getElementById("obj");obj.setAttribute("onclick", "javasc

js 添加事件 attachEvent 和 addEventListener 的用法

一般我们在JS中添加事件,是这样子的 obj.onclick=method 这种绑定事件的方式,兼容主流浏览器,但如果一个元素上添加多次同一事件呢? obj.onclick=method1; obj.onclick=method2; obj.onclick=method3; 如果这样写,那么只有最后绑定的事件,这里是method3会被执行,这个时候我们就不能用onclick这样的写法了,主角改登场了,在IE中我们可以使用attachEvent方法 //object.attachEvent(eve

js原生添加事件的方式

js原生添加事件的方式: 1. 直接在html标签上添加 <div onclick="alert('div')">div</div> 2. 用dom的on...方法添加 document.getElementById('div').onclick = function () {alert('div')}; 3. 用addEventListener或attachEvent添加 document.getElementById('div').addEventListe

js动态添加事件-事件委托

作者:白狼 出处:http://www.manks.top/javascript-dynamic-event.html 本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利. 其所谓的动态添加事件实质就是指js中的事件委托. 我们知道在js中,事件处理只能绑定在当前被选中的元素上,换句话也就是说,事件处理只能绑定在当前文档已经存在的元素上!但是,往往小伙伴们都会遇到一个问题就是,我的元素是后来动态添加到页面的,而我又想给该元素绑定

js添加事件、移除事件、阻止冒泡、阻止浏览器默认行为等写法(兼容IE/FF/CHROME)

网上有关这方面的代码比较多而乱,这里整理一下并加以改进. 添加事件 var addEvent = function( obj, type, fn ) { if (obj.addEventListener) obj.addEventListener( type, fn, false ); else if (obj.attachEvent) { obj["e"+type+fn] = fn; obj.attachEvent( "on"+type, function() {

【 D3.js 进阶系列 — 2.1 】 力学图的事件 + 顶点的固定

本章讨论在力学图中经常使用到的事件( Event ),然后对[p=555">进阶 - 第 2.0 章]的人物关系图进行改进.使用户可以固定拖拽的对象. 在[入门 - 第 9.2 章]和[进阶 - 第 2.0 章]中,都用到了下面代码: force.on("tick", function(){ }); 这里的 force 是之前代码中定义的布局( Layout ).tick 表示当运动进行中每更新一帧时. 这是力学图中最常使用的事件,用于设定力学图每一帧是怎样更新的.除此

深入理解js Dom事件机制(二)——添加事件处理程序

深入理解js Dom事件机制(一)--事件流 事件就是当用户或者浏览器自身执行的某种动作,诸如 click.mouseover等都是事件的名称,那响应个事件的函数就称为事件处理程序(事件处理函数.事件句柄). 事件处理程序的名字都是以on+事件名称命名,比如 click事件的事件处理程序就是onclick, 为某个事件指定事件处理程序的方式大致分为三种. 1.HTML事件处理程序 这个很简单,大家基本初学js的时候都应该用过,就不再赘述,直接看实例代码 <!DOCTYPE html> <