我的d3可视化问题有些问题。我正在尝试做一个显示15年以上发展的折线图。
第一个问题是x轴不会根据变焦进行缩放。 我用它来开始: http://bl.ocks.org/mbostock/4dc8736fb1ce9799c6d6 但我不知道为什么我的轴不会变焦。
其次,轴标签错误,应该是周和年(例如01-2016)
最后一项:如果缺少某些数据,我有哪些机会,例如2013年的数据?我可以在图表中休息一下,以便今年只有一个空白区域吗?
这是HTML
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="main.css">
<script src="//d3js.org/d3.v3.min.js"></script>
<title>Test Tool</title>
</head>
<body>
<!--MAIN-->
<main>
<!--LINE CHART -->
<script>
// Set the dimensions of the canvas / graph
var margin = {top: 10, right: 20, bottom: 30, left: 50},
width = 1000 - margin.left - margin.right,
height = 570 - margin.top - margin.bottom;
// Set the ranges
var x = d3.time.scale().domain([-width / 2, width / 2])
.range([0, width]);
var y = d3.scale.linear().domain([-height / 2, height / 2])
.range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(10);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
var zoom = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([1, 10])
.on("zoom", zoomed);
var drag = d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
var area = d3.svg.area()
.x(function(d) { return x(d.meldewoche); })
.y0(height)
.y1(function(d) { return y(d.faelle); })
.interpolate("basis");
var areaflip = d3.svg.area()
.x(function(d) { return x(d.meldewoche); })
.y0(height)
.y1(function(d) { return y(-d.faelle); })
.interpolate("basis");
// Define the line
var valueline = d3.svg.line()
.x(function(d) { return x(d.meldewoche); })
.y(function(d) { return y(d.faelle); })
.interpolate("basis");
var valuelineflip = d3.svg.line()
.x(function(d) { return x(d.meldewoche); })
.y(function(d) { return y(-d.faelle); })
.interpolate("basis");
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 + ")")
.call(zoom);
var container = svg.append("g");
var rect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all");
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
// Get the data
d3.csv("data-hanta-gesamt.csv", function(error, data) {
data.forEach(function(d) {
// Parse the date / time
var parseDate = d3.time.format("%W-%Y").parse;
d.meldewoche = parseDate(d.meldewoche);
d.faelle = +d.faelle;
});
// Scale the range of the data
x.domain(d3.extent(data, function(d) { return d.meldewoche; }));
y.domain([0, d3.max(data, function(d) { return d.faelle+550; })]);
// Add the valueline path.
container.append("path")
.attr("class", "line")
.attr("d", valueline(data))
.attr("transform", "translate(0,-265)");
container.append("path")
.attr("class", "lineflip")
.attr("d", valuelineflip(data))
.attr("transform", "translate(0,-265)");
container.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area)
.attr("transform", "translate(0,-265)");
container.append("path")
.datum(data)
.attr("class", "areaflip")
.attr("d", areaflip)
.attr("transform", "translate(0,-265)");
});
//ZOOM
function zoomed() {
container.select(".x axis").call(xAxis);
container.select(".y axis").call(yAxis);
//svg.selectAll('.line').attr('d', line)
container.attr("transform", "translate(" + d3.event.translate[0] + ",0)scale(" + d3.event.scale + ",1)");
}
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
d3.select(this)
.attr("cx", d.x = d3.event.x)
.attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("dragging", false);
}
</script>
</main>
</body>
</html>
CSS:
body {
background: #E1E2DD;
color: #333;
font: 1em/1em "Helvetica Neue";
}
#main {
float: left;
padding: 3em;
width: 65%;
}
#footer {
padding: 1em;
text-align: right;
width:65%;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
stroke-width: 1;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.lineflip {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.area {
fill: lightsteelblue;
stroke-width: 0;
fill-opacity: .67;
}
.areaflip {
fill: lightsteelblue;
stroke-width: 0;
fill-opacity: .67;
}
csv看起来像这样:
meldewoche,faelle
01-2001,2
03-2001,1
04-2001,2
05-2001,2
07-2001,1
08-2001,6
09-2001,1
...
答案 0 :(得分:0)
您只需进行一些小修改即可解决您提到的问题。
问题1:x轴没有缩放以响应缩放。您遇到的问题来自于您更新x-和zoomed
中的y轴。特别是,您当前的代码尝试从container
:
container.select(".x axis").call(xAxis);
container.select(".y axis").call(yAxis);
但是,轴不是container
的子项。此外,您更换了按类&#34;轴&#34;选择轴所需的.
。有空间。如果您选择轴作为svg
的子项并正确设置类选择器,那么您的缩放行为将起作用:
svg.select(".x.axis").call(xAxis);
svg.select(".y.axis").call(yAxis);
问题2:x轴标记错误。此问题源于您在加载数据之前添加x轴的事实。因此,没有使用数据的日期设置x轴的域。
此问题的解决方案是将所有依赖x轴的代码移动到d3.csv
。这样,当您添加轴或甚至缩放时,x轴的刻度x
的域已经正确设置。以下是为我工作的更新后的Javascript。
//设置画布/图形的尺寸 var margin = { 前10名, 右:20, 底部:30, 左:50 }, width = 1000 - margin.left - margin.right, height = 570 - margin.top - margin.bottom;
// Set the ranges
var x = d3.time.scale().domain([-width / 2, width / 2])
.range([0, width]);
var y = d3.scale.linear().domain([-height / 2, height / 2])
.range([height, 0]);
// Define the axes
var xAxis = d3.svg.axis().scale(x)
.orient("bottom").ticks(10);
var yAxis = d3.svg.axis().scale(y)
.orient("left").ticks(5);
// Get the data
d3.csv("data-hanta-gesamt.csv", function(error, data) {
data.forEach(function(d) {
// Parse the date / time
var parseDate = d3.time.format("%W-%Y").parse;
d.meldewoche = parseDate(d.meldewoche);
d.faelle = +d.faelle;
});
var drag = d3.behavior.drag()
.origin(function(d) {
return d;
})
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
var area = d3.svg.area()
.x(function(d) {
return x(d.meldewoche);
})
.y0(height)
.y1(function(d) {
return y(d.faelle);
})
.interpolate("basis");
var areaflip = d3.svg.area()
.x(function(d) {
return x(d.meldewoche);
})
.y0(height)
.y1(function(d) {
return y(-d.faelle);
})
.interpolate("basis");
// Define the line
var valueline = d3.svg.line()
.x(function(d) {
return x(d.meldewoche);
})
.y(function(d) {
return y(d.faelle);
})
.interpolate("basis");
var valuelineflip = d3.svg.line()
.x(function(d) {
return x(d.meldewoche);
})
.y(function(d) {
return y(-d.faelle);
})
.interpolate("basis");
// Scale the range of the data
x.domain(d3.extent(data, function(d) {
return d.meldewoche;
}));
y.domain([0, d3.max(data, function(d) {
return d.faelle + 550;
})]);
var zoom = d3.behavior.zoom()
.x(x)
.y(y)
.scaleExtent([1, 10])
.on("zoom", zoomed);
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 + ")")
.call(zoom);
var container = svg.append("g");
var rect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all");
// Add the Y Axis
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
// Add the X Axis
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
// Add the valueline path.
container.append("path")
.attr("class", "line")
.attr("d", valueline(data))
.attr("transform", "translate(0,-265)");
container.append("path")
.attr("class", "lineflip")
.attr("d", valuelineflip(data))
.attr("transform", "translate(0,-265)");
container.append("path")
.datum(data)
.attr("class", "area")
.attr("d", area)
.attr("transform", "translate(0,-265)");
container.append("path")
.datum(data)
.attr("class", "areaflip")
.attr("d", areaflip)
.attr("transform", "translate(0,-265)");
//ZOOM
function zoomed() {
svg.select(".x.axis").call(xAxis);
svg.select(".y.axis").call(yAxis);
//svg.selectAll('.line').attr('d', line)
container.attr("transform", "translate(" + d3.event.translate[0] + ",0)scale(" + d3.event.scale + ",1)");
}
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
d3.select(this)
.attr("cx", d.x = d3.event.x)
.attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("dragging", false);
}
});