[JS] JavaScript框架(2) D3
D3(Data-Driven Documents)是一个用于网页作图、生成互动图形的JavaScript函数库。
官网:http://d3js.org/
下载:
cdn:<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
d3.zip
1.hello world
1 2 | d3.select( 'body' ) //选择body元素 .append( 'p' ).text( 'hello world' ); //创建p元素,innerText='hello world' |
2.data
1 2 3 4 5 6 7 8 9 10 11 12 13 | <p>1</p> <script> var arr = [1, 2, 3, 7, 6, 5]; var d = d3.select( 'body' ) //选择body .selectAll( 'p' ).data(arr).enter() //选择所有p元素 传入数据 生成一个对象,update属性是一个数组和传入数据元素个数相同 .append( 'p' ); //循环传入数据元素个数多出的次数(这里是6-1次) d.text( function (v, i) { //v代表value i代表index return v; }).style( 'color' , function (v) { if (v > 4) return 'red' ; return 'blue' ; }); </script> |
3.div条形图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <style> .bar { display: inline-block; width: 20px; margin-right: 2px; background-color: teal; } </style> </head> <body> <script> var arr = [10, 20, 30, 70, 60, 50]; var d = d3.select( 'body' ) .selectAll( 'p' ).data(arr).enter() .append( 'div' ); d.attr( 'class' , 'bar' ) .style( 'height' , function (v) { return v*5 + 'px' ; }); </script> </body> |
4.svg
SVG标签包含一些视觉元素,包括矩形,圆形,椭圆形,线条,文字和路径等。基于像素的坐标系统,其中浏览器的左上角是原点(0,0)。x,y的正方向分别是右和下。
svg:<svg width="500" height="200"/>
矩形:<rect x="0" y="0" width="500" height="50"/>
圆形:<circle cx="0" cy="0" r="10"/> cx,cy是圆心坐标,r是半径
椭圆形:<ellipse cx="0" cy="0" rx="100" ry="100"/> cx,cy是一个点的坐标,rx,ry是另一个点的坐标。
线条:<line x1="0" y1="0" x2="100" y2="100" stroke="black"/> x1,y1是一个点的坐标,x2,y2是另一个点的坐标。stroke指定描边使得线是可见的
5.rect条形图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <script> //data var arr = []; for ( var i = 0; i < 20; i++) { var temp = Math.random() * 30; arr.push(Math.round(temp)); //生成30以内的整数 } //svg var w = 600; var h = 100; var pad = 2; var svg = d3.select( 'body' ).append( 'svg' ).attr( 'width' , w).attr( 'height' , h); //rect var rects = svg.selectAll( 'rect' ).data(arr).enter().append( 'rect' ); rects.attr( 'x' , function (v, i) { return (w / (arr.length)) * i; }) //svg width除以元素个数 .attr( 'y' , function (v, i) { return h - v * 3; }) //x、y轴分别在右,下为正方向 .attr( 'width' , function (v, i) { return w / arr.length - pad; }) //x坐标-pad .attr( 'height' , function (v, i) { return v * 3 }) .attr( 'fill' , function (v, i) { return 'rgb(0,0,' + (255 - v) + ')' }); //text var texts = svg.selectAll( 'text' ).data(arr) .enter() .append( "text" ) .text( function (d) { return d; }) .attr( "text-anchor" , "middle" ) .attr( "x" , function (d, i) { return i * (w / arr.length) + (w / arr.length - pad) / 2; }) .attr( "y" , function (d) { return h - (d * 3) + 11; //字体高度 }) .attr( "font-family" , "sans-serif" ) .attr( "font-size" , "11px" ) .attr( "fill" , "white" ); </script> |
6.比例尺
1 2 3 4 5 6 7 8 9 10 11 12 | <script> var arr = [[1, 2], [3, 1], [4, 5]]; d3.max(arr); //默认比较第一个元素 d3.max(arr, function (temp) { return temp[1]; //设置比较第二个元素 }); //比例尺 var s = d3.scale.linear() .domain([0, 20]) //源目标范围 .range([0, 100]); //显示值范围 </script> |
7.坐标轴
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <svg id= "svg" width= "1000" height= "100" ></svg> <script> //data var arr = []; for ( var i = 0; i < 5; i++) { var temp = Math.random() * 30; arr.push(Math.round(temp)); //生成30以内的整数 } //比例尺 var s = d3.scale.linear().domain([0, d3.max(arr)]).range([0, 1000]); //axis var axis = d3.svg.axis().scale(s).orient( 'bottom' ); //绘制坐标轴 var svg = d3.select( 'svg' ); svg.append( 'g' ).call(axis); </script> |
8.自己封装的单柱形图
createZXT()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | function createZXT(svg, arr, colorFn) { var svg = svg ? svg : d3.select( 'body' ).append( 'svg' ).attr( 'width' , 500).attr( 'height' , 100); var arr = arr ? arr : function () { var arr = []; for ( var i = 0; i < 10; i++) { var temp = Math.random() * 30; arr.push(Math.round(temp)); //生成30以内的整数 } return arr; }(); var w = svg.attr( 'width' ), h = svg.attr( 'height' ); var pad = 2; var yScale = d3.scale.linear().domain([0, d3.max(arr)]).range([0, h]); var rects = svg.selectAll( 'rect' ).data(arr).enter().append( 'rect' ); rects.attr( 'x' , function (v, i) { return (w / (arr.length)) * i; }) .attr( 'y' , function (v, i) { return h - yScale(v); }) .attr( 'width' , function (v, i) { return w / arr.length - pad; }) .attr( 'height' , function (v, i) { return yScale(v); }) .attr( 'fill' , function (v, i) { return colorFn ? colorFn(v, i) : 'rgb(0,0,' + (255 - v) + ')' }); var texts = svg.selectAll( 'text' ).data(arr) .enter() .append( "text" ) .text( function (d) { return d; }) .attr( "text-anchor" , "middle" ) .attr( "x" , function (d, i) { return i * (w / arr.length) + (w / arr.length - pad) / 2; }) .attr( "y" , function (v) { return h - yScale(v) + 11; //字体高度 }) .attr( "font-family" , "sans-serif" ) .attr( "font-size" , "11px" ) .attr( "fill" , "white" ); } |
调用:
1 2 3 4 5 6 7 8 9 10 11 12 | //arr var arr = []; for ( var i = 0; i < 15; i++) { var temp = Math.random() * 255; arr.push(Math.round(temp)); } var svg = d3.select( 'svg' ); createZXT(svg, arr, function (v) { //传入颜色函数 return 'rgb(' + (255 - v) + ',0,0)' ; }) createZXT(svg, arr) //传入svg画布,和数据 //函数内部,已处理画布大小和数据的比例尺 |
9.自己封装的双柱形图
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | function creatDB(option) { if (!option) return ; if (!option.container || !option.svgw || !option.svgh || !option.xarr || !option.arr1 || !option.arr2) return ; var svg = d3.select( '#' + option.container).append( 'svg' ) .attr( 'width' , option.svgw) .attr( 'height' , option.svgh); //#region 坐标轴 //比例尺 var xScale = d3.scale.linear().domain([0, option.xarr.length]).range([0, option.svgw]); //axis var axis = d3.svg.axis().scale(xScale).orient( 'bottom' ).ticks(option.xarr.length); //绘制坐标轴 svg.append( "g" ) .attr( "class" , "axis" ) .attr( "transform" , "translate(30,50)" ) .call(axis); //比例尺 var max1 = d3.max(option.arr1); var max2 = d3.max(option.arr2); var maxV = max1 > max2 ? max1 : max2; var yScale = d3.scale.linear().domain([0, maxV]).range([option.svgh, 0]); //axis var ayis = d3.svg.axis().scale(yScale).orient( 'left' ); //绘制坐标轴 svg.append( "g" ) .attr( "class" , "axis" ) .attr( "transform" , "translate(30,50)" ) .call(ayis); //#endregion 坐标轴 var aw = option.svgw / option.xarr.length; var newArr = []; for ( var i = 0; i < arr1.length; i++) { newArr.push(arr1[i]); newArr.push(arr2[i]); } svg.selectAll( 'rect' ).data(newArr).enter().append( 'rect' ) .attr( 'x' , function (v, i) { return aw / 2 * i; }) .attr( 'y' , function (v,i) { return option.svgh - v*10; }) .attr( 'width' , aw / 2) .attr( 'height' , function (v, i) { return v * 10; }) .attr( 'fill' , function (v,i) { return i % 2 == 0 ? 'blue' : 'red' ; }); } |
兼容性问题:
SVG技术不能兼容IE8及更低版本的IE浏览器。如果想要IE8使用d3,请用r2d3.js(一个结合了 Raphael.js的扩展库,用VML解决)
1 2 3 | <!--[if lte IE 8]><script src="r2d3.js" charset="utf-8"></script><![endif]--> <!--[if gte IE 9]><!--> < script src="d3.js"></ script > |
d3 selector对象支持的方法
参考:
http://www.bootcdn.cn/r2d3/
http://blog.csdn.net/tianxuzhang/article/category/1623437
http://www.ourd3js.com/wordpress/?p=396
待续
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义