D3.js:缩放时,在2D图形中沿着直线移动圆
D3.js: Moving circles along with line in a 2D graph when zoomed
我目前正在尝试用d3.js绘制时间序列数据。我已经绘制了一条线,并为每个数据点绘制了圆圈(将来圆圈将用于注释特定的数据点)。我正在尝试使用d3.js中的"缩放"行为来缩放所有组件。但我无法沿直线拖动和缩放圆。
我怎样才能沿着直线移动圆圈。以下是代码的jsfiddle:
https://jsfiddle.net/adityap16/4sts8nfs/2/
代码:
var data = [{
"mytime": "2015-12-01T23:10:00.000Z",
"value": 64
}, {
"mytime": "2015-12-01T23:15:00.000Z",
"value": 67
}, {
"mytime": "2015-12-01T23:20:00.000Z",
"value": 70
}, {
"mytime": "2015-12-01T23:25:00.000Z",
"value": 64
}, {
"mytime": "2015-12-01T23:30:00.000Z",
"value": 72
}, {
"mytime": "2015-12-01T23:35:00.000Z",
"value": 75
}, {
"mytime": "2015-12-01T23:40:00.000Z",
"value": 71
}, {
"mytime": "2015-12-01T23:45:00.000Z",
"value": 80
}, {
"mytime": "2015-12-01T23:50:00.000Z",
"value": 83
}, {
"mytime": "2015-12-01T23:55:00.000Z",
"value": 86
}, {
"mytime": "2015-12-02T00:00:00.000Z",
"value": 80
}, {
"mytime": "2015-12-02T00:05:00.000Z",
"value": 85
}];
var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ").parse;
data.forEach(function(d) {
d.mytime = parseDate(d.mytime);
});
//var margin = { top: 30, right: 30, bottom: 40, left:50 },
var margin = {
top: 30,
right: 30,
bottom: 40,
left: 50
},
height = 200,
width = 900;
var color = "green";
var xaxis_param = "mytime";
var yaxis_param = "value";
var params1 = {
margin: margin,
height: height,
width: width,
color: color,
xaxis_param: xaxis_param,
yaxis_param: yaxis_param
};
draw_graph(data, params1);
function draw_graph(data, params) {
var make_x_axis = function() {
return d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.ticks(5);
};
var make_y_axis = function() {
return d3.svg.axis()
.scale(y_scale)
.orient("left")
.ticks(5);
};
//Get the margin
var xaxis_param = params.xaxis_param;
var yaxis_param = params.yaxis_param;
var color_code = params.color;
var margin = params.margin;
var height = params.height - margin.top - margin.bottom,
width = params.width - margin.left - margin.right;
var x_extent = d3.extent(data, function(d) {
return d[xaxis_param]
});
var y_extent = d3.extent(data, function(d) {
return d[yaxis_param]
});
var x_scale = d3.time.scale()
.domain(x_extent)
.range([0, width]);
var y_scale = d3.scale.linear()
.domain([0, y_extent[1]])
.range([height, 0]);
var zoom = d3.behavior.zoom()
.x(x_scale)
.y(y_scale)
.on("zoom", zoomed);
//Line
var line = d3.svg.line()
.defined(function(d) {
return d[yaxis_param];
})
.x(function(d) {
return x_scale(d[xaxis_param]);
})
.y(function(d) {
return y_scale(d[yaxis_param]);
});
var lineRef = d3.svg.line()
.x(function(d) {
return x_scale(d[xaxis_param]);
})
.y(function(d) {
return y_scale(20);
});
var myChart = d3.select('body').append('svg')
.attr('id', 'graph')
.style('background', '#E7E0CB')
.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);
myChart.append("svg:rect")
.attr("width", width)
.attr("height", height)
.attr("class", "plot");
var legend = myChart.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + 5 + "," + (height - 25) + ")")
legend.append("rect")
.style("fill", color_code)
.attr("width", 20)
.attr("height", 20);
legend.append("text")
.text(yaxis_param)
.attr("x", 25)
.attr("y", 12);
var vAxis = d3.svg.axis()
.scale(y_scale)
.orient('left')
.ticks(5)
var hAxis = d3.svg.axis()
.scale(x_scale)
.orient('bottom')
.ticks(5);
var majorAxis = d3.svg.axis()
.scale(x_scale)
.orient('bottom')
.ticks(d3.time.day, 1)
.tickSize(-height)
.outerTickSize(0);
myChart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(hAxis);
myChart.append("g")
.attr("class", "x axis major")
.attr("transform", "translate(0," + height + ")")
.call(majorAxis);
myChart.append("g")
.attr("class", "y axis")
.call(vAxis);
var circlePoint = myChart.selectAll('circle')
.data(data)
.enter()
.append("circle");
var circleAttributes = circlePoint
.attr("cx", function (d) { return x_scale(d[xaxis_param]); })
.attr("cy", function (d) { return y_scale(d[yaxis_param]); })
.attr("r", 3)
.style("fill", "none")
.style("stroke", "red");
var clip = myChart.append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height);
var chartBody = myChart.append("g")
.attr("clip-path", "url(#clip)");
chartBody.append("svg:path")
.datum(data)
.attr('class', 'line')
.attr("d", line)
.attr('stroke', color_code)
.attr('stroke-width', 1)
.attr('fill', 'none');
chartBody
.append('svg:path')
.datum(data)
.attr('class', 'line1')
.attr("d", lineRef)
.attr('stroke', 'blue')
.attr('stroke-width', 1)
.style("stroke-dasharray", ("3, 3"))
.attr('fill', 'none');
function zoomed() {
myChart.select(".x.axis").call(hAxis);
myChart.select(".y.axis").call(vAxis);
myChart.select(".x.axis.major").call(majorAxis);
myChart.select(".line")
.attr("class", "line")
.attr("d", line);
myChart.select(".line1")
.attr("class", "line1")
.attr("d", lineRef);
}
}
您只需要在zoomed()
处理程序函数中更新圆的位置:
circlePoint
.attr("cx", function (d) { return x_scale(d[xaxis_param]); })
.attr("cy", function (d) { return y_scale(d[yaxis_param]); });
因为D3的缩放行为将负责更新缩放比例,所以它们可以很容易地用于计算新位置。
请看一下这个片段以获得完整的示例:
var data = [{
"mytime": "2015-12-01T23:10:00.000Z",
"value": 64
}, {
"mytime": "2015-12-01T23:15:00.000Z",
"value": 67
}, {
"mytime": "2015-12-01T23:20:00.000Z",
"value": 70
}, {
"mytime": "2015-12-01T23:25:00.000Z",
"value": 64
}, {
"mytime": "2015-12-01T23:30:00.000Z",
"value": 72
}, {
"mytime": "2015-12-01T23:35:00.000Z",
"value": 75
}, {
"mytime": "2015-12-01T23:40:00.000Z",
"value": 71
}, {
"mytime": "2015-12-01T23:45:00.000Z",
"value": 80
}, {
"mytime": "2015-12-01T23:50:00.000Z",
"value": 83
}, {
"mytime": "2015-12-01T23:55:00.000Z",
"value": 86
}, {
"mytime": "2015-12-02T00:00:00.000Z",
"value": 80
}, {
"mytime": "2015-12-02T00:05:00.000Z",
"value": 85
}];
var parseDate = d3.time.format("%Y-%m-%dT%H:%M:%S.%LZ").parse;
data.forEach(function(d) {
d.mytime = parseDate(d.mytime);
});
//var margin = { top: 30, right: 30, bottom: 40, left:50 },
var margin = {
top: 30,
right: 30,
bottom: 40,
left: 50
},
height = 200,
width = 900;
var color = "green";
var xaxis_param = "mytime";
var yaxis_param = "value";
var params1 = {
margin: margin,
height: height,
width: width,
color: color,
xaxis_param: xaxis_param,
yaxis_param: yaxis_param
};
draw_graph(data, params1);
function draw_graph(data, params) {
var make_x_axis = function() {
return d3.svg.axis()
.scale(x_scale)
.orient("bottom")
.ticks(5);
};
var make_y_axis = function() {
return d3.svg.axis()
.scale(y_scale)
.orient("left")
.ticks(5);
};
//Get the margin
var xaxis_param = params.xaxis_param;
var yaxis_param = params.yaxis_param;
var color_code = params.color;
var margin = params.margin;
var height = params.height - margin.top - margin.bottom,
width = params.width - margin.left - margin.right;
var x_extent = d3.extent(data, function(d) {
return d[xaxis_param]
});
var y_extent = d3.extent(data, function(d) {
return d[yaxis_param]
});
var x_scale = d3.time.scale()
.domain(x_extent)
.range([0, width]);
var y_scale = d3.scale.linear()
.domain([0, y_extent[1]])
.range([height, 0]);
var zoom = d3.behavior.zoom()
.x(x_scale)
.y(y_scale)
.on("zoom", zoomed);
//Line
var line = d3.svg.line()
.defined(function(d) {
return d[yaxis_param];
})
.x(function(d) {
return x_scale(d[xaxis_param]);
})
.y(function(d) {
return y_scale(d[yaxis_param]);
});
var lineRef = d3.svg.line()
.x(function(d) {
return x_scale(d[xaxis_param]);
})
.y(function(d) {
return y_scale(20);
});
var myChart = d3.select('body').append('svg')
.attr('id', 'graph')
.style('background', '#E7E0CB')
.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);
myChart.append("svg:rect")
.attr("width", width)
.attr("height", height)
.attr("class", "plot");
var legend = myChart.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + 5 + "," + (height - 25) + ")")
legend.append("rect")
.style("fill", color_code)
.attr("width", 20)
.attr("height", 20);
legend.append("text")
.text(yaxis_param)
.attr("x", 25)
.attr("y", 12);
var vAxis = d3.svg.axis()
.scale(y_scale)
.orient('left')
.ticks(5)
var hAxis = d3.svg.axis()
.scale(x_scale)
.orient('bottom')
.ticks(5);
var majorAxis = d3.svg.axis()
.scale(x_scale)
.orient('bottom')
.ticks(d3.time.day, 1)
.tickSize(-height)
.outerTickSize(0);
myChart.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(hAxis);
myChart.append("g")
.attr("class", "x axis major")
.attr("transform", "translate(0," + height + ")")
.call(majorAxis);
myChart.append("g")
.attr("class", "y axis")
.call(vAxis);
var circlePoint = myChart.selectAll('circle')
.data(data)
.enter()
.append("circle");
var circleAttributes = circlePoint
.attr("cx", function (d) { return x_scale(d[xaxis_param]); })
.attr("cy", function (d) { return y_scale(d[yaxis_param]); })
.attr("r", 3)
.style("fill", "none")
.style("stroke", "red");
var clip = myChart.append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", width)
.attr("height", height);
var chartBody = myChart.append("g")
.attr("clip-path", "url(#clip)");
chartBody.append("svg:path")
.datum(data)
.attr('class', 'line')
.attr("d", line)
.attr('stroke', color_code)
.attr('stroke-width', 1)
.attr('fill', 'none');
chartBody
.append('svg:path')
.datum(data)
.attr('class', 'line1')
.attr("d", lineRef)
.attr('stroke', 'blue')
.attr('stroke-width', 1)
.style("stroke-dasharray", ("3, 3"))
.attr('fill', 'none');
function zoomed() {
myChart.select(".x.axis").call(hAxis);
myChart.select(".y.axis").call(vAxis);
myChart.select(".x.axis.major").call(majorAxis);
myChart.select(".line")
.attr("class", "line")
.attr("d", line);
myChart.select(".line1")
.attr("class", "line1")
.attr("d", lineRef);
circlePoint
.attr("cx", function (d) { return x_scale(d[xaxis_param]); })
.attr("cy", function (d) { return y_scale(d[yaxis_param]); });
}
}
svg {
font: 10px sans-serif;
}
.plot {
fill: rgba(250, 250, 255, 0.6);
}
.axis path,
.axis line {
fill: none;
stroke: black;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
相关文章:
- Canvas Html5绘图应用程序,移动画布会导致重大问题
- 正在SharePoint 2013母版页中添加JQuery移动文件
- 如何在android中使用phonegap将文件从一个文件夹移动/复制到另一个文件夹
- 如何使用phaser使html5游戏在移动设备浏览器上运行
- FabricJs-限制主对象内添加对象的移动区域
- 如何从画布上的某个移动事件中获取X和Y
- 触摸移动时切换到新元素
- 每当您在选择器内移动鼠标时,悬停功能就会重复
- 有没有一个javascript图形绘制库可以进行气球树布局
- 停止jQuery UI滑块移动超过给定值
- 谷歌地图API v3不适用于移动浏览器或PhoneGap
- 如何将chrome扩展功能移植到移动设备(特别是jquery和trello)
- JQuery移动动态分区页面
- XMLHttpRequest在移动设备上的chrome上不起作用
- D3.js:缩放时,在2D图形中沿着直线移动圆
- jqPlot图形在缩放后向右移动
- 移动设备上的动态图形交互:HTML5和Javascript或本地应用程序
- 如何将D3图形移动到初始缩放和0,0位置-重置图形
- 单击时如何移动画布图形
- 使用裁剪器以减小的尺寸缩放和移动图形 - 是我的方法声音