<del id="d4fwx"><form id="d4fwx"></form></del>
      <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

            <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
          • d3.js實現(xiàn)立體柱圖的方法詳解

            前言

            成都創(chuàng)新互聯(lián)公司主要從事成都做網(wǎng)站、網(wǎng)站建設、網(wǎng)頁設計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務。立足成都服務噶爾,10余年網(wǎng)站建設經(jīng)驗,價格優(yōu)惠、服務專業(yè),歡迎來電咨詢建站服務:18980820575

            眾所周知隨著大數(shù)據(jù)時代的來臨,數(shù)據(jù)可視化的重要性也越來越凸顯,那么今天就基于d3.js今天給大家?guī)砜梢暬A圖表柱圖進階:立體柱圖,之前介紹過了d3.js實現(xiàn)柱狀圖的文章,感興趣的朋友們可以看一看。

            關于d3.js

            d3.js是一個操作svg的圖表庫,d3封裝了圖表的各種算法.對d3不熟悉的朋友可以到d3.js官網(wǎng)學習d3.js.

            另外感謝司機大傻(聲音像張學友一樣性感的一流裝逼手)和司機呆(呆萌女神)等人對d3.js進行翻譯!

            HTML+CSS

            <!DOCTYPE html>
            <html lang="en">
            <head>
             <meta charset="UTF-8">
             <title>Title</title>
             <style>
             * {
             margin: 0;
             padding: 0;
             }
            
             div.tip-hill-div {
             background: rgba(0, 0, 0, 0.7);
             color: #fff;
             padding: 10px;
             border-radius: 5px;
             font-family: Microsoft Yahei;
             }
            
             div.tip-hill-div > h2 {
             font-size: 14px;
             }
            
             div.tip-hill-div > h3 {
             font-size: 12px;
             }
             </style>
            </head>
            <body>
            <div id="chart"></div>
            </body>
            </html>

            JS

            當前使用d3.v4+版本

            <script src="d3-4.js"></script>

            圖表所需數(shù)據(jù)

            var data = [{
             "letter": "白皮雞蛋",
             "child": {
             "category": "0",
             "value": "459.00"
             }
             }, {
             "letter": "紅皮雞蛋",
             "child": {
             "category": "0",
             "value": "389.00"
             }
             }, {
             "letter": "雞蛋",
             "child": {
             "category": "0",
             "value": "336.00"
             }
             }, {
             "letter": "牛肉",
             "child": {
             "category": "0",
             "value": "282.00"
             }
             }, {
             "letter": "羊肉",
             "child": {
             "category": "0",
             "value": "249.00"
             }
             }, {
             "letter": "鴨蛋",
             "child": {
             "category": "0",
             "value": "242.00"
             }
             }, {
             "letter": "紅薯",
             "child": {
             "category": "0",
             "value": "222.00"
             }
             }, {
             "letter": "白菜",
             "child": {
             "category": "0",
             "value": "182.00"
             }
             }, {
             "letter": "雞肉",
             "child": {
             "category": "0",
             "value": "102.00"
             }
             }];

            圖表的一些基礎配置數(shù)據(jù)

            var margin = {
             top: 20,
             right: 50,
             bottom: 50,
             left: 90
             };
            
            var svgWidth = 1000;
            var svgHeight = 500;
            
            
            //創(chuàng)建各個面的顏色數(shù)組
            var mainColorList = ['#f6e242', '#ebec5b', '#d2ef5f', '#b1d894','#97d5ad', '#82d1c0', '#70cfd2', '#63c8ce', '#50bab8', '#38a99d'];
            var topColorList = ['#e9d748', '#d1d252', '#c0d75f', '#a2d37d','#83d09e', '#68ccb6', '#5bc8cb', '#59c0c6', '#3aadab', '#2da094'];
            var rightColorList = ['#dfce51', '#d9db59', '#b9d54a', '#9ece7c','#8ac69f', '#70c3b1', '#65c5c8', '#57bac0', '#42aba9', '#2c9b8f'];
            
            var svg = d3.select('#chart')
             .append('svg')
             .attr('width', svgWidth)
             .attr('height', svgHeight)
             .attr('id', 'svg-column');

            創(chuàng)建X軸序數(shù)比例尺

            function addXAxis() {
             var transform = d3.geoTransform({
             point: function (x, y) {
             this.stream.point(x, y)
             }
             });
             //定義幾何路徑
             var path = d3.geoPath()
             .projection(transform);
            
             xLinearScale = d3.scaleBand()
             .domain(data.map(function (d) {
              return d.letter;
             }))
             .range([0, svgWidth - margin.right - margin.left], 0.1);
             var xAxis = d3.axisBottom(xLinearScale)
             .ticks(data.length);
             //繪制X軸
             var xAxisG = svg.append("g")
             .call(xAxis)
             .attr("transform", "translate(" + (margin.left) + "," + (svgHeight - margin.bottom) + ")");
            
             //刪除原X軸
             xAxisG.select("path").remove();
             xAxisG.selectAll('line').remove();
             //繪制新的立體X軸
             xAxisG.append("path")
             .datum({
              type: "Polygon",
              coordinates: [
              [
              [20, 0],
              [0, 15],
              [svgWidth - margin.right - margin.left, 15],
              [svgWidth + 20 - margin.right - margin.left, 0],
              [20, 0]
              ]
              ]
             })
             .attr("d", path)
             .attr('fill', 'rgb(187,187,187)');
             xAxisG.selectAll('text')
             .attr('font-size', '18px')
             .attr('fill', '#646464')
             .attr('transform', 'translate(0,20)');
            
             dataProcessing(xLinearScale)//核心算法
             }

            你可能注意到了,上面代碼中不僅使用了序數(shù)比例尺,還有地理路徑生成器,因為需要生成立體的柱圖,所以需要講原本的X軸刪除,自己重新進行繪制.下圖是自己重新繪制出來的path路徑:

            d3.js實現(xiàn)立體柱圖的方法詳解

            創(chuàng)建Y軸線性比例尺

            var yLinearScale;
             //創(chuàng)建y軸的比例尺渲染y軸
             function addYScale() {
             yLinearScale = d3.scaleLinear()
             .domain([0, d3.max(data, function (d, i) {
              return d.child.value * 1;
             }) * 1.2])
             .range([svgHeight - margin.top - margin.bottom, 0]);
            
             //定義Y軸比例尺以及刻度
             var yAxis = d3.axisLeft(yLinearScale)
             .ticks(6);
            
             //繪制Y軸
             var yAxisG = svg.append("g")
             .call(yAxis)
             .attr('transform', 'translate(' + (margin.left + 10) + "," + margin.top + ")");
             yAxisG.selectAll('text')
             .attr('font-size', '18px')
             .attr('fill', '#636363');
             //刪除原Y軸路徑和tick
             yAxisG.select("path").remove();
             yAxisG.selectAll('line').remove();
             }

            創(chuàng)建Y軸時同樣需要把原來的路徑和tick刪除,下圖是效果:

            d3.js實現(xiàn)立體柱圖的方法詳解

            到這,我們的基礎搭建完畢,下面就是核心算法

            核心算法

            為了實現(xiàn)最終效果,我希望大家在理解的時候能把整個立體柱圖分解一下.

            d3.js實現(xiàn)立體柱圖的方法詳解

            我實現(xiàn)立體柱圖的思路是通過2個path路徑和一個rect進行拼湊.

            正面是一個rect,上面和右面利用path路徑生成.

            利用三角函數(shù),通過給定的angle角度計算上面的一個點就可以知道其他所有點的位置進而進行繪制.

            d3.js實現(xiàn)立體柱圖的方法詳解

            通過上圖可以看到,一個立體柱圖我們只需要知道7個點的位置就能夠繪制出來.

            并且已知正面rect4個紅色點的位置.已知柱子的寬度和高度,那么只要求出Top面左上角點的位置,就可以知道余下綠色點的位置.具體算法如下:

            //核心算法思路是Big boss教的,我借花獻佛
            function dataProcessing(xLinearScale) {
             var angle = Math.PI / 2.3;
             for (var i = 0; i < data.length; i++) {
              var d = data[i];
              var depth = 10; 
              d.ow = xLinearScale.bandwidth() * 0.7;
              d.ox = xLinearScale(d.letter);
              d.oh = 1;
              d.p1 = {
              x: Math.cos(angle) * d.ow,
              y: -Math.sin(angle) - depth
              };
              d.p2 = {
              x: d.p1.x + d.ow,
              y: d.p1.y
              };
              d.p3 = {
              x: d.p2.x,
              y: d.p2.y + d.oh
              };
             }
             }

            渲染

            最終我們還要鼠標進行交互,所以先添加tip生成函數(shù)

            //tip的創(chuàng)建方法(方法來自敬愛的鳴哥)
             var tipTimerConfig = {
             longer: 0,
             target: null,
             exist: false,
             winEvent: window.event,
             boxHeight: 398,
             boxWidth: 376,
             maxWidth: 376,
             maxHeight: 398,
             tooltip: null,
            
             showTime: 3500,
             hoverTime: 300,
             displayText: "",
             show: function (val, e) {
              "use strict";
              var me = this;
            
              if (e != null) {
              me.winEvent = e;
              }
            
              me.displayText = val;
            
              me.calculateBoxAndShow();
            
              me.createTimer();
             },
             calculateBoxAndShow: function () {
              "use strict";
              var me = this;
              var _x = 0;
              var _y = 0;
              var _w = document.documentElement.scrollWidth;
              var _h = document.documentElement.scrollHeight;
              var wScrollX = window.scrollX || document.body.scrollLeft;
              var wScrollY = window.scrollY || document.body.scrollTop;
              var xMouse = me.winEvent.x + wScrollX;
              if (_w - xMouse < me.boxWidth) {
              _x = xMouse - me.boxWidth - 10;
              } else {
              _x = xMouse;
              }
            
              var _yMouse = me.winEvent.y + wScrollY;
              if (_h - _yMouse < me.boxHeight + 18) {
              _y = _yMouse - me.boxHeight - 25;
              } else {
            
              _y = _yMouse + 18;
              }
            
              me.addTooltip(_x, _y);
             },
             addTooltip: function (page_x, page_y) {
              "use strict";
              var me = this;
            
              me.tooltip = document.createElement("div");
              me.tooltip.style.left = page_x + "px";
              me.tooltip.style.top = page_y + "px";
              me.tooltip.style.position = "absolute";
            
              me.tooltip.style.width = me.boxWidth + "px";
              me.tooltip.style.height = me.boxHeight + "px";
              me.tooltip.className = "three-tooltip";
            
              var divInnerHeader = me.createInner();
              divInnerHeader.innerHTML = me.displayText;
              me.tooltip.appendChild(divInnerHeader);
            
              document.body.appendChild(me.tooltip);
             },
             createInner: function () {
              "use strict";
              var me = this;
              var divInnerHeader = document.createElement('div');
              divInnerHeader.style.width = me.boxWidth + "px";
              divInnerHeader.style.height = me.boxHeight + "px";
              return divInnerHeader;
             },
             ClearDiv: function () {
              "use strict";
              var delDiv = document.body.getElementsByClassName("three-tooltip");
              for (var i = delDiv.length - 1; i >= 0; i--) {
              document.body.removeChild(delDiv[i]);
              }
             },
             createTimer: function (delTarget) {
              "use strict";
              var me = this;
              var delTip = me.tooltip;
              var delTarget = tipTimerConfig.target;
              var removeTimer = window.setTimeout(function () {
              try {
               if (delTip != null) {
               document.body.removeChild(delTip);
               if (tipTimerConfig.target == delTarget) {
                me.exist = false;
               }
               }
               clearTimeout(removeTimer);
              } catch (e) {
               clearTimeout(removeTimer);
              }
              }, me.showTime);
             },
             hoverTimerFn: function (showTip, showTarget) {
              "use strict";
              var me = this;
            
              var showTarget = tipTimerConfig.target;
            
              var hoverTimer = window.setInterval(function () {
              try {
               if (tipTimerConfig.target != showTarget) {
               clearInterval(hoverTimer);
               } else if (!tipTimerConfig.exist && (new Date()).getTime() - me.longer > me.hoverTime) {
               //show
               tipTimerConfig.show(showTip);
               tipTimerConfig.exist = true;
               clearInterval(hoverTimer);
               }
              } catch (e) {
               clearInterval(hoverTimer);
              }
              }, tipTimerConfig.hoverTime);
             }
             };
            
             var createTooltipTableData = function (info) {
             var ary = [];
             ary.push("<div class='tip-hill-div'>");
             ary.push("<h2>品種信息:" + info.letter + "</h2>");
             ary.push("<h3>成交量: " + info.child.value);
             ary.push("</div>");
             return ary.join("");
             };

            核心算法寫完,就到了最終的渲染了

            function addColumn() {
             function clumnMouseover(d) {
              d3.select(this).selectAll(".transparentPath").attr("opacity", 0.8);
              // 添加 div
              tipTimerConfig.target = this;
              tipTimerConfig.longer = new Date().getTime();
              tipTimerConfig.exist = false;
              //獲取坐標
              tipTimerConfig.winEvent = {
              x: event.clientX - 100,
              y: event.clientY
              };
              tipTimerConfig.boxHeight = 50;
              tipTimerConfig.boxWidth = 140;
            
              //hide
              tipTimerConfig.ClearDiv();
              //show
              tipTimerConfig.hoverTimerFn(createTooltipTableData(d));
             }
            
             function clumnMouseout(d) {
              d3.select(this).selectAll(".transparentPath").attr("opacity", 1);
              tipTimerConfig.target = null;
              tipTimerConfig.ClearDiv();
             }
            
             var g = svg.selectAll('.g')
              .data(data)
              .enter()
              .append('g')
              .on("mouseover", clumnMouseover)
              .on("mouseout", clumnMouseout)
              .attr('transform', function (d) {
               return "translate(" + (d.ox + margin.left + 20) + "," + (svgHeight - margin.bottom + 15) + ")"
              });
             g.transition()
              .duration(2500)
              .attr("transform", function (d) {
               return "translate(" + (d.ox + margin.left + 20) + ", " + (yLinearScale(d.child.value) + margin.bottom - 15) + ")"
              });
            
             g.append('rect')
              .attr('x', 0)
              .attr('y', 0)
              .attr("class", "transparentPath")
              .attr('width', function (d, i) {
               return d.ow;
              })
              .attr('height', function (d) {
               return d.oh;
              })
              .style('fill', function (d, i) {
               return mainColorList[i]
              })
              .transition()
              .duration(2500)
              .attr("height", function (d, i) {
               return svgHeight - margin.bottom - margin.top - yLinearScale(d.child.value);
              });
            
             g.append('path')
              .attr("class", "transparentPath")
              .attr('d', function (d) {
               return "M0,0 L" + d.p1.x + "," + d.p1.y + " L" + d.p2.x + "," + d.p2.y + " L" + d.ow + ",0 L0,0";
              })
              .style('fill', function (d, i) {
               return topColorList[i]
              });
            
             g.append('path')
              .attr("class", "transparentPath")
              .attr('d', function (d) {
               return "M" + d.ow + ",0 L" + d.p2.x + "," + d.p2.y + " L" + d.p3.x + "," + d.p3.y + " L" + d.ow + "," + d.oh + " L" + d.ow + ",0"
              })
              .style('fill', function (d, i) {
               return rightColorList[i]
              })
              .transition()
              .duration(2500)
              .attr("d", function (d, i) {
               return "M" + d.ow + ",0 L" + d.p2.x + "," + d.p2.y + " L" + d.p3.x + "," + (d.p3.y + svgHeight - margin.top - margin.bottom - yLinearScale(d.child.value)) + " L" + d.ow + "," + (svgHeight - margin.top - margin.bottom - yLinearScale(d.child.value)) + " L" + d.ow + ",0"
              });
             }

            由于需要考慮動畫,所以對渲染時的柱子位置進行了處理.對這方面不理解的話可以留言討論.

            d3.js實現(xiàn)立體柱圖的方法詳解

            總結

            以上就是這篇文章的全部內容了,希望本文的內容對大家學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流,謝謝大家對創(chuàng)新互聯(lián)的支持。

            文章題目:d3.js實現(xiàn)立體柱圖的方法詳解
            網(wǎng)頁網(wǎng)址:http://www.jbt999.com/article10/pdgjgo.html

            成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供網(wǎng)頁設計公司、網(wǎng)站排名、電子商務、品牌網(wǎng)站建設、靜態(tài)網(wǎng)站、微信公眾號

            廣告

            聲明:本網(wǎng)站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:[email protected]。內容未經(jīng)允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

            成都定制網(wǎng)站建設

              <del id="d4fwx"><form id="d4fwx"></form></del>
              <del id="d4fwx"><form id="d4fwx"></form></del><del id="d4fwx"><form id="d4fwx"></form></del>

                    <code id="d4fwx"><abbr id="d4fwx"></abbr></code>
                  • 19福利在线 | 豆花视频在线观看一区二区三区 | 日韩视频第一页 | 中文字幕久久人妻无码精品蜜桃 | 99热在线观看精品免费 |