我正在尝试使用画笔来缩放我在d3.js中的自定义图表,但它的表现不应该如此。任何想法可能是错的 这里是js fiddle http://fiddle.jshell.net/saurabh_nitc10/od8gfsd3/9/
就像在这个小提琴http://fiddle.jshell.net/CjaD3/1/中刷完酒吧后走出y轴一样。任何想法现有的小提琴出了什么问题。它不像在缩放后应该做的那样。请帮助。我刚刚更新了小提琴
这是我创建的插件。
(function($) {
$.dualAxis = {};
var xMapObject=[];
var svg = '';
var focus = '';
var tip = '';
function DualAxis(element, options) {
this.$element = $(element);
this.options = options;
this.margin = {top: 20, right: 80, bottom: 30, left: 40},
width = $(this.$element.selector).width() - this.margin.left - this.margin.right,
height = $(this.$element.selector).height() - this.margin.top - this.margin.bottom;
this.options.height = (this.options.height == null? height: this.options.height);
this.options.width = (this.options.width == null? width: this.options.width);
this.rangeMax = this.getMaxX().length*100;
if (this.rangeMax > 14000) this.rangeMax = 14000;
this.enabled = true;
}
DualAxis.prototype = {
draw: function(){
this.options.data.bar.forEach(function(d) {
d.value = +d.value;
});
this.options.data.line.forEach(function(d) {
d.value = +d.value;
});
tip = d3.tip()
.attr('class', 'd3-tip')
.html(function(d) {
var name= xMapObject[d.date];if(name == undefined){name=d.date;}
var table = '<table class="table table-condensed">'
+ '<thead>'
+ '<tr><th colspan="2" style="text-align:center"class="city">'+name+'</th></tr>'
+ '</thead>'
+ '<tbody>'
+ '<tr><td>Total Sales</td><td class="visits">'+d.value+'</td></tr>'
+ '</tbody>'
+ '</table>';
return table;
})
.style({border: '1px solid #fff', 'box-shadow': '1px 1px 4px rgba(0,0,0,0.5)', 'border-radius': 'none','background':'#fff','color':'#555'})
.offset([-12, 0]);
// if(this.options.data.events.length > 1){
// xOffset = (this.options.width/this.options.data.events.length) + 40;
// } else {
// xOffset = this.options.width/2;
// }
xOffset = 62;
svg = this.getSvg();
svg == null ? svg = d3.select(this.$element.selector).append("svg"): svg;
svg = svg
.attr("height", this.options.height+this.margin.bottom+this.margin.top)
.attr("width",this.options.width+this.margin.right+this.margin.left)
.attr('class',this.options.svgClassName);
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", this.options.width)
.attr("height", this.options.height);
focus = svg.append("g").attr("class", "focus").attr("transform", "translate(" + xOffset + "," + 40 + ")");
svg.call(tip);
//this.drawBackground(focus);
this.drawRect(focus,tip);
this.drawXAxis(focus);
this.drawY1Axis(focus);
this.drawY2Axis(focus);
this.drawLine(focus);
this.drawLineLow(focus);
this.drawLineMedium(focus);
this.drawLineHigh(focus);
if (this.options.showLegend)this.drawLegend(focus);
this.zoomBehaviour(focus);
},
drawRect: function(svg,tip){
x = this.getX();
x2 = this.getX();
y1 = this.getY1();
y2 = this.getY2();
height = this.options.height - (this.options.height / 3);
transTime = 0;
if(this.options.animate) transTime = 1000;
svg.selectAll("rect.bar").data(this.options.data.bar).enter().append("rect").attr("class","bar").attr("width", this.options.width/this.options.data.bar.length).attr("x", function (d) {
return x(d.date);
}).attr("y", height).attr("height", 0).style("fill", function (d,i) {
return "#89A54E";
}).on('mouseover', tip.show)
.on('mouseout', tip.hide).transition().duration(transTime).attr("y", function (d) {
if(isNaN(y1(d.value))) return 0;return y1(d.value);
}).attr("height", function (d) {
if(isNaN(y1(d.value))) return 0; return (height - y1(d.value));
}).style("fill", function(d) { return "#89A54E";}).attr("rx","1.5").attr("ry","1.5");
},
drawXAxis:function(svg){
svg.append("g").attr("class", "x axis").attr("transform", "translate(0," + height + ")").call(this.getXAxis()).append("text").attr("transform", "translate(" + xOffset + "," + 40 + ")").style("text-anchor", "end").text(this.options.xAxisText).style("font-weight", "bold");
},
drawY1Axis:function(svg){
svg.append("g").attr("class", "y axis").call(this.getY1Axis()).append("text").attr('id','y1AxisText').attr("transform", "rotate(-90)").attr("y",-36 ).attr("x", -(this.options.height/5)).style("text-anchor", "end").style("fill", "#266866").style("font-weight", "bold").style("letter-spacing", "1px").text(this.options.y1AxisText);
},
drawY2Axis:function(svg){
svg.append("g").attr("class", "y axis").call(this.getY2Axis()).attr("transform", "translate(" + this.options.width + " ,0)") .append("text").attr('id','y2AxisText').attr("transform", "rotate(-90)").attr("y",47 ).attr("x", -(this.options.height/5)).style("text-anchor", "end").style("fill", "#266866").style("font-weight", "bold").style("letter-spacing", "1px").text(this.options.y2AxisText);
},
drawLegend: function(svg){
legend = svg.append("g").attr("class", "legend").attr('transform', 'translate(-30,'+(height+50)+')');
max = d3.max(this.options.values,function(d){return d.length;});
legend.selectAll('rect').data(this.options.values).enter().append("rect").attr("x", function(d,i){return (i*149);}).attr("y", "0").attr("width", 12).attr("height", 12).style("fill", function(d,i){return color(i);});
legend.selectAll('text').data(this.options.values).enter().append("text").attr("x", function (d, i) {return (i*149+15);}).attr("y", "10").text(function (d) {return d;});
},
getSvg: function(){
return this.options.svg;
},
getXAxis:function(){
//var x = d3.scale.ordinal().rangeRoundBands([0, this.options.width], 0);
return d3.svg.axis().scale(x).tickFormat(d3.time.format("%b'%y")).orient("bottom");
//return d3.svg.axis().scale(x).tickValues(x.domain().filter(function(d, i) {return !(i % 10); })).orient("bottom");
},
getY1Axis:function(){
return d3.svg.axis().scale(y1).orient("left").tickFormat(d3.format(".2s"));
},
getY2Axis:function(){
return d3.svg.axis().scale(y2).orient("right").tickFormat(d3.format(".2s"));
},
getMaxX: function(){ //for ordinal we dont know what to scale
return this.options.data.dateForxAxis.map(function (d) {
return d.date;});
},
getMaxY1: function(){
return d3.max(this.options.data.bar, function (d) {return d.value;});
},
getMaxY2: function(){
return d3.max(this.options.data.line, function (d) {return d.value;});
},
getX: function(){
return d3.time.scale().range([0, this.options.width]).domain(d3.extent(this.options.data.dateForxAxis, function(d) { return d.date; }));
},
getY1: function(){
return d3.scale.linear().range([this.options.height - (this.options.height / 3), 0]).domain([0, this.getMaxY1()]);
},
getY2: function(){
return d3.scale.linear().range([this.options.height - (this.options.height / 3), 0]).domain([0, this.getMaxY2()]);
},
drawBackground: function(vis){
vis.append("rect").attr("x", 0).attr("y", 0).attr("width", this.options.width ).attr("height", this.options.height - 50).style("fill", "grey").attr("transform", "translate(0,0)").style("opacity", "0").attr("class","background").attr("id", "background");
},
zoomBehaviour: function(vis){
var that = this;
//zoomBehaviour = d3.behavior.zoom().scaleExtent([1, 1]).on("zoom", zoom);
brush = d3.svg.brush().x(x2).on("brush", brushed);
width = this.options.width;
vis.append("g").attr("class","x brush").call(brush).selectAll("rect").attr("y",-6).attr("height",this.options.height+7);
function brushed(){
x.domain(brush.empty() ? x2.domain() : brush.extent());
vis.selectAll("rect.bar")
.attr("transform", function(d) { return "translate(" + x(d.date) + ",0)"; })
vis.select(".x.axis").call(that.getXAxis());
//vis.select(".line").attr("d", that.getLine());
}
},
drawLine:function(svg){
svg.append('path').datum(this.options.data.line).attr("class", "line").attr("d", this.getLine());
},
getLine:function(){
return d3.svg.line().interpolate("basis") .x(function(d) {return x(d.date); }).y(function(d) { return y2(d.value); });
},
drawLineLow:function(svg){
svg.append('path').datum(this.options.data.future).attr("class", "lineLow").attr("d", this.getLineLow()).style("stroke-dasharray", ("3, 3"));
},
getLineLow:function(){
return d3.svg.line().interpolate("basis") .x(function(d) {return x(d.date); }).y(function(d) { return y2(d.low); });
},
drawLineMedium:function(svg){
svg.append('path').datum(this.options.data.future).attr("class", "lineMedium").attr("d", this.getLineMedium());
},
getLineMedium:function(){
return d3.svg.line().interpolate("basis") .x(function(d) {return x(d.date); }).y(function(d) { return y2(d.medium); });
},
drawLineHigh:function(svg){
svg.append('path').datum(this.options.data.future).attr("class", "lineHigh").attr("d", this.getLineHigh()).style("stroke-dasharray", ("3, 3"));
},
getLineHigh:function(){
return d3.svg.line().interpolate("basis") .x(function(d) {return x(d.date); }).y(function(d) { return y2(d.high); });
},
};
$.fn.dualAxis = function(options){
options = $.extend({}, $.fn.dualAxis.defaults, options);
if(options.data === '' || options.data === null){
var err = 'dualAxis Error: Data Attribute Cannot be Empty or Null.';
(typeof(console) != 'undefined' && console.error) ?
console.error(err) :
alert(err);
}
function elementOptions(ele, options) {
return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
};
function get(ele) {
var gb = $.data(ele, 'gb');
if (!gb) {
gb = new DualAxis(ele,elementOptions(ele, options));
$.data(ele, 'gb', gb);
}
return gb;
}
var gb = get(this);
gb.draw();
};
$.fn.dualAxis.defaults = {
svgClassName: "dualAxis",
svg: null,
xAxisText: 'x-axis',
y1AxisText: 'y1-axis',
y2AxisText: 'y2-axis',
maxX: null,
maxyY: null,
height:null,
width:null,
animate: true,
color: ["#3366cc", "#dc3912", "#ff9900", "#109618"],
showLegend:true,
data: '',
};
})(jQuery);
这是数据的格式
{
"bar": [
{
"date": "50_2012",
"value": "88787"
},
{
"date": "155_2012",
"value": "50573"
},
{
"date": "155_2013",
"value": "5057"
}
],
"dateForxAxis": [
{
"date": "45_2012"
},
{
"date": "155_2012"
},
{
"date": "260_2013"
}
],
"future": [
{
"high": "87878",
"medium": "55535",
"low": "1212"
},
{
"high": "187878",
"medium": "255535",
"low": "14212"
}
],
"line": [
{
"date": "50_2012",
"value": "8787"
},
{
"date": "60_2012",
"value": "47474"
},
{
"date": "168_2012",
"value": "49474"
}
]
};
调用插件
$('#dualAxis').dualAxis({
data: viewData1,
xAxisText: 'Time',
y1AxisText:'Transactions',
y2AxisText:'Sales',
animate:true,
showLegend:false
});
请建议我做错了什么。当它缩放时,它应该缩放甚至线条和其他三条线。
答案 0 :(得分:1)
在拉丝方法中,您正在平移条形而不是设置新的x位置(使它们根据图形外部的原始x位置进行平移)。在拉丝方法中重新设置x位置将在缩放时正确放置条:
vis.selectAll("rect.bar").attr("x", function (d) {
return x(d.date);
});
你的jsfiddle的一个分支,在http://fiddle.jshell.net/brendaz/zr6kkgaa/
处有这个变化答案 1 :(得分:0)
除了你没有在brushed()函数中更新rect.bar元素的宽度外,每件事看起来都很好。你只是更新x坐标。在您的情况下,rect.bar元素宽度始终是常量。而且我还注意到,当你拖动画笔时,由于左侧和右侧的额外填充(可能是故意的),元素会离开受限区域。
所以只需解决问题,你就可以了。