1. 前言
2. 联动的饼图与柱形图
图:
本地链接:http://127.0.0.1/Example/case4/pie-bar.html
知识点:
1 <!DOCTYPE html> 2 <meta charset="utf-8"> 3 <style> 4 body{ 5 width:1060px; 6 margin:50px auto; 7 } 8 path { stroke: #fff; } 9 path:hover { opacity:0.9; } 10 rect:hover { fill:blue; } 11 .axis { font: 10px sans-serif; } 12 .legend tr{ border-bottom:1px solid grey; } 13 .legend tr:first-child{ border-top:1px solid grey; } 14 15 .axis path, 16 .axis line { 17 fill: none; 18 stroke: #000; 19 shape-rendering: crispEdges; 20 } 21 22 .x.axis path { display: none; } 23 .legend{ 24 margin-bottom:76px; 25 display:inline-block; 26 border-collapse: collapse; 27 border-spacing: 0px; 28 } 29 .legend td{ 30 padding:4px 5px; 31 vertical-align:bottom; 32 } 33 .legendFreq, .legendPerc{ 34 align:right; 35 width:50px; 36 } 37 38 </style> 39 <body> 40 <div id=‘dashboard‘> 41 </div> 42 <script src="http://d3js.org/d3.v3.min.js"></script> 43 <script> 44 function dashboard(id, fData){ 45 var barColor = ‘steelblue‘; 46 function segColor(c){ return {low:"#807dba", mid:"#e08214",high:"#41ab5d"}[c]; } 47 48 // compute total for each state. 49 fData.forEach(function(d){d.total=d.freq.low+d.freq.mid+d.freq.high;}); 50 51 // function to handle histogram. 52 function histoGram(fD){ 53 var hG={}, hGDim = {t: 60, r: 0, b: 30, l: 0}; 54 hGDim.w = 500 - hGDim.l - hGDim.r, 55 hGDim.h = 300 - hGDim.t - hGDim.b; 56 57 //create svg for histogram. 58 var hGsvg = d3.select(id).append("svg") 59 .attr("width", hGDim.w + hGDim.l + hGDim.r) 60 .attr("height", hGDim.h + hGDim.t + hGDim.b).append("g") 61 .attr("transform", "translate(" + hGDim.l + "," + hGDim.t + ")"); 62 63 // create function for x-axis mapping. 64 var x = d3.scale.ordinal().rangeRoundBands([0, hGDim.w], 0.1) 65 .domain(fD.map(function(d) { return d[0]; })); 66 67 // Add x-axis to the histogram svg. 68 hGsvg.append("g").attr("class", "x axis") 69 .attr("transform", "translate(0," + hGDim.h + ")") 70 .call(d3.svg.axis().scale(x).orient("bottom")); 71 72 // Create function for y-axis map. 73 var y = d3.scale.linear().range([hGDim.h, 0]) 74 .domain([0, d3.max(fD, function(d) { return d[1]; })]); 75 76 // Create bars for histogram to contain rectangles and freq labels. 77 var bars = hGsvg.selectAll(".bar").data(fD).enter() 78 .append("g").attr("class", "bar"); 79 80 //create the rectangles. 81 bars.append("rect") 82 .attr("x", function(d) { return x(d[0]); }) 83 .attr("y", function(d) { return y(d[1]); }) 84 .attr("width", x.rangeBand()) 85 .attr("height", function(d) { return hGDim.h - y(d[1]); }) 86 .attr(‘fill‘,barColor) 87 .on("mouseover",mouseover)// mouseover is defined below. 88 .on("mouseout",mouseout);// mouseout is defined below. 89 90 //Create the frequency labels above the rectangles. 91 bars.append("text").text(function(d){ return d3.format(",")(d[1])}) 92 .attr("x", function(d) { return x(d[0])+x.rangeBand()/2; }) 93 .attr("y", function(d) { return y(d[1])-5; }) 94 .attr("text-anchor", "middle"); 95 96 function mouseover(d){ // utility function to be called on mouseover. 97 // filter for selected state. 98 var st = fData.filter(function(s){ return s.State == d[0];})[0], 99 nD = d3.keys(st.freq).map(function(s){ return {type:s, freq:st.freq[s]};}); 100 101 // call update functions of pie-chart and legend. 102 pC.update(nD); 103 leg.update(nD); 104 } 105 106 function mouseout(d){ // utility function to be called on mouseout. 107 // reset the pie-chart and legend. 108 pC.update(tF); 109 leg.update(tF); 110 } 111 112 // create function to update the bars. This will be used by pie-chart. 113 hG.update = function(nD, color){ 114 // update the domain of the y-axis map to reflect change in frequencies. 115 y.domain([0, d3.max(nD, function(d) { return d[1]; })]); 116 117 // Attach the new data to the bars. 118 var bars = hGsvg.selectAll(".bar").data(nD); 119 120 // transition the height and color of rectangles. 121 bars.select("rect").transition().duration(500) 122 .attr("y", function(d) {return y(d[1]); }) 123 .attr("height", function(d) { return hGDim.h - y(d[1]); }) 124 .attr("fill", color); 125 126 // transition the frequency labels location and change value. 127 bars.select("text").transition().duration(500) 128 .text(function(d){ return d3.format(",")(d[1])}) 129 .attr("y", function(d) {return y(d[1])-5; }); 130 } 131 return hG; 132 } 133 134 // function to handle pieChart. 135 function pieChart(pD){ 136 var pC ={}, pieDim ={w:250, h: 250}; 137 pieDim.r = Math.min(pieDim.w, pieDim.h) / 2; 138 139 // create svg for pie chart. 140 var piesvg = d3.select(id).append("svg") 141 .attr("width", pieDim.w).attr("height", pieDim.h).append("g") 142 .attr("transform", "translate("+pieDim.w/2+","+pieDim.h/2+")"); 143 144 // create function to draw the arcs of the pie slices. 145 var arc = d3.svg.arc().outerRadius(pieDim.r - 10).innerRadius(0); 146 147 // create a function to compute the pie slice angles. 148 var pie = d3.layout.pie().sort(null).value(function(d) { return d.freq; }); 149 150 // Draw the pie slices. 151 piesvg.selectAll("path").data(pie(pD)).enter().append("path").attr("d", arc) 152 .each(function(d) { this._current = d; }) 153 .style("fill", function(d) { return segColor(d.data.type); }) 154 .on("mouseover",mouseover).on("mouseout",mouseout); 155 156 // create function to update pie-chart. This will be used by histogram. 157 pC.update = function(nD){ 158 piesvg.selectAll("path").data(pie(nD)).transition().duration(500) 159 .attrTween("d", arcTween); 160 } 161 // Utility function to be called on mouseover a pie slice. 162 function mouseover(d){ 163 // call the update function of histogram with new data. 164 hG.update(fData.map(function(v){ 165 return [v.State,v.freq[d.data.type]];}),segColor(d.data.type)); 166 } 167 //Utility function to be called on mouseout a pie slice. 168 function mouseout(d){ 169 // call the update function of histogram with all data. 170 hG.update(fData.map(function(v){ 171 return [v.State,v.total];}), barColor); 172 } 173 // Animating the pie-slice requiring a custom function which specifies 174 // how the intermediate paths should be drawn. 175 function arcTween(a) { 176 var i = d3.interpolate(this._current, a); 177 this._current = i(0); 178 return function(t) { return arc(i(t)); }; 179 } 180 return pC; 181 } 182 183 // function to handle legend. 184 function legend(lD){ 185 var leg = {}; 186 187 // create table for legend. 188 var legend = d3.select(id).append("table").attr(‘class‘,‘legend‘); 189 190 // create one row per segment. 191 var tr = legend.append("tbody").selectAll("tr").data(lD).enter().append("tr"); 192 193 // create the first column for each segment. 194 tr.append("td").append("svg").attr("width", ‘16‘).attr("height", ‘16‘).append("rect") 195 .attr("width", ‘16‘).attr("height", ‘16‘) 196 .attr("fill",function(d){ return segColor(d.type); }); 197 198 // create the second column for each segment. 199 tr.append("td").text(function(d){ return d.type;}); 200 201 // create the third column for each segment. 202 tr.append("td").attr("class",‘legendFreq‘) 203 .text(function(d){ return d3.format(",")(d.freq);}); 204 205 // create the fourth column for each segment. 206 tr.append("td").attr("class",‘legendPerc‘) 207 .text(function(d){ return getLegend(d,lD);}); 208 209 // Utility function to be used to update the legend. 210 leg.update = function(nD){ 211 // update the data attached to the row elements. 212 var l = legend.select("tbody").selectAll("tr").data(nD); 213 214 // update the frequencies. 215 l.select(".legendFreq").text(function(d){ return d3.format(",")(d.freq);}); 216 217 // update the percentage column. 218 l.select(".legendPerc").text(function(d){ return getLegend(d,nD);}); 219 } 220 221 function getLegend(d,aD){ // Utility function to compute percentage. 222 return d3.format("%")(d.freq/d3.sum(aD.map(function(v){ return v.freq; }))); 223 } 224 225 return leg; 226 } 227 228 // calculate total frequency by segment for all state. 229 var tF = [‘low‘,‘mid‘,‘high‘].map(function(d){ 230 return {type:d, freq: d3.sum(fData.map(function(t){ return t.freq[d];}))}; 231 }); 232 233 // calculate total frequency by state for all segment. 234 var sF = fData.map(function(d){return [d.State,d.total];}); 235 236 var hG = histoGram(sF), // create the histogram. 237 pC = pieChart(tF), // create the pie-chart. 238 leg= legend(tF); // create the legend. 239 } 240 </script> 241 242 <script> 243 var freqData=[ 244 {State:‘AL‘,freq:{low:4786, mid:1319, high:249}} 245 ,{State:‘AZ‘,freq:{low:1101, mid:412, high:674}} 246 ,{State:‘CT‘,freq:{low:932, mid:2149, high:418}} 247 ,{State:‘DE‘,freq:{low:832, mid:1152, high:1862}} 248 ,{State:‘FL‘,freq:{low:4481, mid:3304, high:948}} 249 ,{State:‘GA‘,freq:{low:1619, mid:167, high:1063}} 250 ,{State:‘IA‘,freq:{low:1819, mid:247, high:1203}} 251 ,{State:‘IL‘,freq:{low:4498, mid:3852, high:942}} 252 ,{State:‘IN‘,freq:{low:797, mid:1849, high:1534}} 253 ,{State:‘KS‘,freq:{low:162, mid:379, high:471}} 254 ]; 255 256 dashboard(‘#dashboard‘,freqData); 257 </script>
时间: 2024-10-24 10:09:10