d3中两个数据源的工具提示问题
Tooltip issue with two data sources in d3
我有一个d3图表,它是由一些json生成的,而json又是由php生成的。所有这些都很好——php正确地格式化json,图表也正确地显示。它可以在这里看到,我包括下面javascript部分的完整代码:
var margin = {top: 50, right: 150, bottom: 50, left: 150},
w = 2500 - margin.left - margin.right,
h = 500 - margin.top - margin.bottom;
var json = <?php echo $json; ?>;
console.log(json);
d3.json("MM_chart.json", function(error, json) {
if (error) throw error;
var items = json.items;
var locations = json.locations;
var directions = json.stage_directions;
console.log(items);
console.log(locations);
console.log(directions);
var stage_directions = ([44, 49, 114, 140, 209, 217, 249, 257, 265, 277, 305, 334, 358, 381, 398, 409, 440, 470, 491, 547, 555, 564, 572, 587, 614, 630, 640, 691, 704, 725, 743, 775, 793, 818, 823, 841, 845, 868, 872, 888, 902, 910, 920, 925, 963, 993, 1005, 1023, 1031, 1047, 1061, 1096, 1125, 1133, 1143, 1178, 1210, 1228, 1281, 1293, 1336, 1349, 1376, 1395, 1439, 1446, 1454, 1538, 1554, 1562, 1578, 1598, 1610, 1618, 1642, 1646, 1716, 1725, 1743, 1781, 1791, 1797, 1843, 1863, 1887, 1915, 1923, 1939 ,1972, 1989, 2019, 2031, 2039, 2045, 2073, 2085, 2101, 2123]);
var x = d3.scale.linear()
.domain([0, 2200])
.range([0, w]);
var y = d3.scale.ordinal()
.domain(locations.map(function(d) {return d["location"];}))
.rangeBands([0, h]);
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d, i) {return console.log(d.line_text) + "<strong>(" + d.starting_line + ")</strong> <i>" + d.character + "</i>: " + d.line_text;});
var stage_tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d, i) {return console.log(d.direction_text) + "<strong>(" + d.line_after + ") s.d.</strong> <i>" + d.direction_text;});
var svg = d3.select("body").append("svg")
.attr("width", w + margin.left + margin.right)
.attr("height", h + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("text")
.attr("transform", "translate(" + (w / 2) + " ," + (h + margin.bottom - 5) +")")
.style("text-anchor", "middle")
.text("Line Number");
var stage_bars = svg.selectAll(".stage_bar")
.data(directions)
.enter()
.append("rect")
.attr("class", "overlay")
.attr("class", function(d, i) {return "stage_bar " + d.direction_text;})
.attr("x", function(d, i) {return d.line_after;})
.attr("width", 1)
.attr("height", h)
.style("fill", "black")
.style("opacity",0.3)
.call(stage_tip)
.on('mouseover', stage_tip.show)
.on('mouseout',stage_tip.hide);
svg.append("rect")
.attr("class", "overlay")
.attr("x",1)
.attr("width", 1133)
.attr("height", h)
.style ("fill", "red")
.style ("opacity", 0.1);
svg.append("rect")
.attr("class", "overlay")
.attr("x",1133)
.attr("width", 857)
.attr("height", h)
.style ("fill", "yellow")
.style ("opacity", 0.1);
svg.append("rect")
.attr("class", "overlay")
.attr("x",1990)
.attr("width", 134)
.attr("height", h)
.style ("fill", "green")
.style ("opacity", 0.1);
svg.append("rect")
.attr("class", "overlay")
.attr("x",5)
.attr("y", 10)
.attr("width", 485)
.attr("height", 155)
.style ("fill", "aliceblue")
// .style ("opacity", 0.1);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
//.call(bars);
var bars = svg.selectAll(".bar")
.data(items)
.enter()
.append("rect")
.attr("class", function(d, i) {return "bar " + d.character;})
.attr("x", function(d, i) {return d.starting_line;})
.attr("y", function(d, i) {return y(d.location);})
.attr("width", function(d, i) {return d.duration;})
.attr("height", 15)
.style("fill", function(d,i) {return "#" + d.color;})
.call(tip)
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
var listCharacters = d3.set(items.map(function(d) {return d.character})).values();
listColors = [];
listPositions = [];
for (l = 0; l < listCharacters.length; l++) {
for (var key in items) {
if (listCharacters[l] === items[key].character) {
if (listColors.indexOf(items[key].color) > -1) {} else {
listColors.push(items[key].color);
var xlegend = (Math.floor(l / 10) * 100);
var ycounter;
var ylegend;
var oldxlegend;
if (l === 0) {
ycounter = 1;
}
if (ycounter < 10) {
listPositions.push(ycounter * 15);
ycounter++;
} else {
listPositions.push(ycounter * 15);
ycounter = 1;
}
}
} else {}
}
}
console.log(listCharacters);
console.log(listColors);
console.log(listPositions);
var legend = svg.selectAll(".legend")
.data(listCharacters)
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(" + (Math.floor(i / 10) * 105) + ", " + listPositions[i] + ")"; })
legend.append("rect")
.attr("x", 10)
.attr("width", 10)
.attr("height", 10)
.attr("fill", function(d,i) {return "#" + listColors[i];});
legend.append("text")
.attr("x", 22)
.attr("y", 5)
.attr("dy", ".35em")
.text(function(d,i){ return listCharacters[i]});
svg.append("g")
.attr("class", "legend")
.call(legend)
});
我的问题是,我有两个工具提示想要包含,它们来自JSON的两个单独的子部分。工具提示由以下两个var声明定义:
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d, i) {return console.log(d.line_text) + "<strong>(" + d.starting_line + ")</strong> <i>" + d.character + "</i>: " + d.line_text;});
var stage_tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d, i) {return console.log(d.direction_text) + "<strong>(" + d.line_after + ") s.d.</strong> <i>" + d.direction_text;});
并在两个要求栏中声明项目和方向:
var stage_bars = svg.selectAll(".stage_bar")
.data(directions)
.enter()
.append("rect")
.attr("class", "overlay")
.attr("class", function(d, i) {return "stage_bar " + d.direction_text;})
.attr("x", function(d, i) {return d.line_after;})
.attr("width", 1)
.attr("height", h)
.style("fill", "black")
.style("opacity",0.3)
.call(stage_tip)
.on('mouseover', stage_tip.show)
.on('mouseout',stage_tip.hide);
var bars = svg.selectAll(".bar")
.data(items)
.enter()
.append("rect")
.attr("class", function(d, i) {return "bar " + d.character;})
.attr("x", function(d, i) {return d.starting_line;})
.attr("y", function(d, i) {return y(d.location);})
.attr("width", function(d, i) {return d.duration;})
.attr("height", 15)
.style("fill", function(d,i) {return "#" + d.color;})
.call(tip)
.on('mouseover', tip.show)
.on('mouseout', tip.hide);
我的问题是bar的工具提示(调用tip的工具提示)有效,但stage_bars的工具提示不起作用。我认为问题是,我在tip和stage_tip中都调用了同一个类,但将其声明为tip之外的其他类并没有什么区别。
我的问题是如何使两个工具提示都发挥作用。这可能吗?我看到过一些似乎可以做到这一点的例子,但代码并不清楚。
解决方案实际上非常简单。我在svg.append("rect")语句之前声明了stage_bars变量,这意味着指示阶段方向的行位于其他对象下方。因此,鼠标永远无法将鼠标悬停在它们之上以触发工具提示。将var声明移到svg.append语句之后的某个位置解决了这个问题。
相关文章:
- d3.js Chord图的动态工具提示
- Graphiti中是否有任何工具提示功能
- "工具提示"jQuery插件坏了
- 单元格的工具提示或标题不显示超过2000个字符
- d3.js用按钮更新条形图工具提示
- 使Intro.js工具提示响应
- 画布中绘制的矩形区域的弹出工具提示
- 使用CSS/JavaScript更改剑道图工具提示文本颜色
- 禁用NVD3 multiBarHorizontalChart中0值的工具提示
- 如何更改已显示的工具提示
- 如何访问高图表工具提示中的任何特定数据
- 如何在jQuery点击函数中添加并显示引导工具提示
- 我可以't使用jQuery更改工具提示引导程序的位置
- 语义UI中格式化的工具提示
- 柱状图上的Highcharts工具提示
- 引导工具提示用法,在搜索字段中
- 将工具提示添加到d3散点图中
- Highcharts工具提示不显示corrosconding文本值,而是显示'未定义'
- 突出显示在加载表数据源时的工具提示
- d3中两个数据源的工具提示问题