我正在尝试使用画笔在 d3.js 中缩放我的自定义图表,但它没有按应有的方式运行。知道可能出了什么问题 这是 js fiddle http://fiddle.jshell.net/saurabh_nitc10/od8gfsd3/9/
就像这个 fiddle http://fiddle.jshell.net/CjaD3/1/刷完之后,bars 就从 yaxis 出来了。任何想法
现有的 fiddle 有什么问题。缩放后它的行为不正常。请帮忙。我刚刚更新了 fiddle
这是我创建的插件。
(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
});
请提出我做错了什么。当它缩放时,它甚至应该缩放线条和其他三行。
最佳答案
在 brushed 方法中,您正在平移条形图而不是设置新的 x 位置(使它们根据图形外的原始 x 位置进行平移)。在 brushed 方法中重新设置 x 位置将在缩放时正确放置条:
vis.selectAll("rect.bar").attr("x", function (d) {
return x(d.date);
});
在 http://fiddle.jshell.net/brendaz/zr6kkgaa/ 处进行此更改的 jsfiddle 分支
关于javascript - 在折线图+条形图中使用 d3 画笔时出现问题(放大折线图+条形图),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29538926/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
我正在尝试使用ruby和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.
我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h