diff --git a/c3.js b/c3.js index 0ca337f..9c96c17 100644 --- a/c3.js +++ b/c3.js @@ -33,7 +33,8 @@ var __size_width = getConfig(['size','width'], null), __size_height = getConfig(['size','height'], null); - var __zoom_enabled = getConfig(['zoom','enabled'], false); + var __zoom_enabled = getConfig(['zoom','enabled'], false), + __zoom_extent = getConfig(['zoom','extent'], [1, 10]); // data - data configuration checkConfig('data', 'data is required in config'); @@ -362,6 +363,9 @@ } return (domain[1] - domain[0]) / (extent[1] - extent[0]); } + function diffDomain (d) { + return d[1]-d[0]; + } //-- Cache --// @@ -793,13 +797,19 @@ //-- Define brush/zoom -// var brush = d3.svg.brush().on("brush", redrawForBrush); - var zoom = d3.behavior.zoom().on("zoomstart", function(){ zoom.startDomain = d3.event.sourceEvent.altKey ? x.orgDomain() : null; }).on("zoom", __zoom_enabled ? redrawForZoom : null); + var zoom = d3.behavior.zoom().on("zoomstart", function(){ zoom.altDomain = d3.event.sourceEvent.altKey ? x.orgDomain() : null; }).on("zoom", __zoom_enabled ? redrawForZoom : null).scaleExtent(__zoom_extent); // define functions for c3 brush.update = function () { if (context) context.select('.x.brush').call(this); return this; } + zoom.orgScaleExtent = zoom.scaleExtent(); + zoom.updateScaleExtent = function () { + var ratio = diffDomain(x.orgDomain())/diffDomain(orgXDomain); + this.scaleExtent([this.orgScaleExtent[0]*ratio, this.orgScaleExtent[1]*ratio]); + return this; + } /*-- Draw Chart --*/ @@ -1104,7 +1114,7 @@ .call( d3.behavior.drag().origin(Object).on('drag', function(d){ if ( ! __data_selection_enabled) return; // do nothing if not selectable - if (__zoom_enabled && ! zoom.startDomain) return; // skip if zoomable because of conflict drag dehavior + if (__zoom_enabled && ! zoom.altDomain) return; // skip if zoomable because of conflict drag dehavior var sx = dragStart[0], sy = dragStart[1], mouse = d3.mouse(this), @@ -1263,7 +1273,7 @@ // ATTENTION: call here to update tickOffset if (withUpdateXDomain) { x.domain(brush.empty() ? orgXDomain : brush.extent()); - if (__zoom_enabled) zoom.x(x); + if (__zoom_enabled) zoom.x(x).updateScaleExtent(); } y.domain(getYDomain(c3.data.targets, 'y')); y2.domain(getYDomain(c3.data.targets, 'y2')); @@ -1461,11 +1471,14 @@ }); } function redrawForZoom() { - if (d3.event.sourceEvent.type === 'mousemove' && zoom.startDomain) { - x.domain(zoom.startDomain); - zoom.x(x); + if (d3.event.sourceEvent.type === 'mousemove' && zoom.altDomain) { + x.domain(zoom.altDomain); + zoom.x(x).updateScaleExtent(); return; } + if (isCategorized && x.orgDomain()[0] === orgXDomain[0]) { + x.domain([orgXDomain[0]-1e-10, x.orgDomain()[1]]); + } redraw({ withTransition: false, withY: false, diff --git a/c3.min.js b/c3.min.js index 33bbda1..4289e7d 100644 --- a/c3.min.js +++ b/c3.min.js @@ -1,64 +1,65 @@ -(function(xb){function jc(){function l(b,h){b.attr("transform",function(b){return"translate("+(h(b)+S)+",0)"})}function s(b,h){b.attr("transform",function(b){return"translate(0,"+h(b)+")"})}function Oa(b){var h=b[0];b=b[b.length-1];return ha?0:a}function ca(a){var c=Ea[a.id];a.name=l(c)?c:a.id;return a}function wa(a){var c=a[0],d={},n=[],f,b;for(f=1;fw[d].indexOf(f.id)))for(b=0;b=g;g+=diffx2)p+=b(a[f-1],a[f],g,u);return p}function pb(a){var c=k.data.targets=da(a),d,b;O();S();m.domain(d3.extent(a.map(function(a){return a.x}))); -y.domain(C(c,"y"));P.domain(C(c,"y2"));V.domain(m.domain());Qa.domain(y.domain());Ra.domain(P.domain());M.ticks(10>a.length?a.length:10);ga.ticks(Ic).outerTickSize(0).tickFormat(Jc);Sa.ticks(Kc).outerTickSize(0).tickFormat(Lc);za=m.domain();F.x(V);pa&&N.x(m);Ha=d3.select(ya).append("svg").attr("width",r+H+D).attr("height",t+v+U);Za=Ha.append("defs");Za.append("clipPath").attr("id",qb).append("rect").attr("y",v).attr("width",r).attr("height",t-v);Za.append("clipPath").attr("id","xaxis-clip").append("rect").attr("x", --1).attr("y",-1).attr("width",r+2).attr("height",40);Za.append("clipPath").attr("id","yaxis-clip").append("rect").attr("x",-H+1).attr("y",v-1).attr("width",H).attr("height",t-v+2);g=Ha.append("g").attr("transform",I.main);x=qa?Ha.append("g").attr("transform",I.context):null;ra=sa?Ha.append("g").attr("transform",I.legend):null;Z=d3.select(ya).style("position","relative").append("div").style("position","absolute").style("width","30%").style("z-index","10").style("visibility","hidden");g.append("g").attr("class", -"x axis").attr("clip-path",e?"":"url(#xaxis-clip)").attr("transform",I.x).call(e?ga:M);g.append("g").attr("class","y axis").attr("clip-path",e?"url(#yaxis-clip)":"").call(e?M:ga).append("text").attr("transform","rotate(-90)").attr("dy","1.4em").attr("dx","-.8em").style("text-anchor","end").text(Mc);Gb&&g.append("g").attr("class","y2 axis").attr("transform",I.y2).call(Sa);if(pa)g.append("rect").attr("class","zoom-rect").attr("width",r).attr("height",t).style("opacity",0).call(N).on("dblclick.zoom", -null);d=g.append("g").attr("clip-path",Ia).attr("class","grid");ac&&d.append("g").attr("class","xgrids");rb&&(b=d.append("g").attr("class","xgrid-lines").selectAll(".xgrid-line").data(rb).enter().append("g").attr("class","xgrid-line"),b.append("line").attr("class",function(a){return""+a["class"]}),b.append("text").attr("class",function(a){return""+a["class"]}).attr("text-anchor","end").attr("transform",e?"":"rotate(-90)").attr("dx",e?0:-v).attr("dy",-6).text(function(a){return a.text}));Nc&&d.append("g").attr("class", -"xgrid-focus").append("line").attr("class","xgrid-focus").attr("x1",e?0:-10).attr("x2",e?r:-10).attr("y1",e?-10:v).attr("y2",e?-10:t);bc&&d.append("g").attr("class","ygrids");sb&&d.append("g").attr("class","ygrid-lines").selectAll("ygrid-line").data(sb).enter().append("line").attr("class",function(a){return"ygrid-line "+a["class"]});g.append("g").attr("clip-path",Ia).attr("class","regions");g.append("g").attr("clip-path",Ia).attr("class","chart");g.select(".chart").append("g").attr("class","event-rects").style("fill-opacity", -0).selectAll(".event-rects").data(a).enter().append("rect").attr("class",function(a,c){return"event-rect event-rect-"+c}).style("cursor",function(a){return $&&ia?"pointer":null}).on("mouseover",function(a,c){if(!$a){var d=k.data.targets.map(function(a){return ca(a.values[c])}),b,n;if(0",b,e,f;for(b=0;b"+f+""+e+"";return c+""}),Pc=b(["tooltip","init","show"],!1),ta=b(["tooltip","init","x"],0),gc=b(["tooltip","init","position"],{top:"0px",left:"50px"}),qb=ya.replace("#", -"")+"-clip",Ia="url(#"+qb+")",E="timeseries"===ic,oa="categorized"===ic,vb=null,$a=!1,ub=!1,ea=sa?40:0,ha=d3.time.format(Vc).parse,Q=function(a,c){var b=[],e=null!==c?c:"#1f77b4 #ff7f0e #2ca02c #d62728 #9467bd #8c564b #e377c2 #7f7f7f #bcbd22 #17becf".split(" ");return function(c){if(c in a)return a[c];0<=b.indexOf(c)||b.push(c);return e[b.indexOf(c)%e.length]}}(Wc,Xc),oc=function(){var a=[[d3.time.format("%Y/%-m/%-d"),function(){return!0}],[d3.time.format("%-m/%-d"),function(a){return a.getMonth()}], -[d3.time.format("%-m/%-d"),function(a){return 1!=a.getDate()}],[d3.time.format("%-m/%-d"),function(a){return a.getDay()&&1!=a.getDate()}],[d3.time.format("%I %p"),function(a){return a.getHours()}],[d3.time.format("%I:%M"),function(a){return a.getMinutes()}],[d3.time.format(":%S"),function(a){return a.getSeconds()}],[d3.time.format(".%L"),function(a){return a.getMilliseconds()}]];return function(c){for(var b=a.length-1,e=a[b];!e[1](c);)e=a[--b];return e[0](c)}}(),Db,Ib,Fb,Pa,Hb,Jb,r,t,fa,cb,na,Kb, -Lb,fb,gb,m,y,P,V,Qa,Ra,M,ga,Sa,Aa,kc=e?"left":"bottom",lc=e?eb?"top":"bottom":eb?"right":"left",mc=e?db?"bottom":"top":db?"left":"right",nc="bottom",I={main:function(){return"translate("+H+","+v+")"},context:function(){return"translate("+G+","+ua+")"},legend:function(){return"translate("+Oa+","+yb+")"},y2:function(){return"translate("+(e?0:r)+","+(e?10:0)+")"},x:function(){return"translate(0,"+t+")"},subx:function(){return"translate(0,"+fa+")"}},Rc=function(){var a=d3.svg.line().x(e?function(a){return h(a.id)(a.value)}: -Ya).y(e?Ya:function(a){return h(a.id)(a.value)});return function(c){var b;if(nb(c))return"spline"===Y["string"===typeof c?c:c.id]?a.interpolate("cardinal"):a.interpolate("linear"),0b.classes.indexOf(a)})});return J};k.data.get=function(a){a=k.data.getAsTarget(a);return l(a)?a.values.map(function(a){return a.value}): -void 0};k.data.getAsTarget=function(a){var b=Ta(function(b){return b.id==a});return 0a?0:a}function ca(a){var c=Da[a.id];a.name=l(c)?c:a.id;return a}function wa(a){var c=a[0],d={},n=[],f,b;for(f=1;fq[d].indexOf(f.id)))for(b=0;b=g;g+=diffx2)p+=b(a[f-1],a[f],g,h);return p}function ob(a){var c=k.data.targets=da(a),d,b;N();S();m.domain(d3.extent(a.map(function(a){return a.x}))); +x.domain(C(c,"y"));O.domain(C(c,"y2"));V.domain(m.domain());Pa.domain(x.domain());Qa.domain(O.domain());M.ticks(10>a.length?a.length:10);ga.ticks(Hc).outerTickSize(0).tickFormat(Ic);Ra.ticks(Jc).outerTickSize(0).tickFormat(Kc);P=m.domain();F.x(V);pa&&z.x(m);Ga=d3.select(ya).append("svg").attr("width",t+H+D).attr("height",s+v+U);Ya=Ga.append("defs");Ya.append("clipPath").attr("id",pb).append("rect").attr("y",v).attr("width",t).attr("height",s-v);Ya.append("clipPath").attr("id","xaxis-clip").append("rect").attr("x", +-1).attr("y",-1).attr("width",t+2).attr("height",40);Ya.append("clipPath").attr("id","yaxis-clip").append("rect").attr("x",-H+1).attr("y",v-1).attr("width",H).attr("height",s-v+2);g=Ga.append("g").attr("transform",I.main);w=qa?Ga.append("g").attr("transform",I.context):null;ra=sa?Ga.append("g").attr("transform",I.legend):null;Z=d3.select(ya).style("position","relative").append("div").style("position","absolute").style("width","30%").style("z-index","10").style("visibility","hidden");g.append("g").attr("class", +"x axis").attr("clip-path",e?"":"url(#xaxis-clip)").attr("transform",I.x).call(e?ga:M);g.append("g").attr("class","y axis").attr("clip-path",e?"url(#yaxis-clip)":"").call(e?M:ga).append("text").attr("transform","rotate(-90)").attr("dy","1.4em").attr("dx","-.8em").style("text-anchor","end").text(Lc);Fb&&g.append("g").attr("class","y2 axis").attr("transform",I.y2).call(Ra);if(pa)g.append("rect").attr("class","zoom-rect").attr("width",t).attr("height",s).style("opacity",0).call(z).on("dblclick.zoom", +null);d=g.append("g").attr("clip-path",Ha).attr("class","grid");$b&&d.append("g").attr("class","xgrids");qb&&(b=d.append("g").attr("class","xgrid-lines").selectAll(".xgrid-line").data(qb).enter().append("g").attr("class","xgrid-line"),b.append("line").attr("class",function(a){return""+a["class"]}),b.append("text").attr("class",function(a){return""+a["class"]}).attr("text-anchor","end").attr("transform",e?"":"rotate(-90)").attr("dx",e?0:-v).attr("dy",-6).text(function(a){return a.text}));Mc&&d.append("g").attr("class", +"xgrid-focus").append("line").attr("class","xgrid-focus").attr("x1",e?0:-10).attr("x2",e?t:-10).attr("y1",e?-10:v).attr("y2",e?-10:s);ac&&d.append("g").attr("class","ygrids");rb&&d.append("g").attr("class","ygrid-lines").selectAll("ygrid-line").data(rb).enter().append("line").attr("class",function(a){return"ygrid-line "+a["class"]});g.append("g").attr("clip-path",Ha).attr("class","regions");g.append("g").attr("clip-path",Ha).attr("class","chart");g.select(".chart").append("g").attr("class","event-rects").style("fill-opacity", +0).selectAll(".event-rects").data(a).enter().append("rect").attr("class",function(a,c){return"event-rect event-rect-"+c}).style("cursor",function(a){return $&&ja?"pointer":null}).on("mouseover",function(a,c){if(!Za){var d=k.data.targets.map(function(a){return ca(a.values[c])}),b,n;if(0",b,e,f;for(b=0;b"+f+""+e+"";return c+""}), +Oc=b(["tooltip","init","show"],!1),ta=b(["tooltip","init","x"],0),fc=b(["tooltip","init","position"],{top:"0px",left:"50px"}),pb=ya.replace("#","")+"-clip",Ha="url(#"+pb+")",E="timeseries"===hc,ha="categorized"===hc,ub=null,Za=!1,tb=!1,ea=sa?40:0,ia=d3.time.format(Vc).parse,Q=function(a,c){var b=[],e=null!==c?c:"#1f77b4 #ff7f0e #2ca02c #d62728 #9467bd #8c564b #e377c2 #7f7f7f #bcbd22 #17becf".split(" ");return function(c){if(c in a)return a[c];0<=b.indexOf(c)||b.push(c);return e[b.indexOf(c)%e.length]}}(Wc, +Xc),nc=function(){var a=[[d3.time.format("%Y/%-m/%-d"),function(){return!0}],[d3.time.format("%-m/%-d"),function(a){return a.getMonth()}],[d3.time.format("%-m/%-d"),function(a){return 1!=a.getDate()}],[d3.time.format("%-m/%-d"),function(a){return a.getDay()&&1!=a.getDate()}],[d3.time.format("%I %p"),function(a){return a.getHours()}],[d3.time.format("%I:%M"),function(a){return a.getMinutes()}],[d3.time.format(":%S"),function(a){return a.getSeconds()}],[d3.time.format(".%L"),function(a){return a.getMilliseconds()}]]; +return function(c){for(var b=a.length-1,e=a[b];!e[1](c);)e=a[--b];return e[0](c)}}(),Cb,Hb,Eb,Oa,Gb,Ib,t,s,fa,bb,oa,Jb,Kb,eb,fb,m,x,O,V,Pa,Qa,M,ga,Ra,za,jc=e?"left":"bottom",kc=e?db?"top":"bottom":db?"right":"left",lc=e?cb?"bottom":"top":cb?"left":"right",mc="bottom",I={main:function(){return"translate("+H+","+v+")"},context:function(){return"translate("+G+","+ua+")"},legend:function(){return"translate("+Na+","+xb+")"},y2:function(){return"translate("+(e?0:t)+","+(e?10:0)+")"},x:function(){return"translate(0,"+ +s+")"},subx:function(){return"translate(0,"+fa+")"}},Qc=function(){var a=d3.svg.line().x(e?function(a){return h(a.id)(a.value)}:Xa).y(e?Xa:function(a){return h(a.id)(a.value)});return function(c){var b;if(mb(c))return"spline"===Y["string"===typeof c?c:c.id]?a.interpolate("cardinal"):a.interpolate("linear"),0b.classes.indexOf(a)})});return J};k.data.get=function(a){a=k.data.getAsTarget(a);return l(a)?a.values.map(function(a){return a.value}):void 0};k.data.getAsTarget=function(a){var b=Sa(function(b){return b.id==a});return 0