答案 0 :(得分:2)
我能够使用rect
元素解决此问题,并根据opacity
启用index
。首先,我将yaxis
的所有值都放入一个数组中,这样我就可以为每个y
获取rect
属性,然后将rects
添加到一个组g
中1}}。
// add the Y Axis
svg.append("g").attr('class', 'y axis')
.call(d3.axisLeft(y));
//Store all values of the y-axis to an array
var yval = []
d3.selectAll('.y.axis>g>text').each(function(d) {
yval.push(d);
});
// Create rects and assign opacity based on index
rects.selectAll('rect').data(yval).enter().append('rect')
.attr('x', 0).attr('y', function(d) { return y(d); })
.attr('height', height / yval.length)
.attr('width', width).style('fill-opacity', function(d, i) {
if (i == 0) {
return 0;
}
if (i % 2 == 0) {
return 0.1;
} else {
return 0;
}
});
// set the dimensions and margins of the graph
var margin = {
top: 20,
right: 20,
bottom: 30,
left: 50
},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%d-%b-%y");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.close);
});
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// gridlines in x axis function
function make_x_gridlines() {
return d3.axisBottom(x)
.ticks(5)
}
// gridlines in y axis function
function make_y_gridlines() {
return d3.axisLeft(y)
.ticks(5)
}
// Get the data
var data = [{
"date": "1-May-12",
"close": 58.13
},
{
"date": "30-Apr-12",
"close": 53.98
},
{
"date": "27-Apr-12",
"close": 67
},
{
"date": "26-Apr-12",
"close": 89.7
},
{
"date": "25-Apr-12",
"close": 99
},
{
"date": "24-Apr-12",
"close": 130.28
},
{
"date": "23-Apr-12",
"close": 166.7
},
{
"date": "20-Apr-12",
"close": 234.98
},
{
"date": "19-Apr-12",
"close": 345.44
},
{
"date": "18-Apr-12",
"close": 443.34
},
{
"date": "17-Apr-12",
"close": 543.7
},
{
"date": "16-Apr-12",
"close": 580.13
},
{
"date": "13-Apr-12",
"close": 605.23
},
{
"date": "12-Apr-12",
"close": 622.77
},
{
"date": "11-Apr-12",
"close": 626.2
},
{
"date": "10-Apr-12",
"close": 628.44
},
{
"date": "9-Apr-12",
"close": 636.23
},
{
"date": "5-Apr-12",
"close": 633.68
},
{
"date": "4-Apr-12",
"close": 624.31
},
{
"date": "3-Apr-12",
"close": 629.32
},
{
"date": "2-Apr-12",
"close": 618.63
},
{
"date": "30-Mar-12",
"close": 599.55
},
{
"date": "29-Mar-12",
"close": 609.86
},
{
"date": "28-Mar-12",
"close": 617.62
},
{
"date": "27-Mar-12",
"close": 614.48
},
{
"date": "26-Mar-12",
"close": 606.98
}
]
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.close = +d.close;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) {
return d.date;
}));
y.domain([0, d3.max(data, function(d) {
return d.close;
})]);
// add the X gridlines
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(make_x_gridlines()
.tickSize(-height)
.tickFormat("")
)
// add the Y gridlines
svg.append("g")
.attr("class", "grid")
.call(make_y_gridlines()
.tickSize(-width)
.tickFormat("")
)
var rects = svg.append('g').attr('class', 'intBands')
// add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the Y Axis
svg.append("g").attr('class', 'y axis')
.call(d3.axisLeft(y));
var yval = []
d3.selectAll('.y.axis>g>text').each(function(d) {
yval.push(d);
});
rects.selectAll('rect').data(yval).enter().append('rect')
.attr('x', 0).attr('y', function(d) {
return y(d)
}).attr('height', height / yval.length).attr('width', width).style('fill-opacity', function(d, i) {
if (i == 0) {
return 0;
}
if (i % 2 == 0) {
return 0.1;
} else {
return 0;
}
});

.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
.grid line {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}

<!DOCTYPE html>
<meta charset="utf-8">
<style>
/* set the CSS */
</style>
<body>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
</script>
</body>
&#13;
如果有人有更好的方法,请发布您的解决方案。感谢。
答案 1 :(得分:1)
一种方法是从y轴获取网格线之间的范围,并为每个网格线包含一个矩形:
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%d-%b-%y");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var valueline = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.close); });
// append the svg obgect to the body of the page
// appends a 'group' element to 'svg'
// moves the 'group' element to the top left margin
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// gridlines in x axis function
function make_x_gridlines() {
return d3.axisBottom(x)
.ticks(5)
}
// gridlines in y axis function
function make_y_gridlines() {
return d3.axisLeft(y)
.ticks(5)
}
// Get the data
var data = [
{ date: "1-May-12", close: 58.13 },
{ date: "30-Apr-12", close: 53.98 },
{ date: "27-Apr-12", close: 67.00 },
{ date: "26-Apr-12", close: 89.70 },
{ date: "25-Apr-12", close: 99.00 },
{ date: "24-Apr-12", close: 130.28 },
{ date: "23-Apr-12", close: 166.70 },
{ date: "20-Apr-12", close: 234.98 },
{ date: "19-Apr-12", close: 345.44 },
{ date: "18-Apr-12", close: 443.34 },
{ date: "17-Apr-12", close: 543.70 },
{ date: "16-Apr-12", close: 580.13 },
{ date: "13-Apr-12", close: 605.23 },
{ date: "12-Apr-12", close: 622.77 },
{ date: "11-Apr-12", close: 626.20 },
{ date: "10-Apr-12", close: 628.44 },
{ date: "9-Apr-12", close: 636.23 },
{ date: "5-Apr-12", close: 633.68 },
{ date: "4-Apr-12", close: 624.31 },
{ date: "3-Apr-12", close: 629.32 },
{ date: "2-Apr-12", close: 618.63 },
{ date: "30-Mar-12", close: 599.55 },
{ date: "29-Mar-12", close: 609.86 },
{ date: "28-Mar-12", close: 617.62 },
{ date: "27-Mar-12", close: 614.48 },
{ date: "26-Mar-12", close: 606.98 }
]
// d3.csv("data.csv").then(data) {
// format the data
data.forEach(function(d) {
d.date = parseTime(d.date);
d.close = +d.close;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([0, d3.max(data, function(d) { return d.close; })]);
// add the X gridlines
svg.append("g")
.attr("class", "grid")
.attr("transform", "translate(0," + height + ")")
.call(make_x_gridlines()
.tickSize(-height)
.tickFormat("")
)
// add the Y gridlines
svg.append("g")
.attr("class", "grid ylines")
.call(make_y_gridlines()
.tickSize(-width)
.tickFormat("")
)
// add the valueline path.
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", valueline);
// add the X Axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the Y Axis
svg.append("g")
.call(d3.axisLeft(y));
var bands = [];
var start;
d3.selectAll(".ylines .tick line")
.each(function(d, i) {
if (i % 2 == 0)
start = d;
else {
bands.push({ "start": start, "end": d })
start = null;
}
});
// If it remains the top band:
if (start)
bands.push({ "start": start, "end": d3.max(data, function(d) { return d.close; }) })
svg.append("g").selectAll("band")
.data(bands)
.enter().append("rect")
.attr("y", d => y(d.end))
.attr("height", d => y(d.start) - y(d.end))
.attr("x", d => 0)
.attr("width", d => width)
.style("opacity", 0.1)
.style("stroke", "#005e23")
.style("fill", "#005e23");
// });
&#13;
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
.grid line {
stroke: lightgrey;
stroke-opacity: 0.7;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
&#13;
<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
</body>
&#13;
// Let's retrieve from the grid lines the associated bands y-extremities:
var bands = [];
var start;
d3.selectAll(".ylines .tick line")
.each(function(d, i) {
if (i % 2 == 0)
start = d;
else {
bands.push({ "start": start, "end": d })
start = null; // in order to know if we should use the top band
}
});
// If it remains a top band:
if (start)
bands.push({ "start": start, "end": d3.max(data, function(d) { return d.close; }) })
// Our bands look like:
// [{start: 0,end: 100}, {start: 200,end: 300}, ..., {start: 600,end: 636.23}]
svg.append("g").selectAll("band")
.data(bands)
.enter().append("rect")
.attr("y", d => y(d.end))
.attr("height", d => y(d.start) - y(d.end))
.attr("x", d => 0)
.attr("width", d => width)
.style("opacity", 0.1)
.style("stroke", "#005e23")
.style("fill", "#005e23");
使用网格线而不是刻度线可以选择比网格线更多的刻度。