我正在努力解决这个问题,我正在尝试缩放我的图表,特别是我动态绘制的线条。 在这里,我的小提琴:https://jsfiddle.net/w3j89Lf3/
<link href="http://getbootstrap.com/examples/justified-nav/justified-nav.css" rel="stylesheet">
<style>
.axis path {
fill: none;
stroke: #777;
shape-rendering: crispEdges;
}
.axis text {
font-family: Lato;
font-size: 13px;
}
.legend {
font-size: 14px;
font-weight: bold;
}
.grid .tick {
stroke: lightgrey;
opacity: 0.7;
}
.grid path {
stroke-width: 0;
}
</style>
我的代码适用于x和y轴,但不适用于我的线条,因为您可以在我的“缩放”功能中看到。
<div class="container">
<div class="jumbotron">
<svg id="visualisation" width="1000" height="500"></svg>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script>
function InitChart() {
var data = [{
"Client": "ABC",
"sale": "202",
"year": "2000"
}, {
"Client": "ABC",
"sale": "215",
"year": "2002"
}, {
"Client": "ABC",
"sale": "179",
"year": "2004"
}, {
"Client": "ABC",
"sale": "199",
"year": "2006"
}, {
"Client": "ABC",
"sale": "134",
"year": "2008"
}, {
"Client": "ABC",
"sale": "176",
"year": "2010"
}, {
"Client": "XYZ",
"sale": "100",
"year": "2000"
}, {
"Client": "XYZ",
"sale": "215",
"year": "2002"
}, {
"Client": "XYZ",
"sale": "179",
"year": "2004"
}, {
"Client": "XYZ",
"sale": "199",
"year": "2006"
}, {
"Client": "XYZ",
"sale": "134",
"year": "2008"
}, {
"Client": "XYZ",
"sale": "176",
"year": "2013"
}];
var dataGroup = d3.nest()
.key(function(d) {
return d.Client;
})
.entries(data);
var vis = d3.select("#visualisation"),
WIDTH = 1000,
HEIGHT = 500,
MARGINS = {
top: 50,
right: 20,
bottom: 50,
left: 50
};
//Aggiungi ASSI con scala
xScale = d3.scale.linear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(data, function(d) {
return d.year;
}), d3.max(data, function(d) {
return d.year;
})]),
yScale = d3.scale.linear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(data, function(d) {
return d.sale;
}), d3.max(data, function(d) {
return d.sale;
})]),
xAxis = d3.svg.axis()
.scale(xScale),
yAxis = d3.svg.axis()
.scale(yScale)
.orient("left");
vis.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
//Aggiungi GRID
function make_x_axis() {
return d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(10)
}
function make_y_axis() {
return d3.svg.axis()
.scale(yScale)
.orient("left")
.ticks(10)
}
vis.append("svg:g")
.attr("class", "grid")
.attr("transform", "translate(0," + HEIGHT + ")")
.call( make_x_axis()
.tickSize(-HEIGHT, 0, 0)
.tickFormat("")
)
vis.append("svg:g")
.attr("class", "grid")
.call( make_y_axis()
.tickSize(-WIDTH, 0, 0)
.tickFormat("")
)
var lineGen = d3.svg.line()
.x(function(d) {
return xScale(d.year);
})
.y(function(d) {
return yScale(d.sale);
})
.interpolate("basis"); //linear
lSpace = WIDTH/dataGroup.length;
dataGroup.forEach(function(d, i) {
color = "hsl(" + Math.random() * 360 + ",100%,50%)";
vis.append('svg:path')
.attr('d', lineGen(d.values))
.attr('stroke', color)
.attr('stroke-width', 2)
.attr('id', 'line_'+d.key)
.attr('fill', 'none');
vis.append("text")
.attr("x", (lSpace / 2) + i * lSpace)
.attr("y", HEIGHT)
//.style("stroke", "black")
.style("fill", color)
.attr("class", "legend").on('click', function() {
var active = d.active ? false : true;
var opacity = active ? 0 : 1;
d3.select("#line_" + d.key).style("opacity", opacity);
d.active = active;
})
.text(d.key);
});
function zoomed() {
vis.select(".x.axis").call(xAxis);
vis.select(".y.axis").call(yAxis);
vis.selectAll('path.line').attr("d", function(d) {return line(d.values)}); **-> HERE I WOULD ZOOM/TRANSFORM**
}
var zoom = d3.behavior.zoom()
.x(xScale)
.y(yScale)
.scaleExtent([1, 10])
.on("zoom", zoomed);
vis.call(zoom)
}
InitChart();
</script>
</div>
</div>
答案 0 :(得分:1)
应该改变两件事以使其发挥作用。
首先在缩放功能中,您最终得到一个空的选择,因为路径没有线类。在生成路径时将路线类添加到路径,以使.selectAll('path.line')
工作。
其次,您没有将数据绑定到路径,因此稍后您无法在缩放功能中使用它。如果将匿名函数作为.attr
的第二个参数传递,那么此函数的第一个参数(在您的情况下为d
)将是绑定到选择的数据。要使这条线工作:
vis.selectAll('path.line').attr("d", function(d) {return line(d.values)});
您必须向路径添加数据。一种方法是这样的:
vis.append('svg:path').datum(d)
但是,有一种更好的方法来绑定数据并输入新元素而不是您使用的forEach
循环。我推荐由Scott Murray撰写的this非常有用的教程,解释了d3数据绑定。
以下是更新后的jsfiddle。