page.html中:
<!DOCTYPE html>
<!-- https://bl.ocks.org/mbostock/3886208 -->
<style>
#tooltip {
position: absolute;
width: 200px;
height: auto;
padding: 10px;
background-color: white;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
pointer-events: none;
}
.legend {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 60%;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0;
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
}
g[class="col_1"] rect:hover {
fill:#80061b;
}
g[class="col_2"] rect:hover {
fill:#008394;
}
</style>
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.7.0/d3-legend.min.js"></script>
<body>
<div id="tooltip" class="hidden">
<p><strong>Month: </strong><span id="month"></span><p>
<p><strong>Value: </strong><span id="count"></span></p>
</div>
<script>
var margin = {top: 20, right: 20, bottom: 50, left: 80},
width = 1300 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// parse the date / time
// look at the .csv in Notepad! DO NOT LOOK AT EXCEL!
var parseDate = d3.timeParse("%m/%d/%Y");
var x = d3.scaleTime()
.range([0, width - margin.left - margin.right]);
var y = d3.scaleLinear().range([height, 0]);
var z = d3.scaleOrdinal()
.range(["#CE1126", "#00B6D0"]); // red and blue
var xMonthAxis = d3.axisBottom(x)
.ticks(d3.timeMonth.every(1))
.tickFormat(d3.timeFormat("%b")); // label every month
var xYearAxis = d3.axisBottom(x)
.ticks(d3.timeYear.every(1))
.tickFormat(d3.timeFormat("%Y")); // label every year
var yAxis = d3.axisLeft(y).tickFormat(d3.format('.2s'));
var formatNum = d3.format(",")
// load .csv file
d3.csv("test_data.csv", function(d, i, columns) {
for (i = 1, t = 0; i < columns.length; ++i) t += d[columns[i]] = +d[columns[i]];
d.total = t;
return d;
}, function(error, data){
if (error) throw error;
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var keys = data.columns.slice(1);
var barWidth = (width - margin.right- margin.left)/(data.length+1);
data.sort(function(a, b) { return b.date - a.date; });
x.domain(d3.extent( data, function(d){ return d.date }) );
var max = x.domain()[1];
var min = x.domain()[0];
var datePlusOneMonth = d3.timeDay.offset(d3.timeMonth.offset(max, 1), -1); // last day of current month: move up one month, back one day
x.domain([min,datePlusOneMonth]);
y.domain([0, d3.max(data, function(d) { return d.total; })]).nice();
z.domain(keys);
// the bars
g.append("g")
.selectAll("g")
.data(d3.stack().keys(keys)(data))
.enter().append("g")
.attr('class', function(d) { return d.key; })
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("x", function(d) { return x(d.data.date); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", barWidth)
.on("mousemove", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.mouse(this)[0]) + 88;
var yPosition = parseFloat(d3.mouse(this)[1]) - 29;
var value = d.data[d3.select(this.parentNode).attr('class')]; // differentiating between col1 and col2 values
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#count")
.text(formatNum(value)); // return the value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#month")
.text(d3.timeFormat("%B %Y")(d.data.date)); // return the value
//Show the tooltip
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
});
// x-axis
var monthAxis = g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(xMonthAxis);
const firstDataYear = x.domain()[0];
xYearAxis.tickValues([firstDataYear].concat(x.ticks()));
var yearAxis = g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + (height + 25) + ")")
.call(xYearAxis);
var valueAxis = g.append("g")
.attr("class", "axis")
.call(yAxis);
monthAxis.selectAll("g").select("text")
.attr("transform","translate(" + barWidth/2 + ",0)");
var options = d3.keys(data[0]).filter(function(key) { return key !== "date"; }).reverse();
var legend = svg.selectAll(".legend")
.data(options.slice().filter(function(type){ return type != "total"}))
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", z);
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return capitalizeFirstLetter(d); });
});
</script>
</body>
test_data.csv :
date,col_1,col_2
11/1/2012,1977652,1802851
12/1/2012,1128739,948687
1/1/2013,1201944,1514667
2/1/2013,1863148,1834006
3/1/2013,1314851,1906060
4/1/2013,1283943,1978702
5/1/2013,1127964,1195606
6/1/2013,1773254,977214
7/1/2013,1929574,1127450
8/1/2013,1980411,1808161
9/1/2013,1405691,1182788
10/1/2013,1336790,937890
11/1/2013,1851053,1358400
12/1/2013,1472623,1214610
1/1/2014,1155116,1757052
2/1/2014,1571611,1935038
3/1/2014,1898348,1320348
4/1/2014,1444838,1934789
5/1/2014,1235087,950194
6/1/2014,1272040,1580656
7/1/2014,980781,1680164
8/1/2014,1391291,1115999
9/1/2014,1211125,1542148
10/1/2014,1020824,1782795
11/1/2014,1685081,926612
12/1/2014,1469254,1767071
1/1/2015,1168523,935897
2/1/2015,1602610,1450541
3/1/2015,1830278,1354876
4/1/2015,1275158,1412555
5/1/2015,1560961,1839718
6/1/2015,949948,1587130
7/1/2015,1413765,1494446
8/1/2015,1166141,1305105
9/1/2015,958975,1202219
10/1/2015,902696,1023987
11/1/2015,961441,1865628
12/1/2015,1363145,1954046
1/1/2016,1862878,1470741
2/1/2016,1723891,1042760
3/1/2016,1906747,1169012
4/1/2016,1963364,1927063
5/1/2016,1899735,1936915
6/1/2016,1300369,1430697
7/1/2016,1777108,1401210
8/1/2016,1597045,1566763
9/1/2016,1558287,1140057
10/1/2016,1965665,1953595
11/1/2016,1800438,937551
12/1/2016,1689152,1221895
1/1/2017,1607824,1963282
2/1/2017,1878431,1415658
3/1/2017,1730296,1947106
4/1/2017,1956756,1696780
5/1/2017,1746673,1662892
6/1/2017,989702,1537646
7/1/2017,1098812,1592064
8/1/2017,1861973,1892987
9/1/2017,1129596,1406514
10/1/2017,1528632,1725020
11/1/2017,925850,1795575
输出:
期望输出:
我想在此图片上方插入一个滑块,勾勒出上图中显示的月数,如下所示:
用户需要能够使用滑块选择介于1和24之间的整数月份。应始终显示最近一个月(在本例中为Nov 2017
)。滑块将仅显示最近一个月之前的月份数,由滑块中选择的值给出。 (例如,如果从滑块中选择1
,图表将只包含Oct 2017
和Nov 2017
。)
我已经尝试过使用https://bl.ocks.org/officeofjane/9b9e606e9876e34385cc4aeab188ed73的代码,但由于以下原因,这并不能满足我的需求:滑块值和数据中的值不一定对应于过滤(即,月数与要过滤的日期之比)。我确实理解了使用滑块使条形图工作所需的基本思路 - 必须使用exit
和enter
选项。
我不需要一个完整的解决方案,但任何有关如何开始这方面的指导都将受到赞赏。
答案 0 :(得分:2)
好。这是一个带有简单的 jQuery滑块的代码片段(正如我在评论中所建议的那样),过滤掉过去24个月的数据。要显示初始数据,即原始数据,必须将滑块设置为0(无法找到任何其他方法)。您可以使用滑块代码。
var dataAsCsv = `date,col_1,col_2
11/1/2012,1977652,1802851
12/1/2012,1128739,948687
1/1/2013,1201944,1514667
2/1/2013,1863148,1834006
3/1/2013,1314851,1906060
4/1/2013,1283943,1978702
5/1/2013,1127964,1195606
6/1/2013,1773254,977214
7/1/2013,1929574,1127450
8/1/2013,1980411,1808161
9/1/2013,1405691,1182788
10/1/2013,1336790,937890
11/1/2013,1851053,1358400
12/1/2013,1472623,1214610
1/1/2014,1155116,1757052
2/1/2014,1571611,1935038
3/1/2014,1898348,1320348
4/1/2014,1444838,1934789
5/1/2014,1235087,950194
6/1/2014,1272040,1580656
7/1/2014,980781,1680164
8/1/2014,1391291,1115999
9/1/2014,1211125,1542148
10/1/2014,1020824,1782795
11/1/2014,1685081,926612
12/1/2014,1469254,1767071
1/1/2015,1168523,935897
2/1/2015,1602610,1450541
3/1/2015,1830278,1354876
4/1/2015,1275158,1412555
5/1/2015,1560961,1839718
6/1/2015,949948,1587130
7/1/2015,1413765,1494446
8/1/2015,1166141,1305105
9/1/2015,958975,1202219
10/1/2015,902696,1023987
11/1/2015,961441,1865628
12/1/2015,1363145,1954046
1/1/2016,1862878,1470741
2/1/2016,1723891,1042760
3/1/2016,1906747,1169012
4/1/2016,1963364,1927063
5/1/2016,1899735,1936915
6/1/2016,1300369,1430697
7/1/2016,1777108,1401210
8/1/2016,1597045,1566763
9/1/2016,1558287,1140057
10/1/2016,1965665,1953595
11/1/2016,1800438,937551
12/1/2016,1689152,1221895
1/1/2017,1607824,1963282
2/1/2017,1878431,1415658
3/1/2017,1730296,1947106
4/1/2017,1956756,1696780
5/1/2017,1746673,1662892
6/1/2017,989702,1537646
7/1/2017,1098812,1592064
8/1/2017,1861973,1892987
9/1/2017,1129596,1406514
10/1/2017,1528632,1725020
11/1/2017,925850,1795575`;
// Initialize jQuery slider
$('div#month-slider').slider({
min: 0,
max: 24,
create: function() {
// add value to the handle on slider creation
$(this).find('.ui-slider-handle').html($( this ).slider( "value" ));
},
slide: function(e, ui) {
// change values on slider handle and label based on slider value
$('div.slider-container span.value').html(ui.value);
$(e.target).find('.ui-slider-handle').html(ui.value);
// calculate offset date based on slider value
var offsetDate = ui.value ? d3.timeMonth.offset(datePlusOneMonth, -ui.value) : min;
// set x domain and re-render xAxis
x.domain([offsetDate, datePlusOneMonth]);
g.select('.x.axis').call(xMonthAxis);
g.select('.yearaxis.axis').call(xYearAxis);
// calcuate filtered data based on new offset date, set y axis domain and re-render y axis
var filteredData = data.filter(function(d) { return d.date >= offsetDate; });
y.domain([0, d3.max(filteredData, function(d) { return d.total; })]).nice();
g.select('.y.axis').transition().duration(200).call(yAxis);
// re-render the bars based on new filtered data
// the bars
var bars = g.select("g.bars")
.selectAll("g")
.data(d3.stack().keys(keys)(filteredData));
var barRects = bars.enter().append("g").merge(bars)
.attr('class', function(d) { return d.key; })
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; });
barRects.exit().remove();
barRects.enter()
.append("rect");
barWidth = (width - margin.right- margin.left)/(filteredData.length+1);
g.select("g.bars").selectAll('g rect')
.attr("x", function(d) { return x(d.data.date); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", barWidth)
.on("mousemove", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.mouse(this)[0]) + 88;
var yPosition = parseFloat(d3.mouse(this)[1]) - 29;
var value = d.data[d3.select(this.parentNode).attr('class')]; // differentiating between col1 and col2 values
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#count")
.text(formatNum(value)); // return the value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#month")
.text(d3.timeFormat("%B %Y")(d.data.date)); // return the value
//Show the tooltip
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
});
}
})
var margin = {top: 20, right: 20, bottom: 50, left: 80},
width = 1300 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
var g = svg.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// parse the date / time
// look at the .csv in Notepad! DO NOT LOOK AT EXCEL!
var parseDate = d3.timeParse("%m/%d/%Y");
var x = d3.scaleTime()
.range([0, width - margin.left - margin.right]);
var y = d3.scaleLinear().range([height, 0]);
var z = d3.scaleOrdinal()
.range(["#CE1126", "#00B6D0"]); // red and blue
var xMonthAxis = d3.axisBottom(x)
.ticks(d3.timeMonth.every(1))
.tickFormat(d3.timeFormat("%b")); // label every month
var xYearAxis = d3.axisBottom(x)
.ticks(d3.timeMonth.every(6))
.tickFormat(d3.timeFormat("%Y")); // label every year
var yAxis = d3.axisLeft(y).tickFormat(d3.format('.2s'));
var formatNum = d3.format(",")
var data = d3.csvParse(dataAsCsv, function(d, i, columns) {
for (i = 1, t = 0; i < columns.length; ++i) t += d[columns[i]] = +d[columns[i]];
d.total = t;
return d;
});
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var keys = data.columns.slice(1);
var barWidth = (width - margin.right- margin.left)/(data.length+1);
data.sort(function(a, b) { return b.date - a.date; });
x.domain(d3.extent( data, function(d){ return d.date }) );
var max = x.domain()[1];
var min = x.domain()[0];
var datePlusOneMonth = d3.timeDay.offset(d3.timeMonth.offset(max, 1), -1); // last day of current month: move up one month, back one day
x.domain([min,datePlusOneMonth]);
y.domain([0, d3.max(data, function(d) { return d.total; })]).nice();
z.domain(keys);
// the bars
g.append("g").classed('bars', true)
.selectAll("g")
.data(d3.stack().keys(keys)(data))
.enter().append("g")
.attr('class', function(d) { return d.key; })
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("x", function(d) { return x(d.data.date); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", barWidth)
.on("mousemove", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.mouse(this)[0]) + 88;
var yPosition = parseFloat(d3.mouse(this)[1]) - 29;
var value = d.data[d3.select(this.parentNode).attr('class')]; // differentiating between col1 and col2 values
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#count")
.text(formatNum(value)); // return the value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#month")
.text(d3.timeFormat("%B %Y")(d.data.date)); // return the value
//Show the tooltip
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
});
// x-axis
var monthAxis = g.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xMonthAxis);
const firstDataYear = x.domain()[0];
// xYearAxis.tickValues([firstDataYear].concat(x.ticks()));
var yearAxis = g.append("g")
.attr("class", "yearaxis axis")
.attr("transform", "translate(0," + (height + 25) + ")")
.call(xYearAxis);
var valueAxis = g.append("g")
.attr("class", "y axis")
.call(yAxis);
monthAxis.selectAll("g").select("text")
.attr("transform","translate(" + barWidth/2 + ",0)");
var options = d3.keys(data[0]).filter(function(key) { return key !== "date"; }).reverse();
var legend = svg.selectAll(".legend")
.data(options.slice().filter(function(type){ return type != "total"}))
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.style("fill", z);
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.style("text-anchor", "end")
.text(function(d) { return capitalizeFirstLetter(d); });
&#13;
#tooltip {
position: absolute;
width: 200px;
z-index: 2;
height: auto;
padding: 10px;
background-color: white;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
-webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
-moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
pointer-events: none;
}
.legend {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 60%;
}
#tooltip.hidden {
display: none;
}
#tooltip p {
margin: 0;
font-family: sans-serif;
font-size: 16px;
line-height: 20px;
}
g[class="col_1"] rect:hover {
fill:#80061b;
}
g[class="col_2"] rect:hover {
fill:#008394;
}
div.slider-container {
margin: 20px auto;
}
div#month-slider {
width: 50%;
margin: 0 auto;
}
div#month-slider .ui-slider-handle {
text-align: center;
}
&#13;
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script
src="https://code.jquery.com/ui/1.12.0/jquery-ui.min.js"
integrity="sha256-eGE6blurk5sHj+rmkfsGYeKyZx3M4bG+ZlFyA7Kns7E="
crossorigin="anonymous"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3-legend/1.7.0/d3-legend.min.js"></script>
<div id="tooltip" class="hidden">
<p><strong>Month: </strong><span id="month"></span><p>
<p><strong>Value: </strong><span id="count"></span></p>
</div>
<div class="slider-container">
<span>Number of months: <span class="value"></span></span>
<div id="month-slider">
</div>
</div>
&#13;
重要的代码更改:
jQuery滑块,min
值0
且max
值24
(其中0将显示原始数据,1-24
将是最近一次日期(11月17日)的最后一个月的数据。
// Initialize jQuery slider
$('div#month-slider').slider({
min: 0,
max: 24,
create: function() {
// add value to the handle on slider creation
$(this).find('.ui-slider-handle').html($( this ).slider( "value" ));
},
slide: function(e, ui) {
// change values on slider handle and label based on slider value
$('div.slider-container span.value').html(ui.value);
$(e.target).find('.ui-slider-handle').html(ui.value);
// calculate offset date based on slider value
var offsetDate = ui.value ? d3.timeMonth.offset(datePlusOneMonth, -ui.value) : min;
// set x domain and re-render xAxis
x.domain([offsetDate, datePlusOneMonth]);
g.select('.x.axis').call(xMonthAxis);
g.select('.yearaxis.axis').call(xYearAxis);
// calcuate filtered data based on new offset date, set y axis domain and re-render y axis
var filteredData = data.filter(function(d) { return d.date >= offsetDate; });
y.domain([0, d3.max(filteredData, function(d) { return d.total; })]).nice();
g.select('.y.axis').transition().duration(200).call(yAxis);
// re-render the bars based on new filtered data
// the bars
var bars = g.select("g.bars")
.selectAll("g")
.data(d3.stack().keys(keys)(filteredData));
var barRects = bars.enter().append("g").merge(bars)
.attr('class', function(d) { return d.key; })
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; });
barRects.exit().remove();
barRects.enter()
.append("rect");
barWidth = (width - margin.right- margin.left)/(filteredData.length+1);
g.select("g.bars").selectAll('g rect')
.attr("x", function(d) { return x(d.data.date); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", barWidth)
.on("mousemove", function(d) {
//Get this bar's x/y values, then augment for the tooltip
var xPosition = parseFloat(d3.mouse(this)[0]) + 88;
var yPosition = parseFloat(d3.mouse(this)[1]) - 29;
var value = d.data[d3.select(this.parentNode).attr('class')]; // differentiating between col1 and col2 values
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#count")
.text(formatNum(value)); // return the value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#month")
.text(d3.timeFormat("%B %Y")(d.data.date)); // return the value
//Show the tooltip
d3.select("#tooltip").classed("hidden", false);
})
.on("mouseout", function() {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
});
}
})
<强>详细信息:强>
d3.timeMonth.offset
计算偏移日期。其他变化:
为轴添加了其他类以区分它们。 X轴:
.attr("class", "x axis")
X年轴:
.attr("class", "yearaxis axis")
Y轴:
.attr("class", "y axis")
在jQuery滑块上添加了一些CSS:
div.slider-container {
margin: 20px auto;
}
div#month-slider {
width: 50%;
margin: 0 auto;
}
div#month-slider .ui-slider-handle {
text-align: center;
}
z-index
到div#tooltip
。尝试删除它,你就会知道原因。
如果您有任何疑问,请与我们联系。希望这可以帮助。 :)
修改强>
计算barWidth
后,在滑块中添加以下代码
monthAxis.selectAll("g").select("text")
.attr("transform","translate(" + barWidth/2 + ",0)");
我花了一段时间才弄明白,但我提出了一种不同于回答here的方法。通过这种方法,尝试从数据中取出几行,您将观察到乱七八糟的碎片。
因此,在新方法中,tickValues
的{{1}}计算如下:
xYearAxis
即。从 const firstDataYear = x.domain()[0];
var tickValues = x.ticks().filter(function(d) { return !d.getMonth()});
if(firstDataYear.getFullYear() !== tickValues[0].getFullYear()) {
tickValues = [firstDataYear].concat(tickValues);
}
xYearAxis.tickValues(tickValues);
获取所有年份,如果没有,则前置x domain
。我发现这是一种更好的方法。
这是一个演示链接:
如果这解决了问题,请告诉我。