- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
通过优秀的网络书交互式数据可视化工作,并创建了(一个怪物)脚本来创建交互式条形图:
我添加了一个鼠标悬停事件监听器,以在悬停时更改条形的颜色。问题是通过上面 1. 添加的条形没有改变颜色。据我所知,这些栏已正确选择,但无论出于何种原因,这些栏的鼠标悬停事件都不会被触发:
svg.select(".bars").selectAll("rect")
.on("mouseover", function() {
d3.select(this)
.transition()
.attr("fill", "red");
})
预先感谢您的帮助,我们始终不胜感激。
完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Interactive Data Visualization for the Web Program-Along</title>
<style>
/* axes are made up of path, line, and text elements */
.axis path,
.axis line {
fill: none;
stroke: navy;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
/* color is CSS property, but need SVG property fill to change color */
fill: navy;
}
</style>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<p>Click on this text to update the chart with new data values.</p>
<script type="text/javascript">
var n = 50;
var domain = Math.random() * 1000;
function gen_data(n, domain) {
var d = [];
for (var i = 0; i < n; i++) {
d.push(
{ id: i, val: Math.random() * domain }
);
}
return d;
}
// define key function once for use in .data calls
var key = function(d) {
return d.id;
};
var dataset = gen_data(n, domain);
// define graphic dimensions
var w = 500, h = 250, pad = 30;
// get input domains
var ylim = d3.extent(dataset, function(d) {
return d.val;
});
// define scales
var x_scale = d3.scale.ordinal()
.domain(d3.range(dataset.length))
.rangeRoundBands([0, w - pad], 0.15);
var y_scale = d3.scale.linear()
.domain([ylim[0], ylim[1] + pad]) // could have ylim[0] instead
// range must be backward [upper, lower] to accommodate svg y inversion
.range([h, 0]); // tolerance to avoid clipping points
var color_scale = d3.scale.linear()
.domain([ylim[0], ylim[1]])
.range([0, 255]);
// create graphic
var svg = d3.select("body").append("div").append("svg")
.attr("width", w)
.attr("height", h);
svg.append("g")
.attr("class", "bars")
.selectAll(".bars rect")
.data(dataset)
.enter()
.append("rect")
.attr({
x: function(d, i) {
return x_scale(i) + pad;
},
y: function(d) {
return y_scale(d.val);
},
width: x_scale.rangeBand(), // calculates width automatically
height: function(d) { return h - y_scale(d.val); },
opacity: 0.6,
fill: function(d) {
return "rgb(50, 0, " + Math.floor(color_scale(d.val)) + ")";
}
});
// add axes
var yAxis = d3.svg.axis()
.scale(y_scale) // must be passed data-to-pixel mapping (scale)
.ticks(3) // optional (d3 can assign ticks automatically)
.orient("left");
// since function, must be called
// create <g> to keep things tidy, to style via CSS, & to adjust placement
svg.append("g")
.attr({
class: "axis",
transform: "translate(" + pad + ",0)"
})
.call(yAxis);
// add event listener for clearing/adding all new values
d3.select("p")
.on("click", function() {
// generate new dataset
dataset = gen_data(n, domain);
// remove extra bars
d3.selectAll(".bars rect")
.data(dataset, function(d, i) { if (i < 50) { return d; }})
.exit()
.transition()
.attr("opacity", 0)
.remove();
// update scales
x_scale.domain(d3.range(dataset.length))
.rangeRoundBands([0, w - pad], 0.15);
ylim = d3.extent(dataset, function(d) {
return d.val;
});
y_scale.domain([ylim[0], ylim[1] + pad]);
// update bar values & colors
d3.selectAll(".bars rect")
.data(dataset)
.transition()
.duration(500)
.attr("x", function(d, i) { return x_scale(i) + pad; })
.transition() // yes, it's really this easy...feels like cheating
.delay(function(d, i) { return i * (1000 / dataset.length); }) // set dynamically
.duration(1000) // optional: control transition duration in ms
.each("start", function() {
// "start" results in immediate effect (no nesting transitions)
d3.select(this) // this to select each element (ie, rect)
.attr("fill", "magenta")
.attr("opacity", 0.2);
})
.attr({
y: function(d) { return y_scale(d.val); },
height: function(d) { return h - y_scale(d.val); }
})
.each("end", function() {
d3.selectAll(".bars rect")
.transition()
// needs delay or may interrupt previous transition
.delay(700)
.attr("fill", function(d) {
return "rgb(50, 0, " + Math.floor(color_scale(d.val)) + ")";
})
.attr("opacity", 0.6)
.transition()
.duration(100)
.attr("fill", "red")
.transition()
.duration(100)
.attr("fill", function(d) {
return "rgb(50, 0, " + Math.floor(color_scale(d.val)) + ")";
});
});
// update axis (no need to update axis-generator function)
svg.select(".axis")
.transition()
.duration(1000)
.call(yAxis);
});
// extend dataset by 1 for each click on svg
svg.on("click", function() {
// extend dataset & update x scale
dataset.push({ id: dataset.length, val: Math.random() * domain });
x_scale.domain(d3.range(dataset.length));
// add this datum to the bars <g> tag as a rect
var bars = svg.select(".bars")
.selectAll("rect")
.data(dataset, key);
bars.enter() // adds new data point(s)
.append("rect")
.attr({
x: w,
y: function(d) {
return y_scale(d.val);
},
width: x_scale.rangeBand(), // calculates width automatically
height: function(d) { return h - y_scale(d.val); },
opacity: 0.6,
fill: function(d) {
return "rgb(50, 0, " + Math.floor(color_scale(d.val)) + ")";
}
});
// how does this move all the other bars!?
// because the entire dataset is mapped to bars
bars.transition()
.duration(500)
.attr("x", function(d, i) {
return x_scale(i) + pad;
});
});
// add mouseover color change transition using d3 (vs CSS)
svg.select(".bars").selectAll("rect")
.on("mouseover", function() {
d3.select(this)
.transition()
.attr("fill", "red");
})
.on("mouseout", function(d) {
d3.select(this)
.transition()
.attr("fill", function() {
return "rgb(50, 0, " + Math.floor(color_scale(d.val)) + ")";
})
.attr("opacity", 0.6);
})
// print to console when clicking on bar = good for debugging
.on("click", function(d) { console.log(d); });
</script>
</body>
</html>
更新:
感谢 Miroslav 的建议,我开始尝试不同的方法来解决问题,并遇到了 Makyen 对 this related SO post 的回答。 .
虽然我想象有一种更高效的方法来处理这个问题,但我决定在每次鼠标进入 svg 元素时使用以下代码重新绑定(bind) mouseover 事件监听器:
svg.on("mouseover", mouse_over_highlight);
// add mouseover color change transition using d3 (vs CSS)
function mouse_over_highlight() {
d3.selectAll("rect")
.on("mouseover", function () {
d3.select(this)
.transition()
.attr("fill", "red");
})
.on("mouseout", function (d) {
d3.select(this)
.transition()
.attr("fill", function () {
return "rgb(50, 0, " + Math.floor(color_scale(d.val)) + ")";
})
.attr("opacity", 0.6);
})
// print to console when clicking on bar = good for debugging
.on("click", function (d) {
console.log(d);
});
}
最佳答案
您的事件仅在第一个栏触发而不是动态栏触发的原因是您添加事件监听器的方式。
您的方式仅将事件放在页面上已存在的元素上(它们位于 DOM 结构中)。任何新元素都不会绑定(bind)此事件监听器。
您可以通过将代码放入类似
的函数中来快速检查这一点function setListeners() {
svg.select(".bars").selectAll("rect").on("mouseover", function() {
d3.select(this)
.transition()
.attr("fill", "red");
})
}
在屏幕上添加任何新栏后,添加此函数调用并查看它是否适用于所有元素。如果确实如此,您需要以适用于所有元素(包括动态添加的元素)的方式编写事件监听器。方法是将事件设置到某些父 DOM 节点,然后检查您是否将鼠标悬停在您希望事件触发的对象上。
示例:
$(document).on(EVENT, SELECTOR, function(){
code;
});
这会将事件放在主体上,如果您超出了正确的元素,您可以在触发后检查选择器。然而,自从我使用 D3 以来已经有一段时间了,我不确定 D3、SVG 和 jQuery 如何一起使用,上次我这样做时他们遇到了一些麻烦。在这种情况下,事件应该是鼠标悬停,选择器应该是您的矩形条,函数应该是您想要运行的内容。
如果其他一切都失败了,以防它们不合作,只需使用该函数设置事件监听器,并在每次动态添加新元素后调用它。
关于javascript - selectAll ("rect") 选择所有矩形,但不对某些矩形应用鼠标悬停功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30078916/
我正在尝试为我的网站创建一个功能,允许用户使用 mousemove 和 touchmove 事件水平滚动 div 内容(类似于 Apple AppStore any app Screenshots s
我有固定的侧边栏导航栏,它在悬停时工作,但我想通过单击折叠按钮打开第一个菜单。类似于悬停在菜单 1 上的工作方式。我已经尝试了以下方法。 jsfiddle Demo $(document).on('c
Mouse.Synchronize() 在 .Net 中有什么作用? MSDN 说它“强制鼠标重新同步” 最佳答案 只是我的假设: Stylus 中存在类似的方法类别:Stylus.Synchroni
有没有什么办法可以同时使用鼠标, pygame.mouse.set_visible(False) 已激活。当前鼠标仅在尝试使用时返回右下坐标。需要在隐藏鼠标时能够获得正确的坐标。 在他们的 docum
我有一个缺少数据的数据库。我需要估算数据(我使用的是鼠标),然后根据原始列创建新列(使用估算数据)。我需要使用这些新列进行统计分析。 具体来说,我的参与者使用李克特 7 分量表填写了几份问卷。有些人没
我正在编写一个与电脑交互的机器人。简而言之,我所做的是: -截取屏幕截图- 在此屏幕截图上识别对象(使用 cv2 matchTemplate) -使用找到的位置进行一些鼠标操作(例如:将鼠标指针移动到
我的程序是一个文本游戏,它使用 WindowsForm 上的文本框模拟控制台输出。我试图实现的一个功能是通过单击一个按钮,它将以一定的速度输出到 TextBox,这是通过这种方法实现的 atm: pu
我遇到了一个问题。如果有任何帮助,我将不胜感激。 我正在尝试从玩家位置射击到鼠标点击位置。代码没有给我任何错误,根据我的逻辑,它应该可以工作,但它没有 它创建了项目符号对象,仅此而已。 //Bulle
给定一个带蓝牙的 Windows Mobile 6.1 智能手机,我想将它注册为鼠标。 基本上我现在做的: 使用 Guid {00001124-0000-1000-8000-00805f9b34fb}
我有一个关于在 JavaFX 中实现鼠标拖动事件的正确方法的问题。 我的 playGame() 方法当前使用 onMouseClicked,但这只是一个占位符 理想情况下,我希望“飞盘”沿着鼠标拖动的
已关闭。此问题旨在寻求有关书籍、工具、软件库等的建议。不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以
我目前正在使用 Windows 的 RawInput API 来访问键盘和鼠标输入。我有点困惑的一件事是,当我将鼠标注册为 RawInputDevice 时,我无法移动我的 Win32 窗口或使用那里
我想在我的网站浏览器窗口中 move 鼠标,如下所示:www.lmsify.com。我怎样才能做到这一点?(javascript、flash、activex) 问候,丽莎M 最佳答案 他们并没有真正
我想要一个动画。我是后端开发人员,但我必须使用 jquery 创建动画。 动画、背景和元素位置随鼠标移动而变化。 类似于http://www.kennedyandoswald.com/#!/premi
如何将鼠标“锁定”到某个 OpenGL 窗口。有点像在 Minecraft 中是如何完成的。GameDev 是一个更好的询问地点吗? 最佳答案 正如 Robert 在评论中所说,OpenGL 实际上并
我正在尝试实现一个颜色选择器,它从屏幕上各处的像素中获取颜色。为此,我计划使用全局鼠标 Hook 来监听 WM_MOUSEMOVE,以便在鼠标四处移动时更新颜色,并监听鼠标点击以确认 (WM_LBUT
如何使用 Java 和 JNA(Java native 访问)与 Windows API 交互?。我试图通过在鼠标输入流上排队鼠标事件来让鼠标做某事,并且代码有效,因为 SendInput(...)
我想用 C++ 脚本 move 鼠标光标。我在 Parallels 中的 Windows 7 中使用 Visual C++ 2010 Express,并创建了一个控制台应用程序。 我知道 SetCur
我有一些关于 WH_MOUSE 的问题。根据我的阅读,通过将钩子(Hook)放入 DLL 中,它会注入(inject)进程。这是否意味着捕获鼠标也适用于我的桌面、菜单启动等?那么应用程序的标题栏呢?我
如何为多只鼠标显示另一个光标? 我有两个 TMemos,两个可以输入各自 TMemo 的键盘,2 个鼠标,我需要 2 个光标。 如果假设的话,我已经可以检测出哪只鼠标是哪只了。我怎样才能让我自己的光标
我是一名优秀的程序员,十分优秀!