我正在使用D3在x轴上创建具有画笔功能的两级分组类别条形图。但是,即使我没有添加任何与隐藏x轴相关的CSS,X轴线也不会显示在FireFox中。 X轴线出现在Chrome和IE中。 注意:如果我们点击整页x轴线显示,也可以显示它。
// Code goes here
var barsData = [
{
"value":100,
"key":"03-08-2016,0",
"secondKey":"Windows 7/Chrome49"
},
{
"value":40,
"key":"04-08-2016,1",
"secondKey":"Windows 7/Chrome49"
},
{
"value":20,
"key":"05-08-2016,2",
"secondKey":"Windows 7/Chrome49"
},
{
"value":100,
"key":"03-08-2016,3",
"secondKey":"Windows 7/Chrome50"
},
{
"value":27,
"key":"04-08-2016,4",
"secondKey":"Windows 7/Chrome50"
},
{
"value":57,
"key":"05-08-2016,5",
"secondKey":"Windows 7/Chrome50"
},
{
"value":40,
"key":"04-08-2016,6",
"secondKey":"Windows 7/Firefox44"
},
{
"value":60,
"key":"05-08-2016,7",
"secondKey":"Windows 7/Firefox44"
},
{
"value":50,
"key":"04-08-2016,8",
"secondKey":"Windows 7/Chrome47"
},
{
"value":40,
"key":"05-08-2016,9",
"secondKey":"Windows 7/Chrome47"
},
{
"value":80,
"key":"04-08-2016,10",
"secondKey":"Windows 7/Firefox45"
},
{
"value":60,
"key":"05-08-2016,11",
"secondKey":"Windows 7/Firefox45"
},
{
"value":0,
"key":"04-08-2016,12",
"secondKey":"Windows 7/IE10"
},
{
"value":40,
"key":"05-08-2016,13",
"secondKey":"Windows 7/IE10"
},
{
"value":50,
"key":"04-08-2016,14",
"secondKey":"Windows 7/Firefox42"
}
];
var osLevelData = [
{
"key":"Windows 7/Chrome49",
"values":[
{
"value":100,
"key":"03-08-2016,0",
"secondKey":"Windows 7/Chrome49"
},
{
"value":40,
"key":"04-08-2016,1",
"secondKey":"Windows 7/Chrome49"
},
{
"value":20,
"key":"05-08-2016,2",
"secondKey":"Windows 7/Chrome49"
}
],
"centerBarPosVal":"03-08-2016,0",
"lastBarPosVal":"05-08-2016,2"
},
{
"key":"Windows 7/Chrome50",
"values":[
{
"value":100,
"key":"03-08-2016,3",
"secondKey":"Windows 7/Chrome50"
},
{
"value":27,
"key":"04-08-2016,4",
"secondKey":"Windows 7/Chrome50"
},
{
"value":57,
"key":"05-08-2016,5",
"secondKey":"Windows 7/Chrome50"
}
],
"centerBarPosVal":"03-08-2016,3",
"lastBarPosVal":"05-08-2016,5"
},
{
"key":"Windows 7/Firefox44",
"values":[
{
"value":40,
"key":"04-08-2016,6",
"secondKey":"Windows 7/Firefox44"
},
{
"value":60,
"key":"05-08-2016,7",
"secondKey":"Windows 7/Firefox44"
}
],
"centerBarPosVal":"04-08-2016,6",
"lastBarPosVal":"05-08-2016,7"
},
{
"key":"Windows 7/Chrome47",
"values":[
{
"value":50,
"key":"04-08-2016,8",
"secondKey":"Windows 7/Chrome47"
},
{
"value":40,
"key":"05-08-2016,9",
"secondKey":"Windows 7/Chrome47"
}
],
"centerBarPosVal":"04-08-2016,8",
"lastBarPosVal":"05-08-2016,9"
},
{
"key":"Windows 7/Firefox45",
"values":[
{
"value":80,
"key":"04-08-2016,10",
"secondKey":"Windows 7/Firefox45"
},
{
"value":60,
"key":"05-08-2016,11",
"secondKey":"Windows 7/Firefox45"
}
],
"centerBarPosVal":"04-08-2016,10",
"lastBarPosVal":"05-08-2016,11"
},
{
"key":"Windows 7/IE10",
"values":[
{
"value":0,
"key":"04-08-2016,12",
"secondKey":"Windows 7/IE10"
},
{
"value":40,
"key":"05-08-2016,13",
"secondKey":"Windows 7/IE10"
}
],
"centerBarPosVal":"04-08-2016,12",
"lastBarPosVal":"05-08-2016,13"
},
{
"key":"Windows 7/Firefox42",
"values":[
{
"value":50,
"key":"04-08-2016,14",
"secondKey":"Windows 7/Firefox42"
}
],
"centerBarPosVal":"04-08-2016,14",
"lastBarPosVal":"04-08-2016,14"
}
];
var barColor = "#4A7B9D";
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 40
},
width = 860 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var min_margin = {
top: height,
right: margin.right + 10,
bottom: margin.bottom,
left: margin.left + 10
},
min_height = 10,
min_width = 860 - min_margin.left - min_margin.right;
//first scale
var x = d3.scale.ordinal().rangeRoundBands([0, width], .2);
//second scale
var groupx = d3.scale.ordinal().rangeRoundBands([0, width], .2);
//scroll scale
var min_x = d3.scale.ordinal().rangeRoundBands([0, width], .2);
//y scale
var y = d3.scale.linear().range([height, 0]);
//Add domain for X scale
x.domain(barsData.map(function(d) {
return d.key;
}));
//Add domain for X scale
groupx.domain(osLevelData.map(function(d) {
return d.key;
}));
//scroll domain
min_x.domain(barsData.map(function(d) {
return d.key;
}));
//domain Y
y.domain([0, d3.max(barsData, function(d) {
return d.value;
})]);
//x axis
var xAxis = d3.svg.axis()
.scale(x)
.tickFormat(function(d){
return d.split(",")[0];
})
.orient("bottom");
//group axis
var groupAxis = d3.svg.axis()
.scale(groupx)
.tickFormat(function(d){
return d;
})
.orient("bottom");
//scroll axis
var min_xAxis = d3.svg.axis()
.scale(min_x)
.tickFormat(function(d){
return d;
})
.orient("bottom");
var main_xZoom = d3.scale.linear()
.range([0, width])
.domain([0, width]);
// y axis
var yAxis = d3.svg.axis()
.scale(y)
.tickFormat(function(d){
return d;
})
.orient("left")
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", 800 + margin.top + margin.bottom);
//main g
var main = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
main.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height + min_height + margin.bottom);
// Add the x axis DOM elements
var xDOM = main.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (height + min_height) + ")")
.attr("clip-path", "url(#clip)")
.call(xAxis)
//.selectAll(".tick text")
//.call(wrap, x.rangeBand());
xDOM.selectAll(".tick").append("line")
.attr("class","groupline")
.attr("y2",30)
.attr("transform", function(d,index) {
/*var position;
osLevelData.forEach(function(ddd){
if(ddd.key === d){
position = ddd.lastBarPosVal;
}
})*/
return "translate(" + (x.rangeBand()/2) + ",0)";
//console.log("d ..",d);
});
// Add the group axis DOM elements
var groupDOM = main.append("g")
.attr("class", "x1 axis")
.attr("transform", "translate(0," + (height + min_height + 30) + ")")
.attr("clip-path", "url(#clip)")
.call(groupAxis)
.selectAll(".tick")
.attr("transform", function(d) {
var centerPos;
osLevelData.forEach(function(ddd){
if(ddd.key === d){
centerPos = ddd.centerBarPosVal;
}
})
return "translate(" + (x(centerPos)+(x.rangeBand()/2)) + ",0)";
});
//.selectAll(".tick text")
//.call(wrap, groupx.rangeBand());
groupDOM.append("line")
.attr("class","groupline")
.attr("y2",30)
.attr("transform", function(d) {
var lastPos;
var centerPos;
osLevelData.forEach(function(ddd){
if(ddd.key === d){
lastPos = ddd.lastBarPosVal;
centerPos = ddd.centerBarPosVal;
}
})
return "translate(" + ((x(lastPos)+x.rangeBand()) - (x(centerPos)+(x.rangeBand()/2))) + ",0)";
});
//scroll DOM element
var mini_x_append = main.append("g")
.attr("transform", "translate(0," + (margin.top + height + 60) + ")")
.attr("width", min_width);
main.append("g")
.attr("class", "y axis")
.call(yAxis);
//create group with all bars
main.append("g")
.attr("clip-path", "url(#clip)")
.selectAll(".rect")
.data(barsData)
.enter().append("rect")
.attr("class", "rect")
.attr("x", function(d) {
return x(d.key);
})
.attr("width", x.rangeBand())
.attr("y", function(d) {
return y(d.value);
})
.attr("height", function(d) {
return height - y(d.value);
})
.attr("fill",barColor);
//To display bar value on bars
main.selectAll("text.bar")
.data(barsData)
.enter().append("text")
.attr("class", "bar")
.attr("text-anchor", "middle")
.attr("x", function(d) { return x(d.key) + x.rangeBand()/2; })
.attr("y", function(d) { return y(d.value) - 5; })
.text(function(d) { return d.value+"%"; });
var xBrush = d3.svg.brush().x(min_x).on("brush", xBrushed);
//d3.svg.brush().x(groupx).on("brush", xBrushed);
var x_arc = d3.svg.arc()
.outerRadius(min_height / 2)
.startAngle(0)
.endAngle(function(d, i) {
return i ? -Math.PI : Math.PI;
});
var brush_x_grab = mini_x_append.append("g")
.attr("class", "x brush")
.call(xBrush);
brush_x_grab.selectAll(".resize").append("path")
.attr("transform", "translate(0," + min_height / 2 + ")")
.attr("d", x_arc)
.attr("fill","#FF0000");
brush_x_grab.selectAll("rect").attr("height", min_height).style("visibility","visible").attr("fill","#D3D3D3");
// Called to re-draw the bars on the main chart when the brush on the x axis
// has been altered.
function xBrushed() {
var originalRange = main_xZoom.range();
main_xZoom.domain(xBrush.empty() ? originalRange : xBrush.extent());
x.rangeRoundBands([main_xZoom(originalRange[0]), main_xZoom(originalRange[1])], .2);
groupx.rangeRoundBands([main_xZoom(originalRange[0]), main_xZoom(originalRange[1])], .2);
main.selectAll(".rect")
.data(barsData)
.attr("width", function(d) {
return x.rangeBand();
})
.attr("x", function(d) {
return x(d.key);
});
main.selectAll(".bar")
.data(barsData)
.attr("x", function(d) { return x(d.key) + x.rangeBand()/2; })
.attr("y", function(d) { return y(d.value) - 5; })
.text(function(d) { return d.value+"%"; });
main.select("g.x.axis").call(xAxis).selectAll(".tick .groupline")
.attr("transform", function(d,index) {
return "translate(" + (x.rangeBand()/2) + ",0)";
});
main.select("g.x1.axis").call(groupAxis).selectAll(".tick")
.attr("transform", function(d) {
var centerPos;
osLevelData.forEach(function(ddd){
if(ddd.key === d){
centerPos = ddd.centerBarPosVal;
}
})
return "translate(" + (x(centerPos)+(x.rangeBand()/2)) + ",0)";
})
.selectAll(".tick .groupline")
.attr("transform", function(d) {
var centerPos;
var lastPos;
osLevelData.forEach(function(ddd){
if(ddd.key === d){
lastPos = ddd.lastBarPosVal;
centerPos = ddd.centerBarPosVal;
}
})
return "translate(" + ((x(lastPos)+x.rangeBand()) - (x(centerPos)+(x.rangeBand()/2))) + ",0)";
})
//main.selectAll(
};
// This comes from the example at http://bl.ocks.org/mbostock/7555321
// for wrapping long axis tick labels
function wrap(text, width) {
text.each(function() {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
y = text.attr("y"),
dy = parseFloat(text.attr("dy")),
tspan = text.text(null).append("tspan").attr("x", 0).attr("y", y).attr("dy", dy + "em");
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [word];
tspan = text.append("tspan").attr("x", 0).attr("y", y).attr("dy", ++lineNumber * lineHeight + dy + "em").text(word);
}
}
});
};
// Set the initial brush selections.
// svg.select(".x.brush").call(xBrush.extent(main_xZoom.domain()));
svg.select(".x.brush").call(xBrush.extent([0, 220]));
//svg.select(".y.brush").call(yBrush.extent(mini_y0.domain()));
// Forces a refresh of the brushes and main chart based
// on the selected extents.
xBrushed();
//yBrushed();
function type(d) {
d.frequency = +d.frequency;
return d;
}

/* Styles go here */
g.axis path,
g.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
g.brush rect.extent {
fill-opacity: 0.5;
fill:#FF0000;
}
.resize path {
fill-opacity: 0.2;
}
.bar {
fill: steelblue;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}

<body>
<script src="https://d3js.org/d3.v3.min.js"></script>
<script src="http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
</body>
&#13;