发布时间:2015-01-10 00:00 来源:未知
D3是目前最流行的JavaScript可视化图表库之一,D3的图表类型非常丰富,并且支持SVG格式,因此应用十分广泛,也有很多图表插件基于D3开发,比如MetricsGraphics.js,在D3上构建的数据图表非常强大。
关于D3的具体用法,可以看D3图形库API参考该文。该篇文章主要对介绍一些经典图表的实现效果及代码。
效果图:
index.html代码:
<!DOCTYPE html> <meta charset="utf-8"> <style> svg { font: 10px sans-serif; } .y.axis path { display: none; } .y.axis line { stroke: #fff; stroke-opacity: .2; shape-rendering: crispEdges; } .y.axis .zero line { stroke: #000; stroke-opacity: 1; } .title { font: 300 78px Helvetica Neue; fill: #666; } .birthyear, .age { text-anchor: middle; } .birthyear { fill: #fff; } rect { fill-opacity: .6; fill: #e377c2; } rect:first-child { fill: #1f77b4; } </style> <body> <script src="http://d3js.org/d3.v3.min.js"></script> <script> var margin = {top: 20, right: 40, bottom: 30, left: 20}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom, barWidth = Math.floor(width / 19) - 1; var x = d3.scale.linear() .range([barWidth / 2, width - barWidth / 2]); var y = d3.scale.linear() .range([height, 0]); var yAxis = d3.svg.axis() .scale(y) .orient("right") .tickSize(-width) .tickFormat(function(d) { return Math.round(d / 1e6) + "M"; }); // An SVG element with a bottom-right origin. var svg = d3.select("body").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // A sliding container to hold the bars by birthyear. var birthyears = svg.append("g") .attr("class", "birthyears"); // A label for the current year. var title = svg.append("text") .attr("class", "title") .attr("dy", ".71em") .text(2000); d3.csv("population.csv", function(error, data) { // Convert strings to numbers. data.forEach(function(d) { d.people = +d.people; d.year = +d.year; d.age = +d.age; }); // Compute the extent of the data set in age and years. var age1 = d3.max(data, function(d) { return d.age; }), year0 = d3.min(data, function(d) { return d.year; }), year1 = d3.max(data, function(d) { return d.year; }), year = year1; // Update the scale domains. x.domain([year1 - age1, year1]); y.domain([0, d3.max(data, function(d) { return d.people; })]); // Produce a map from year and birthyear to [male, female]. data = d3.nest() .key(function(d) { return d.year; }) .key(function(d) { return d.year - d.age; }) .rollup(function(v) { return v.map(function(d) { return d.people; }); }) .map(data); // Add an axis to show the population values. svg.append("g") .attr("class", "y axis") .attr("transform", "translate(" + width + ",0)") .call(yAxis) .selectAll("g") .filter(function(value) { return !value; }) .classed("zero", true); // Add labeled rects for each birthyear (so that no enter or exit is required). var birthyear = birthyears.selectAll(".birthyear") .data(d3.range(year0 - age1, year1 + 1, 5)) .enter().append("g") .attr("class", "birthyear") .attr("transform", function(birthyear) { return "translate(" + x(birthyear) + ",0)"; }); birthyear.selectAll("rect") .data(function(birthyear) { return data[year][birthyear] || [0, 0]; }) .enter().append("rect") .attr("x", -barWidth / 2) .attr("width", barWidth) .attr("y", y) .attr("height", function(value) { return height - y(value); }); // Add labels to show birthyear. birthyear.append("text") .attr("y", height - 4) .text(function(birthyear) { return birthyear; }); // Add labels to show age (separate; not animated). svg.selectAll(".age") .data(d3.range(0, age1 + 1, 5)) .enter().append("text") .attr("class", "age") .attr("x", function(age) { return x(year - age); }) .attr("y", height + 4) .attr("dy", ".71em") .text(function(age) { return age; }); // Allow the arrow keys to change the displayed year. window.focus(); d3.select(window).on("keydown", function() { switch (d3.event.keyCode) { case 37: year = Math.max(year0, year - 10); break; case 39: year = Math.min(year1, year + 10); break; } update(); }); function update() { if (!(year in data)) return; title.text(year); birthyears.transition() .duration(750) .attr("transform", "translate(" + (x(year1) - x(year)) + ",0)"); birthyear.selectAll("rect") .data(function(birthyear) { return data[year][birthyear] || [0, 0]; }) .transition() .duration(750) .attr("y", y) .attr("height", function(value) { return height - y(value); }); } });
数据文件:
year,age,sex,people 1850,0,1,1483789 1850,0,2,1450376 1850,5,1,1411067 1850,5,2,1359668 1850,10,1,1260099 1850,10,2,1216114 1850,15,1,1077133 1850,15,2,1110619 1850,20,1,1017281 1850,20,2,1003841 1850,25,1,862547 1850,25,2,799482 1850,30,1,730638 1850,30,2,639636 1850,35,1,588487 1850,35,2,505012 1850,40,1,475911 1850,40,2,428185 1850,45,1,384211 1850,45,2,341254 1850,50,1,321343 1850,50,2,286580 1850,55,1,194080 1850,55,2,187208 1850,60,1,174976 1850,60,2,162236 1850,65,1,106827 1850,65,2,105534 1850,70,1,73677 1850,70,2,71762 1850,75,1,40834 1850,75,2,40229 1850,80,1,23449 1850,80,2,22949 1850,85,1,8186 1850,85,2,10511 1850,90,1,5259 1850,90,2,6569 1860,0,1,2120846 1860,0,2,2092162 1860,5,1,1804467 1860,5,2,1778772 1860,10,1,1612640 1860,10,2,1540350 1860,15,1,1438094 1860,15,2,1495999 1860,20,1,1351121 1860,20,2,1370462 1860,25,1,1217615 1860,25,2,1116373 1860,30,1,1043174 1860,30,2,936055 1860,35,1,866910 1860,35,2,737136 1860,40,1,699434 1860,40,2,616826 1860,45,1,552404 1860,45,2,461739 1860,50,1,456176 1860,50,2,407305 1860,55,1,292417 1860,55,2,267224 1860,60,1,260887 1860,60,2,249735 1860,65,1,149331 1860,65,2,141405 1860,70,1,98465 1860,70,2,101778 1860,75,1,56699 1860,75,2,57597 1860,80,1,29007 1860,80,2,29506 1860,85,1,10434 1860,85,2,14053 1860,90,1,7232 1860,90,2,6622 1870,0,1,2800083 1870,0,2,2717102 1870,5,1,2428469 1870,5,2,2393680 1870,10,1,2427341 1870,10,2,2342670 1870,15,1,1958390 1870,15,2,2077248 1870,20,1,1805303 1870,20,2,1909382 1870,25,1,1509059 1870,25,2,1574285 1870,30,1,1251534 1870,30,2,1275629 1870,35,1,1185336 1870,35,2,1137490 1870,40,1,968861 1870,40,2,944401 1870,45,1,852672 1870,45,2,747916 1870,50,1,736387 1870,50,2,637801 1870,55,1,486036 1870,55,2,407819 1870,60,1,399264 1870,60,2,374801 1870,65,1,260829 1870,65,2,239080 1870,70,1,173364 1870,70,2,165501 1870,75,1,86929 1870,75,2,89540 1870,80,1,47427 1870,80,2,54190 1870,85,1,15891 1870,85,2,19302 1870,90,1,8649 1870,90,2,13068 1880,0,1,3533662 1880,0,2,3421597 1880,5,1,3297503 1880,5,2,3179142 1880,10,1,2911924 1880,10,2,2813550 1880,15,1,2457734 1880,15,2,2527818 1880,20,1,2547780 1880,20,2,2512803 1880,25,1,2119393 1880,25,2,1974241 1880,30,1,1749107 1880,30,2,1596772 1880,35,1,1540772 1880,35,2,1483717 1880,40,1,1237347 1880,40,2,1239435 1880,45,1,1065973 1880,45,2,1003711 1880,50,1,964484 1880,50,2,863012 1880,55,1,679147 1880,55,2,594843 1880,60,1,580298 1880,60,2,526956 1880,65,1,369398 1880,65,2,346303 1880,70,1,255422 1880,70,2,251860 1880,75,1,141628 1880,75,2,143513 1880,80,1,67526 1880,80,2,77290 1880,85,1,22437 1880,85,2,31227 1880,90,1,10272 1880,90,2,15451 1900,0,1,4619544 1900,0,2,4589196 1900,5,1,4465783 1900,5,2,4390483 1900,10,1,4057669 1900,10,2,4001749 1900,15,1,3774846 1900,15,2,3801743 1900,20,1,3694038 1900,20,2,3751061 1900,25,1,3389280 1900,25,2,3236056 1900,30,1,2918964 1900,30,2,2665174 1900,35,1,2633883 1900,35,2,2347737 1900,40,1,2261070 1900,40,2,2004987 1900,45,1,1868413 1900,45,2,1648025 1900,50,1,1571038 1900,50,2,1411981 1900,55,1,1161908 1900,55,2,1064632 1900,60,1,916571 1900,60,2,887508 1900,65,1,672663 1900,65,2,640212 1900,70,1,454747 1900,70,2,440007 1900,75,1,268211 1900,75,2,265879 1900,80,1,127435 1900,80,2,132449 1900,85,1,44008 1900,85,2,48614 1900,90,1,15164 1900,90,2,20093 1910,0,1,5296823 1910,0,2,5287477 1910,5,1,4991803 1910,5,2,4866139 1910,10,1,4650747 1910,10,2,4471887 1910,15,1,4566154 1910,15,2,4592269 1910,20,1,4637632 1910,20,2,4447683 1910,25,1,4257755 1910,25,2,3946153 1910,30,1,3658125 1910,30,2,3295220 1910,35,1,3427518 1910,35,2,3088990 1910,40,1,2860229 1910,40,2,2471267 1910,45,1,2363801 1910,45,2,2114930 1910,50,1,2126516 1910,50,2,1773592 1910,55,1,1508358 1910,55,2,1317651 1910,60,1,1189421 1910,60,2,1090697 1910,65,1,850159 1910,65,2,813868 1910,70,1,557936 1910,70,2,547623 1910,75,1,322679 1910,75,2,350900 1910,80,1,161715 1910,80,2,174315 1910,85,1,59699 1910,85,2,62725 1910,90,1,23929 1910,90,2,28965 1920,0,1,5934792 1920,0,2,5694244 1920,5,1,5789008 1920,5,2,5693960 1920,10,1,5401156 1920,10,2,5293057 1920,15,1,4724365 1920,15,2,4779936 1920,20,1,4549411 1920,20,2,4742632 1920,25,1,4565066 1920,25,2,4529382 1920,30,1,4110771 1920,30,2,3982426 1920,35,1,4081543 1920,35,2,3713810 1920,40,1,3321923 1920,40,2,3059757 1920,45,1,3143891 1920,45,2,2669089 1920,50,1,2546035 1920,50,2,2200491 1920,55,1,1880975 1920,55,2,1674672 1920,60,1,1587549 1920,60,2,1382877 1920,65,1,1095956 1920,65,2,989901 1920,70,1,714618 1920,70,2,690097 1920,75,1,417292 1920,75,2,439465 1920,80,1,187000 1920,80,2,211110 1920,85,1,75991 1920,85,2,92829 1920,90,1,22398 1920,90,2,32085 1930,0,1,5875250 1930,0,2,5662530 1930,5,1,6542592 1930,5,2,6129561 1930,10,1,6064820 1930,10,2,5986529 1930,15,1,5709452 1930,15,2,5769587 1930,20,1,5305992 1930,20,2,5565382 1930,25,1,4929853 1930,25,2,5050229 1930,30,1,4424408 1930,30,2,4455213 1930,35,1,4576531 1930,35,2,4593776 1930,40,1,4075139 1930,40,2,3754022 1930,45,1,3633152 1930,45,2,3396558 1930,50,1,3128108 1930,50,2,2809191 1930,55,1,2434077 1930,55,2,2298614 1930,60,1,1927564 1930,60,2,1783515 1930,65,1,1397275 1930,65,2,1307312 1930,70,1,919045 1930,70,2,918509 1930,75,1,536375 1930,75,2,522716 1930,80,1,246708 1930,80,2,283579 1930,85,1,88978 1930,85,2,109210 1930,90,1,30338 1930,90,2,43483 1940,0,1,5294628 1940,0,2,5124653 1940,5,1,5468378 1940,5,2,5359099 1940,10,1,5960416 1940,10,2,5868532 1940,15,1,6165109 1940,15,2,6193701 1940,20,1,5682414 1940,20,2,5896002 1940,25,1,5438166 1940,25,2,5664244 1940,30,1,5040048 1940,30,2,5171522 1940,35,1,4724804 1940,35,2,4791809 1940,40,1,4437392 1940,40,2,4394061 1940,45,1,4190187 1940,45,2,4050290 1940,50,1,3785735 1940,50,2,3488396 1940,55,1,2972069 1940,55,2,2810000 1940,60,1,2370232 1940,60,2,2317790 1940,65,1,1897678 1940,65,2,1911117 1940,70,1,1280023 1940,70,2,1287711 1940,75,1,713875 1940,75,2,764915 1940,80,1,359418 1940,80,2,414761 1940,85,1,127303 1940,85,2,152131 1940,90,1,42263 1940,90,2,58119 1950,0,1,8211806 1950,0,2,7862267 1950,5,1,6706601 1950,5,2,6450863 1950,10,1,5629744 1950,10,2,5430835 1950,15,1,5264129 1950,15,2,5288742 1950,20,1,5573308 1950,20,2,5854227 1950,25,1,6007254 1950,25,2,6317332 1950,30,1,5676022 1950,30,2,5895178 1950,35,1,5511364 1950,35,2,5696261 1950,40,1,5076985 1950,40,2,5199224 1950,45,1,4533177 1950,45,2,4595842 1950,50,1,4199164 1950,50,2,4147295 1950,55,1,3667351 1950,55,2,3595158 1950,60,1,3035038 1950,60,2,3009768 1950,65,1,2421234 1950,65,2,2548250 1950,70,1,1627920 1950,70,2,1786831 1950,75,1,1006530 1950,75,2,1148469 1950,80,1,511727 1950,80,2,637717 1950,85,1,182821 1950,85,2,242798 1950,90,1,54836 1950,90,2,90766 1960,0,1,10374975 1960,0,2,10146999 1960,5,1,9495503 1960,5,2,9250741 1960,10,1,8563700 1960,10,2,8310764 1960,15,1,6620902 1960,15,2,6617493 1960,20,1,5268384 1960,20,2,5513495 1960,25,1,5311805 1960,25,2,5548259 1960,30,1,5801342 1960,30,2,6090862 1960,35,1,6063063 1960,35,2,6431337 1960,40,1,5657943 1960,40,2,5940520 1960,45,1,5345658 1960,45,2,5516028 1960,50,1,4763364 1960,50,2,4928844 1960,55,1,4170581 1960,55,2,4402878 1960,60,1,3405293 1960,60,2,3723839 1960,65,1,2859371 1960,65,2,3268699 1960,70,1,2115763 1960,70,2,2516479 1960,75,1,1308913 1960,75,2,1641371 1960,80,1,619923 1960,80,2,856952 1960,85,1,253245 1960,85,2,384572 1960,90,1,75908 1960,90,2,135774 1970,0,1,8685121 1970,0,2,8326887 1970,5,1,10411131 1970,5,2,10003293 1970,10,1,10756403 1970,10,2,10343538 1970,15,1,9605399 1970,15,2,9414284 1970,20,1,7729202 1970,20,2,8341830 1970,25,1,6539301 1970,25,2,6903041 1970,30,1,5519879 1970,30,2,5851441 1970,35,1,5396732 1970,35,2,5708021 1970,40,1,5718538 1970,40,2,6129319 1970,45,1,5794120 1970,45,2,6198742 1970,50,1,5298312 1970,50,2,5783817 1970,55,1,4762911 1970,55,2,5222164 1970,60,1,4037643 1970,60,2,4577251 1970,65,1,3142606 1970,65,2,3894827 1970,70,1,2340826 1970,70,2,3138009 1970,75,1,1599269 1970,75,2,2293376 1970,80,1,886155 1970,80,2,1417553 1970,85,1,371123 1970,85,2,658511 1970,90,1,186502 1970,90,2,314929 1980,0,1,8439366 1980,0,2,8081854 1980,5,1,8680730 1980,5,2,8275881 1980,10,1,9452338 1980,10,2,9048483 1980,15,1,10698856 1980,15,2,10410271 1980,20,1,10486776 1980,20,2,10614947 1980,25,1,9624053 1980,25,2,9827903 1980,30,1,8705835 1980,30,2,8955225 1980,35,1,6852069 1980,35,2,7134239 1980,40,1,5692148 1980,40,2,5953910 1980,45,1,5342469 1980,45,2,5697543 1980,50,1,5603709 1980,50,2,6110117 1980,55,1,5485098 1980,55,2,6160229 1980,60,1,4696140 1980,60,2,5456885 1980,65,1,3893510 1980,65,2,4896947 1980,70,1,2857774 1980,70,2,3963441 1980,75,1,1840438 1980,75,2,2951759 1980,80,1,1012886 1980,80,2,1919292 1980,85,1,472338 1980,85,2,1023115 1980,90,1,204148 1980,90,2,499046 1990,0,1,9307465 1990,0,2,8894007 1990,5,1,9274732 1990,5,2,8799955 1990,10,1,8782542 1990,10,2,8337284 1990,15,1,9020572 1990,15,2,8590991 1990,20,1,9436188 1990,20,2,9152644 1990,25,1,10658027 1990,25,2,10587292 1990,30,1,11028712 1990,30,2,11105750 1990,35,1,9853933 1990,35,2,10038644 1990,40,1,8712632 1990,40,2,8928252 1990,45,1,6848082 1990,45,2,7115129 1990,50,1,5553992 1990,50,2,5899925 1990,55,1,4981670 1990,55,2,5460506 1990,60,1,4953822 1990,60,2,5663205 1990,65,1,4538398 1990,65,2,5594108 1990,70,1,3429420 1990,70,2,4610222 1990,75,1,2344932 1990,75,2,3723980 1990,80,1,1342996 1990,80,2,2545730 1990,85,1,588790 1990,85,2,1419494 1990,90,1,238459 1990,90,2,745146 2000,0,1,9735380 2000,0,2,9310714 2000,5,1,10552146 2000,5,2,10069564 2000,10,1,10563233 2000,10,2,10022524 2000,15,1,10237419 2000,15,2,9692669 2000,20,1,9731315 2000,20,2,9324244 2000,25,1,9659493 2000,25,2,9518507 2000,30,1,10205879 2000,30,2,10119296 2000,35,1,11475182 2000,35,2,11635647 2000,40,1,11320252 2000,40,2,11488578 2000,45,1,9925006 2000,45,2,10261253 2000,50,1,8507934 2000,50,2,8911133 2000,55,1,6459082 2000,55,2,6921268 2000,60,1,5123399 2000,60,2,5668961 2000,65,1,4453623 2000,65,2,4804784 2000,70,1,3792145 2000,70,2,5184855 2000,75,1,2912655 2000,75,2,4355644 2000,80,1,1902638 2000,80,2,3221898 2000,85,1,970357 2000,85,2,1981156 2000,90,1,336303 2000,90,2,1064581
效果图:
JavaScript代码:
<!DOCTYPE html> <meta charset="utf-8"> <style> body { font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; width: 960px; height: 500px; position: relative; } form { position: absolute; top: 1em; left: 1em; } path { fill-rule: evenodd; stroke: #333; stroke-width: 2px; } .sun path { fill: #6baed6; } .planet path { fill: #9ecae1; } .annulus path { fill: #c6dbef; } </style> <form> <input type="radio" name="reference" id="ref-annulus"> <label for="ref-annulus">Annulus</label><br> <input type="radio" name="reference" id="ref-planet" checked> <label for="ref-planet">Planets</label><br> <input type="radio" name="reference" id="ref-sun"> <label for="ref-sun">Sun</label> </form> <script src="http://d3js.org/d3.v3.min.js"></script> <script> var width = 960, height = 500, radius = 80, x = Math.sin(2 * Math.PI / 3), y = Math.cos(2 * Math.PI / 3); var offset = 0, speed = 4, start = Date.now(); var svg = d3.select("body").append("svg") .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")scale(.55)") .append("g"); var frame = svg.append("g") .datum({radius: Infinity}); frame.append("g") .attr("class", "annulus") .datum({teeth: 80, radius: -radius * 5, annulus: true}) .append("path") .attr("d", gear); frame.append("g") .attr("class", "sun") .datum({teeth: 16, radius: radius}) .append("path") .attr("d", gear); frame.append("g") .attr("class", "planet") .attr("transform", "translate(0,-" + radius * 3 + ")") .datum({teeth: 32, radius: -radius * 2}) .append("path") .attr("d", gear); frame.append("g") .attr("class", "planet") .attr("transform", "translate(" + -radius * 3 * x + "," + -radius * 3 * y + ")") .datum({teeth: 32, radius: -radius * 2}) .append("path") .attr("d", gear); frame.append("g") .attr("class", "planet") .attr("transform", "translate(" + radius * 3 * x + "," + -radius * 3 * y + ")") .datum({teeth: 32, radius: -radius * 2}) .append("path") .attr("d", gear); d3.selectAll("input[name=reference]") .data([radius * 5, Infinity, -radius]) .on("change", function(radius1) { var radius0 = frame.datum().radius, angle = (Date.now() - start) * speed; frame.datum({radius: radius1}); svg.attr("transform", "rotate(" + (offset += angle / radius0 - angle / radius1) + ")"); }); d3.selectAll("input[name=speed]") .on("change", function() { speed = +this.value; }); function gear(d) { var n = d.teeth, r2 = Math.abs(d.radius), r0 = r2 - 8, r1 = r2 + 8, r3 = d.annulus (r3 = r0, r0 = r1, r1 = r3, r2 + 20) : 20, da = Math.PI / n, a0 = -Math.PI / 2 + (d.annulus Math.PI / n : 0), i = -1, path = ["M", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)]; while (++i < n) path.push( "A", r0, ",", r0, " 0 0,1 ", r0 * Math.cos(a0 += da), ",", r0 * Math.sin(a0), "L", r2 * Math.cos(a0), ",", r2 * Math.sin(a0), "L", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0), "A", r1, ",", r1, " 0 0,1 ", r1 * Math.cos(a0 += da / 3), ",", r1 * Math.sin(a0), "L", r2 * Math.cos(a0 += da / 3), ",", r2 * Math.sin(a0), "L", r0 * Math.cos(a0), ",", r0 * Math.sin(a0)); path.push("M0,", -r3, "A", r3, ",", r3, " 0 0,0 0,", r3, "A", r3, ",", r3, " 0 0,0 0,", -r3, "Z"); return path.join(""); } d3.timer(function() { var angle = (Date.now() - start) * speed, transform = function(d) { return "rotate(" + angle / d.radius + ")"; }; frame.selectAll("path").attr("transform", transform); frame.attr("transform", transform); // frame of reference }); </script>
更多D3相关的内容,可以前往其官方网站查阅。