charts-d3.min.js 11.9 KB
function D3ScatterPlotMatrix(t,e,i){this.utils=new ChartsD3Utils,this.placeholderSelector=t,this.svg=null,this.defaultConfig={width:void 0,size:200,padding:20,brush:!0,guides:!0,tooltip:!0,ticks:void 0,margin:{left:30,right:30,top:30,bottom:30},x:{orient:"bottom",scale:"linear"},y:{orient:"left",scale:"linear"},dot:{radius:2,color:null,d3ColorCategory:"category10"},variables:{labels:[],keys:[],value:function(t,e){return t[e]}},groups:{key:void 0,includeInPlot:!1}},this.setConfig(i||{}),e&&this.setData(e),this.init()}D3ScatterPlotMatrix.prototype.setData=function(t){return this.data=t,this},D3ScatterPlotMatrix.prototype.setConfig=function(t){return this.config=this.utils.deepExtend({},this.defaultConfig,t),this},D3ScatterPlotMatrix.prototype.initPlot=function(){var t=this,e=this.config.margin,i=this.config;this.plot={x:{},y:{},dot:{color:null}},this.setupVariables(),this.plot.size=i.size;var a=i.width,o=d3.select(this.placeholderSelector).node();if(!a){var l=e.left+e.right+this.plot.variables.length*this.plot.size;a=Math.min(o.getBoundingClientRect().width,l)}var s=a;s||(s=o.getBoundingClientRect().height),this.plot.width=a-e.left-e.right,this.plot.height=s-e.top-e.bottom,void 0===i.ticks&&(i.ticks=this.plot.size/40),this.setupX(),this.setupY(),i.dot.d3ColorCategory&&(this.plot.dot.colorCategory=d3.scale[i.dot.d3ColorCategory]());var r=i.dot.color;return r?(this.plot.dot.colorValue=r,"string"==typeof r||r instanceof String?this.plot.dot.color=r:this.plot.dot.colorCategory&&(this.plot.dot.color=function(e){return t.plot.dot.colorCategory(t.plot.dot.colorValue(e))})):i.groups.key&&(this.plot.dot.color=function(e){return t.plot.dot.colorCategory(e[i.groups.key])}),this},D3ScatterPlotMatrix.prototype.setupVariables=function(){var t=this.config.variables,e=this.data,i=this.plot;i.domainByVariable={},i.variables=t.keys,i.variables&&i.variables.length||(i.variables=this.utils.inferVariables(e,this.config.groups.key,this.config.includeInPlot)),i.labels=[],i.labelByVariable={},i.variables.forEach(function(a,o){i.domainByVariable[a]=d3.extent(e,function(e){return t.value(e,a)});var l=a;t.labels&&t.labels.length>o&&(l=t.labels[o]),i.labels.push(l),i.labelByVariable[a]=l}),void 0,i.subplots=[]},D3ScatterPlotMatrix.prototype.setupX=function(){var t=this.plot,e=t.x,i=this.config;e.value=i.variables.value,e.scale=d3.scale[i.x.scale]().range([i.padding/2,t.size-i.padding/2]),e.map=function(t,i){return e.scale(e.value(t,i))},e.axis=d3.svg.axis().scale(e.scale).orient(i.x.orient).ticks(i.ticks),e.axis.tickSize(t.size*t.variables.length)},D3ScatterPlotMatrix.prototype.setupY=function(){var t=this.plot,e=t.y,i=this.config;e.value=i.variables.value,e.scale=d3.scale[i.y.scale]().range([t.size-i.padding/2,i.padding/2]),e.map=function(t,i){return e.scale(e.value(t,i))},e.axis=d3.svg.axis().scale(e.scale).orient(i.y.orient).ticks(i.ticks),e.axis.tickSize(-t.size*t.variables.length)},D3ScatterPlotMatrix.prototype.drawPlot=function(){function t(t){var i=e.plot;i.subplots.push(t);var o=d3.select(this);i.x.scale.domain(i.domainByVariable[t.x]),i.y.scale.domain(i.domainByVariable[t.y]),o.append("rect").attr("class","mw-frame").attr("x",a.padding/2).attr("y",a.padding/2).attr("width",a.size-a.padding).attr("height",a.size-a.padding),t.update=function(){var t=this,a=o.selectAll("circle").data(e.data);a.enter().append("circle"),a.attr("cx",function(e){return i.x.map(e,t.x)}).attr("cy",function(e){return i.y.map(e,t.y)}).attr("r",e.config.dot.radius),i.dot.color&&a.style("fill",i.dot.color),i.tooltip&&a.on("mouseover",function(e){i.tooltip.transition().duration(200).style("opacity",.9),i.tooltip.html("("+i.x.value(e,t.x)+", "+i.y.value(e,t.y)+")").style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){i.tooltip.transition().duration(500).style("opacity",0)}),a.exit().remove()},t.update()}var e=this,i=e.plot.variables.length,a=this.config;e.svgG.selectAll(".mw-axis-x.mw-axis").data(e.plot.variables).enter().append("g").attr("class","mw-axis-x mw-axis"+(a.guides?"":" mw-no-guides")).attr("transform",function(t,a){return"translate("+(i-a-1)*e.plot.size+",0)"}).each(function(t){e.plot.x.scale.domain(e.plot.domainByVariable[t]),d3.select(this).call(e.plot.x.axis)}),e.svgG.selectAll(".mw-axis-y.mw-axis").data(e.plot.variables).enter().append("g").attr("class","mw-axis-y mw-axis"+(a.guides?"":" mw-no-guides")).attr("transform",function(t,i){return"translate(0,"+i*e.plot.size+")"}).each(function(t){e.plot.y.scale.domain(e.plot.domainByVariable[t]),d3.select(this).call(e.plot.y.axis)}),a.tooltip&&(e.plot.tooltip=this.utils.selectOrAppend(d3.select(e.placeholderSelector),"div.mw-tooltip","div").attr("class","mw-tooltip").style("opacity",0));var o=e.svgG.selectAll(".mw-cell").data(e.utils.cross(e.plot.variables,e.plot.variables)).enter().append("g").attr("class","mw-cell").attr("transform",function(t){return"translate("+(i-t.i-1)*e.plot.size+","+t.j*e.plot.size+")"});a.brush&&this.drawBrush(o),o.each(t),o.filter(function(t){return t.i===t.j}).append("text").attr("x",a.padding).attr("y",a.padding).attr("dy",".71em").text(function(t){return e.plot.labelByVariable[t.x]})},D3ScatterPlotMatrix.prototype.update=function(){this.plot.subplots.forEach(function(t){t.update()})},D3ScatterPlotMatrix.prototype.initSvg=function(){var t=this,e=this.config,i=t.plot.width+e.margin.left+e.margin.right,a=t.plot.height+e.margin.top+e.margin.bottom;t.svg=d3.select(t.placeholderSelector).select("svg"),t.svg.empty()||t.svg.remove(),t.svg=d3.select(t.placeholderSelector).append("svg"),t.svg.attr("width",i).attr("height",a).attr("viewBox","0 0  "+i+" "+a).attr("preserveAspectRatio","xMidYMid meet").attr("class","mw-d3-scatterplot-matrix"),t.svgG=t.svg.append("g").attr("class","mw-container").attr("transform","translate("+e.margin.left+","+e.margin.top+")"),e.width&&!e.height||d3.select(window).on("resize",function(){})},D3ScatterPlotMatrix.prototype.init=function(){var t=this;t.initPlot(),t.initSvg(),t.drawPlot()},D3ScatterPlotMatrix.prototype.drawBrush=function(t){function e(t){s!==this&&(d3.select(s).call(l.clear()),o.plot.x.scale.domain(o.plot.domainByVariable[t.x]),o.plot.y.scale.domain(o.plot.domainByVariable[t.y]),s=this)}function i(t){var e=l.extent();o.svgG.selectAll("circle").classed("hidden",function(i){return e[0][0]>i[t.x]||i[t.x]>e[1][0]||e[0][1]>i[t.y]||i[t.y]>e[1][1]})}function a(){l.empty()&&o.svgG.selectAll(".hidden").classed("hidden",!1)}var o=this,l=d3.svg.brush().x(o.plot.x.scale).y(o.plot.y.scale).on("brushstart",e).on("brush",i).on("brushend",a);t.append("g").call(l);var s};
function D3ScatterPlot(t,e,o){this.utils=new ChartsD3Utils,this.placeholderSelector=t,this.svg=null,this.defaultConfig={width:0,height:0,guides:!1,tooltip:!0,margin:{left:50,right:30,top:30,bottom:50},x:{label:"X",value:function(t){return t[0]},orient:"bottom",scale:"linear"},y:{label:"Y",value:function(t){return t[1]},orient:"left",scale:"linear"},dot:{radius:2,color:"black",d3ColorCategory:"category10"}},e&&this.setData(e),o&&this.setConfig(o),this.init()}D3ScatterPlot.prototype.setData=function(t){return this.data=t,this},D3ScatterPlot.prototype.setConfig=function(t){return this.config=this.utils.deepExtend({},this.defaultConfig,t),this},D3ScatterPlot.prototype.initPlot=function(){var t=this,e=this.config.margin,o=this.config;this.plot={x:{},y:{},dot:{color:null}};var i=o.width,a=d3.select(this.placeholderSelector).node();i||(i=a.getBoundingClientRect().width);var l=o.height;l||(l=a.getBoundingClientRect().height),this.plot.width=i-e.left-e.right,this.plot.height=l-e.top-e.bottom,this.setupX(),this.setupY(),o.dot.d3ColorCategory&&(this.plot.dot.colorCategory=d3.scale[o.dot.d3ColorCategory]());var r=o.dot.color;return r&&(this.plot.dot.colorValue=r,"string"==typeof r||r instanceof String?this.plot.dot.color=r:this.plot.dot.colorCategory&&(this.plot.dot.color=function(e){return t.plot.dot.colorCategory(t.plot.dot.colorValue(e))})),this},D3ScatterPlot.prototype.setupX=function(){var t=this.plot,e=t.x,o=this.config.x;e.value=o.value,e.scale=d3.scale[o.scale]().range([0,t.width]),e.map=function(t){return e.scale(e.value(t))},e.axis=d3.svg.axis().scale(e.scale).orient(o.orient);var i=this.data;t.x.scale.domain([d3.min(i,t.x.value)-1,d3.max(i,t.x.value)+1]),this.config.guides&&e.axis.tickSize(-t.height)},D3ScatterPlot.prototype.setupY=function(){var t=this.plot,e=t.y,o=this.config.y;e.value=o.value,e.scale=d3.scale[o.scale]().range([t.height,0]),e.map=function(t){return e.scale(e.value(t))},e.axis=d3.svg.axis().scale(e.scale).orient(o.orient),this.config.guides&&e.axis.tickSize(-t.width);var i=this.data;t.y.scale.domain([d3.min(i,t.y.value)-1,d3.max(i,t.y.value)+1])},D3ScatterPlot.prototype.draw=function(){this.drawAxisX(),this.drawAxisY(),this.update()},D3ScatterPlot.prototype.drawAxisX=function(){var t=this,e=t.plot,o=this.config.x;t.svgG.append("g").attr("class","mw-axis-x mw-axis"+(t.config.guides?"":" mw-no-guides")).attr("transform","translate(0,"+e.height+")").call(e.x.axis).append("text").attr("class","mw-label").attr("transform","translate("+e.width/2+","+t.config.margin.bottom+")").attr("dy","-1em").style("text-anchor","middle").text(o.label)},D3ScatterPlot.prototype.drawAxisY=function(){var t=this,e=t.plot,o=this.config.y;t.svgG.append("g").attr("class","mw-axis mw-axis-y"+(t.config.guides?"":" mw-no-guides")).call(e.y.axis).append("text").attr("class","mw-label").attr("transform","translate("+-t.config.margin.left+","+e.height/2+")rotate(-90)").attr("dy","1em").style("text-anchor","middle").text(o.label)},D3ScatterPlot.prototype.update=function(){var t=this,e=t.plot,o=this.data,i=t.svgG.selectAll(".mw-dot").data(o);i.enter().append("circle").attr("class","mw-dot"),i.attr("r",t.config.dot.radius).attr("cx",e.x.map).attr("cy",e.y.map),e.tooltip&&i.on("mouseover",function(t){e.tooltip.transition().duration(200).style("opacity",.9),e.tooltip.html("("+e.x.value(t)+", "+e.y.value(t)+")").style("left",d3.event.pageX+5+"px").style("top",d3.event.pageY-28+"px")}).on("mouseout",function(t){e.tooltip.transition().duration(500).style("opacity",0)}),e.dot.color&&i.style("fill",e.dot.color),i.exit().remove()},D3ScatterPlot.prototype.initSvg=function(){var t=this,e=this.config,o=t.plot.width+e.margin.left+e.margin.right,i=t.plot.height+e.margin.top+e.margin.bottom;t.svg=d3.select(t.placeholderSelector).select("svg"),t.svg.empty()||t.svg.remove(),t.svg=d3.select(t.placeholderSelector).append("svg"),t.svg.attr("width",o).attr("height",i).attr("viewBox","0 0  "+o+" "+i).attr("preserveAspectRatio","xMidYMid meet").attr("class","mw-d3-scatterplot"),t.svgG=t.svg.append("g").attr("transform","translate("+e.margin.left+","+e.margin.top+")"),e.tooltip&&(t.plot.tooltip=this.utils.selectOrAppend(d3.select(t.placeholderSelector),"div.mw-tooltip","div").attr("class","mw-tooltip").style("opacity",0)),e.width&&!e.height||d3.select(window).on("resize",function(){})},D3ScatterPlot.prototype.init=function(){var t=this;t.initPlot(),t.initSvg(),t.draw()};
function ChartsD3Utils(){}ChartsD3Utils.prototype.deepExtend=function(t){var r=this;!t&&arguments.length>1&&Array.isArray(arguments[1])&&(t=[]),t=t||{};for(var e=1;e<arguments.length;e++){var n=arguments[e];if(n)for(var i in n)if(n.hasOwnProperty(i)){var o=Array.isArray(t[i]),s=r.isObject(t[i]),a=r.isObject(n[i]);s&&!o&&a?r.deepExtend(t[i],n[i]):t[i]=n[i]}}return t},ChartsD3Utils.prototype.cross=function(t,r){var e,n,i=[],o=t.length,s=r.length;for(e=-1;++e<o;)for(n=-1;++n<s;)i.push({x:t[e],i:e,y:r[n],j:n});return i},ChartsD3Utils.prototype.inferVariables=function(t,r,e){var n=[];if(t.length){var i=t[0];if(i instanceof Array)n=i.map(function(t,r){return r});else if("object"==typeof i)for(var o in i)i.hasOwnProperty(o)&&n.push(o)}if(!e){var s=n.indexOf(r);s>-1&&n.splice(s,1)}return n},ChartsD3Utils.prototype.isObject=function(t){return null!==t&&"object"==typeof t},ChartsD3Utils.prototype.isNumber=function(t){return!isNaN(t)&&"number"==typeof t},ChartsD3Utils.prototype.isFunction=function(t){return"function"==typeof t},ChartsD3Utils.prototype.selectOrAppend=function(t,r,e){var n=t.select(r);return n.empty()?t.append(e||r):n};