- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
第一个问题:
对于单个条形图,当我们将鼠标悬停在某个条形上时,我们将获得所选条形的值,即i
。例如,以下代码检测我们选择的 x 轴元素并将其分配给名为 selectedYear
的变量:
.on("mouseover", function (d, i) {
selectedYear = i;
update();
barChart.selectAll("text")
.attr("fill", "black");
d3.select(this).attr("fill", "orange");
})
但是,当它是下面的堆叠栏时,如何在 mouseover 函数中将“2006”赋予 selectedYear
并将“SmartPhone”赋予 seletedCategory
?
第二个问题:
当我将鼠标悬停在条形上时,如何突出显示 x 轴上的相应文本?在上图中,当鼠标悬停在 2006 栏的任何 block 上时,如何使文本“2006”突出显示?
下面是我的整个代码:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script src="d3.min.js" charset="UTF-8"></script>
<script>
var width = 700;
var height = 500;
var dataSet;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height);
var dataSet1 = [
{ name: "PC" ,
sales: [ { year:2005, profit: 3000 },
{ year:2006, profit: 1300 },
{ year:2007, profit: 3700 },
{ year:2008, profit: 4900 },
{ year:2009, profit: 700 }] },
{ name: "SmartPhone" ,
sales: [ { year:2005, profit: 2000 },
{ year:2006, profit: 4000 },
{ year:2007, profit: 1810 },
{ year:2008, profit: 6540 },
{ year:2009, profit: 2820 }] },
{ name: "Software" ,
sales: [ { year:2005, profit: 1100 },
{ year:2006, profit: 1700 },
{ year:2007, profit: 1680 },
{ year:2008, profit: 4000 },
{ year:2009, profit: 4900 }] }
];
var stack = d3.layout.stack()
.values(function(d){ return d.sales; })
.x(function(d){ return d.year; })
.y(function(d){ return d.profit; });
var data = stack(dataSet1);
var padding = { left:50, right:100, top:30, bottom:30 };
var xRangeWidth = width - padding.left - padding.right;
var xScale = d3.scale.ordinal()
.domain(data[0].sales.map(function(d){ return d.year; }))
.rangeBands([0, xRangeWidth],0.3);
var maxProfit = d3.max(data[data.length-1].sales, function(d){
return d.y0 + d.y;
});
var yRangeWidth = height - padding.top - padding.bottom;
var yScale = d3.scale.linear()
.domain([0, maxProfit])
.range([0, yRangeWidth]);
var color = d3.scale.category10();
var groups = svg.selectAll("g")
.data(data)
.enter()
.append("g")
.style("fill",function(d,i){ return color(i); });
var rects = groups.selectAll("rect")
.data(function(d){ return d.sales; })
.enter()
.append("rect")
.attr("x",function(d){ return xScale(d.year); })
.attr("y",function(d){ return yRangeWidth - yScale( d.y0 + d.y ); })
.attr("width",60)
.attr("height",function(d){ return yScale(d.y); })
.attr("transform","translate(" + padding.left + "," + padding.top + ")")
.attr("stroke","white")
.on("mouseover", function (d, i) {
groups.selectAll("rect")
.attr("stroke","white")
d3.select(this)
.attr("stroke", "black")
.attr("stroke-width", 3);
selectedYear = i;
})
.on("mouseout", function (d) {
// d3.select(this).attr("stroke", "white").attr("stroke-width", 0);
});
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom");
yScale.range([yRangeWidth, 0]);
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
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 + "," + (height - padding.bottom - yRangeWidth) + ")")
.call(yAxis);
var labHeight = 50;
var labRadius = 10;
var labelCircle = groups.append("circle")
.attr("cx",width - padding.right*0.98)
.attr("cy",function(d,i){ return padding.top * 2 + labHeight * i; })
.attr("r",labRadius);
var labelText = groups.append("text")
.attr("x",width - padding.right*0.8)
.attr("y",function(d,i){ return padding.top * 2 + labHeight * i; })
.attr("dy",labRadius/2)
.text(function(d){ return d.name; });
</script>
</body>
</html>
最佳答案
一些想法...
var width = 600,
height = 200,
padding = { left:50, right:200, top:20, bottom:30},
xRangeWidth = width - padding.left - padding.right,
yRangeWidth = height - padding.top - padding.bottom;
var dataSet;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + [padding.left, padding.top] + ")");
var dataSet1 = [
{ name: "PC" ,
sales: [ { year:2005, profit: 3000 },
{ year:2006, profit: 1300 },
{ year:2007, profit: 3700 },
{ year:2008, profit: 4900 },
{ year:2009, profit: 700 }] },
{ name: "SmartPhone" ,
sales: [ { year:2005, profit: 2000 },
{ year:2006, profit: 4000 },
{ year:2007, profit: 1810 },
{ year:2008, profit: 6540 },
{ year:2009, profit: 2820 }] },
{ name: "Software" ,
sales: [ { year:2005, profit: 1100 },
{ year:2006, profit: 1700 },
{ year:2007, profit: 1680 },
{ year:2008, profit: 4000 },
{ year:2009, profit: 4900 }] }
],
// experiment to demonstrate unsupported data structure //////////////////////////////
dataset2 = dataSet1.map(function(d){
return {
name: d.name,
sales: d.sales.reduce(function(s, o) {
return (s[o.year] = o.profit, s)
},{})
}
}),
_stack = d3.layout.stack()
.values(layer)
.x(function(d){ return d.year; })
.y(function(d){ return d.profit; }),
dataRaw = _stack(dataset2).map(function(d){
return {
name: d.name,
sales: layer(d)
}
});
function layer(d){
return Object.keys(d.sales).map(function(y){
return {profit: d.sales[y],year:y}
});
}
// end experiment /////////////////////////////////////////////////////////////////////
var offsetSelect = d3.ui.select({
before: "svg",
style: {position: "absolute", left: width - padding.right + 15 + "px", top: yRangeWidth + "px"},
onUpdate: function() {
update(dataSet1)
},
data : ["wiggle", "zero", "expand", "silhouette"]
}),
orderSelect = d3.ui.select({
before: "svg",
style: {position: "absolute", left: width - padding.right + 15 + "px", top: yRangeWidth - 20 + "px"},
onUpdate: function() {
update(dataSet1)
},
data : ["inside-out", "default", "reverse"]
}),
stack = d3.layout.stack()
.values(function(d){ return d.sales; })
.x(function(d){ return d.year; })
.y(function(d){ return d.profit; })
.out(function out(d, y0, y) {
d.p0 = y0;
d.y = y;
}
);
// apply a transform to map screen space to cartesian space
// this removes all confusion and mess when plotting data!
var plotArea = svg.append("g")
.attr(transplot(yRangeWidth))
.attr("class", "plotArea");
// x Axis
var xPadding = {inner: 0.1, outer: 0.3},
xScale = d3.scale.ordinal()
.rangeBands([0, xRangeWidth], xPadding.inner, xPadding.outer),
xAxis = d3Axis()
.scale(xScale)
.orient("bottom"),
gX = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + yRangeWidth + ")");
// y Axis
var yAxisScale = d3.scale.linear()
.range([yRangeWidth, 0]),
yAxis = d3Axis()
.scale(yAxisScale)
.orient("left"),
gY = svg.append("g")
.attr("class", "y axis")
.style("pointer-events", "none");
var yScale = d3.scale.linear()
.range([0, yRangeWidth]);
var color = d3.scale.category10();
function update(dataSet) {
var data = stack.offset(offsetSelect.value())
.order(orderSelect.value())(dataSet),
maxProfit = d3.max(data,function(d) {
return d3.max(d.sales, function(s) {
return s.profit + s.p0
})
});
function yDomain(){return [0, offsetSelect.value() == "expand" ? 1 : maxProfit]}
xScale.domain(data[0].sales.map(stack.x()));
yAxisScale.domain(yDomain());
yScale.domain(yAxisScale.domain());
var series = plotArea.selectAll(".series")
.data(data);
series.enter()
.append("g")
.attr("class", "series");
series.style("fill", function(d, i) {
return color(i);
});
series.exit().remove();
var s = xScale.rangeBand(),
w = s - xPadding.inner,
points = series.selectAll("rect")
.data(function(d) {
return d.sales;
}),
newPoints = points.enter()
.append("rect")
.attr("width", w)
.on("mouseover", function(d) {
var rect = d3.select(this), selectedYear = d.year;
// if the plot is not normalised, offset the axis to align with the selected group
if(offsetSelect.value() != "expand") {
var pMin = d3.min(data,function(d) {
return d3.min(d.sales.filter(function(p) {
return p.year == selectedYear
}), function(s) {
return s.p0
})
});
yAxisScale.domain([-pMin, yDomain()[1] - pMin]);
gY.transition().call(yAxis).attr("transform", "translate(" + rect.attr("x") + ",0)");
}
// manage the highlighting
series.selectAll("rect")
.transition()
.attr({opacity: 0.5});
rect
.transition()
.attr({opacity: 1});
d3.selectAll(".x.axis .tick")
.filter(function(d) {
return d == selectedYear
})
.classed("highlight", true);
// move the selected element to the front
d3.select(this.parentNode)
.moveToFront();
gX.moveToFront();
// add the value for the moused over item to the legend text and highlight it
var g = d3.select(this.parentNode).selectAll(".label").select("text");
g.classed("highlight", true);
g.text(g.text() + ": " + d3.format(">8.0f")(d.profit));
series
.append("g")
.attr("class", "tooltip")
.attr("transform", "translate(" + [rect.attr("x"), rect.attr("y")] + ")")
.append("text")
.attr(transflip())
.text(d3.format(">8.0f")(d.profit))
.attr({x: "1em", y: -rect.attr("height")/2, dy: ".35em", opacity: 0})
.transition().attr("opacity", 1)
.style({fill: "black", "pointer-events": "none"})
})
.on("mouseout", function(d) {
var year = d.year;
d3.selectAll(".x.axis .tick")
.filter(function(d) {
return d == year
})
.classed("highlight", false);
series.selectAll("rect")
.transition()
.attr({opacity: 1});
var g = d3.select(this.parentNode).select("text");
g.classed("highlight", false);
g.text(g.text().split(":")[0])
yAxisScale.domain(yDomain());
yAxis.tickSize(6);
gY.transition().call(yAxis).attr("transform", "translate(0,0)");
series.selectAll(".tooltip")
.transition()
.attr({opacity: 0})
.remove();
});
points.transition()
.attr("x", function(d) {
return xScale(d.year);
})
.attr("y", function(d) {
return yScale(d.p0);
})
.attr("height", function(d) {
return yScale(d.y);
})
.attr("stroke", "white");
points.exit().remove;
gX.transition().call(xAxis);
gY.transition().call(yAxis);
// Add the legend inside the series containers
// The series legend is wrapped in another g so that the
// plot transform can be reversed. Otherwise the text would be mirrored
var labHeight = 40,
labRadius = 10,
label = series.selectAll(".label").data(function(d){return [d.name]}),
newLabel = label.enter().append("g")
.attr("class", "label")
// reverse the transform (it is it's own inverse)
.attr(transplot(yRangeWidth));
label.exit().remove();
// add the marker and the legend text to the normalised container
// push the data (name) down to them
var labelCircle = label.selectAll("circle").data(aID),
// take a moment to get the series order delivered by stack
orders = data.map(function(d) { // simplify the form
return {name: d.name, base: d.sales[0].p0}
}).map(function(d) { // get a copy, sorted by p0
return d
}).sort(function(a, b){
return a.base - b.base
}).map(function(d) { // convert to index permutations
return data.map(function(p) {
return p.name
}).indexOf(d.name)
}).reverse(); // convert to screen y ordinate
labelCircle.enter().append("circle");
labelCircle.attr("cx", xRangeWidth + 20)
.attr("cy", function(d, i, j) {
return labHeight * orders[j];
})
.attr("r", labRadius);
var labelText = label.selectAll("text").data(aID);
labelText.enter().append("text");
labelText.attr("x", xRangeWidth + 40)
.attr("y", function(d, i, j) {
return labHeight * orders[j];
})
.attr("dy", labRadius / 2)
.text(function(d) {
return d;
});
function aID(d){
return [d];
}
}
update(dataSet1);
d3.selection.prototype.moveToFront = function() {
return this.each(function() {
this.parentNode.appendChild(this);
});
};
body {
position: relative;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.axis .tick line {
stroke: #ccc;
/*opacity: 0.5;*/
pointer-events: none;
}
.highlight {
font-weight: bold ;
}
svg {
overflow: visible;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://gitcdn.xyz/repo/cool-Blue/d3-lib/master/inputs/select/select.js"></script>
<script src="https://gitcdn.xyz/repo/cool-Blue/d3-lib/master/plot/plot-transform.js"></script>
关于javascript - d3.js 突出显示堆叠栏并获取选定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32057842/
如何将单元格(在 UICollectionView 中)堆叠在一起? Feedly 做得很好,我想知道是否可以以某种方式操纵 zIndex 属性以在 UICollectionView 的导航中获得类似
我正在尝试堆叠 div 以使用和图像显示顶部和底部淡入淡出。 外部 div(“旋转器”)有一个背景图像,该图像在顶部和底部具有渐变,在中间是透明的。在中间,我想显示内容或图像,并将外部 div 背景图
我有两个动画(在 CSS 中)div,它们围绕彼此旋转。我想在中间为文本添加另一个 div。但是,如果我将 div 放在这两个中的任何一个中,它就会与父 div 一起设置动画。如果我尝试定位它,它就位
图中显示了我想要的 View 。 最佳答案 为此你可以采取 FrameLayout . 例如 - 1: 更新: 例如 - 2:精湛的示例和技巧,可在此处找到:http://w
使用 tf.keras.layers.RNN 的 TensorFlow (1.13.1) 中多层/堆叠 RNN 的初始状态所需的结构是什么? API? 我尝试了以下方法: lstm_cell_size
我在制作条形图时遇到问题,其中 y 轴不是计数,而是变量的值。 我使用stat=identity,这对于一个变量来说很好。但是,如果我有两个变量并且想要创建堆叠/闪避条形图怎么办? 我这里有一些模拟数
我有一个栅格路径列表(rplist = 912 raster pathe for 912 rasters (19yeras)(12months)(4weeks))如下: [1] "C:/Users
我已经完成了一个项目,现在需要更改该项目,以便在变量位于数组中时显示一个 div,如果变量不在数组中则显示另一个 div。 通常我会这么做 祝你愉快,但是我得到的代码已经包含大量 html 和 ph
我在制作条形图时遇到问题,其中 y 轴不是计数,而是来自变量的值。 我使用 stat=identity,这对一个变量来说没问题。但是,如果我有两个变量并想创建一个堆叠/闪避条形图怎么办? 我这里有一些
我有一个栅格路径列表(rplist = 912 raster pathe for 912 rasters (19yeras)(12months)(4weeks))如下: [1] "C:/Users
我正在尝试将分数和耗时标签(scoreAndTimer)添加到我已经工作的贪吃蛇游戏代码中。问题是当我使用 ScoreAndTimer.setText(); 时它与之前的文本堆叠在一起。 我尝试 se
有没有办法将 GTK+ 小部件放入堆栈中? IE。在标签上放置一个按钮,使按钮覆盖标签的一部分。 最佳答案 您可以使用 GtkFixed 作为布局。这将允许您控制子小部件的确切位置,并且它们可以重叠。
我有以下代码: for (Map.Entry e : classes.entrySet()) { ClassReader reader = e.getValue(); ClassWri
我正在尝试根据类别的计数(或比例)更改我的(堆叠)条宽,作为示例,我使用了钻石数据集。我想根据每个类别(变量 cut )的频率看到不同的宽度。我首先创建了一个变量 cut_prop然后用下面的代码绘制
我目前正在 UWP 中开展一个项目,我有一个 CommandBar,我想将其从 Hidden 变为 Compact 如果鼠标移动。五秒钟后(如果鼠标不移动)CommandBar 应该再次返回到Hidd
我是 Swift 新手,并尝试在学习过程中编写一本交互式书籍。我使用 CATransform3DMakeRotation 创建了封面效果。 正如您所看到的,当我堆叠 View 时,问题就出现了。如果我
我已经阅读了 finish(); 命令和 FLAG_ACTIVITY_CLEAR_TOP 命令,还查看了 Common Ware 关于终止应用程序的回答,但我不确定如何放置这进入我的应用程序。 基本上
在我的引擎中,我从成对的顶点/像素着色器文件中加载 Cg 着色器。我希望能够堆叠着色器以组合它们(照明+ Material 等)。除了将着色器分解为单独的函数然后从中创建单个着色器脚本字符串之外,您是
我有一个 Activity 应该自行完成并关闭应用程序。现在,在某些情况下,根据用户导航到 Activity 的方式而变化, Activity 正在堆叠。当 Activity 堆积时,然后调用 fin
我有 10 个具有完全相同的列和数据类型的 csv 文件。什么是最快/最有效的堆叠方式? CSV1: col1 | col2 | col3 1 | 'a' | 0.1 2 | 'b'
我是一名优秀的程序员,十分优秀!