2016-10-01 28 views
8

Tôi muốn tạo một Gauge từ d3.js như một thành phần tôi có thể sử dụng trong Vue. Nhưng tôi đang đấu tranh nhập khẩu đúng cách để tôi có thể bọc nó trong một thành phần tùy chỉnh.d3 là thành phần Vue

Bên cạnh việc cài đặt d3 từ npm: npm install d3. Tôi có điều này cho gauge

// data which need to be fetched 

var name = " "; 

var value = 840; 

var gaugeMaxValue = 1680; 

// donn�es � calculer 
var percentValue = value/gaugeMaxValue; 

//////////////////////// 

var needleClient; 



(function(){ 

var barWidth, chart, chartInset, degToRad, repaintGauge, 
    height, margin, numSections, padRad, percToDeg, percToRad, 
    percent, radius, sectionIndx, svg, totalPercent, width, 
    valueText, formatValue, k; 

    percent = percentValue; 

    numSections = 1; 
    sectionPerc = 1/numSections/2; 
    padRad = 0.025; 
    chartInset = 10; 

    // Orientation of gauge: 
    totalPercent = .75; 

    el = d3.select('.chart-gauge'); 

    margin = { 
    top: 30, 
    right: 30, 
    bottom: 30, 
    left: 30 
    }; 

    width = el[0][0].offsetWidth - margin.left - margin.right; 
    height = width; 
    radius = Math.min(width, height)/2; 
    barWidth = 40 * width/300; 



    //Utility methods 

    percToDeg = function(perc) { 
    return perc * 360; 
    }; 

    percToRad = function(perc) { 
    return degToRad(percToDeg(perc)); 
    }; 

    degToRad = function(deg) { 
    return deg * Math.PI/180; 
    }; 

    // Create SVG element 
    svg = el.append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom); 

    // Add layer for the panel 
    chart = svg.append('g').attr('transform', "translate(" + ((width)/2 + margin.left) + ", " + ((height + margin.top)/2) + ")"); 

    chart.append('path').attr('class', "arc chart-red"); 
    chart.append('path').attr('class', "arc chart-yellow"); 
    chart.append('path').attr('class', "arc chart-green"); 
    chart.append('path').attr('class', "arc chart-yellow_"); 
    chart.append('path').attr('class', "arc chart-red_"); 

    valueText = chart.append("chart") 
    formatValue = d3.format('1%'); 

    arc5 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth) 
    arc4 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth) 
    arc3 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth) 
    arc2 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth) 
    arc1 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth) 

    repaintGauge = function() 
    { 
    perc = 0.5; 
    var next_start = totalPercent; 
    arcStartRad = percToRad(next_start); 
    arcEndRad = arcStartRad + percToRad(0.175); 
    next_start += 0.175; 


    arc1.startAngle(arcStartRad).endAngle(arcEndRad); 

    arcStartRad = percToRad(next_start); 
    arcEndRad = arcStartRad + percToRad(0.05); 
    next_start += 0.05; 

    arc2.startAngle(arcStartRad + padRad).endAngle(arcEndRad); 

    arcStartRad = percToRad(next_start); 
    arcEndRad = arcStartRad + percToRad(0.05); 
    next_start += 0.05; 

    arc3.startAngle(arcStartRad + padRad).endAngle(arcEndRad); 
    arcStartRad = percToRad(next_start); 
    arcEndRad = arcStartRad + percToRad(0.05); 
    next_start += 0.05; 

    arc4.startAngle(arcStartRad + padRad).endAngle(arcEndRad); 
    arcStartRad = percToRad(next_start); 
    arcEndRad = arcStartRad + percToRad(0.175); 
    next_start += 0.175; 

    arc5.startAngle(arcStartRad + padRad).endAngle(arcEndRad); 


    chart.select(".chart-red").attr('d', arc1); 
    chart.select(".chart-yellow").attr('d', arc2); 
    chart.select(".chart-green").attr('d', arc3); 
    chart.select(".chart-yellow_").attr('d', arc4); 
    chart.select(".chart-red_").attr('d', arc5); 
    } 
///////// 


    var Needle = (function() { 

    //Helper function that returns the `d` value for moving the needle 
    var recalcPointerPos = function(perc) { 
     var centerX, centerY, leftX, leftY, rightX, rightY, thetaRad, topX, topY; 
     thetaRad = percToRad(perc/2); 
     centerX = 0; 
     centerY = 0; 
     topX = centerX - this.len * Math.cos(thetaRad); 
     topY = centerY - this.len * Math.sin(thetaRad); 
     leftX = centerX - this.radius * Math.cos(thetaRad - Math.PI/2); 
     leftY = centerY - this.radius * Math.sin(thetaRad - Math.PI/2); 
     rightX = centerX - this.radius * Math.cos(thetaRad + Math.PI/2); 
     rightY = centerY - this.radius * Math.sin(thetaRad + Math.PI/2); 


     return "M " + leftX + " " + leftY + " L " + topX + " " + topY + " L " + rightX + " " + rightY; 




    }; 

    function Needle(el) { 
     this.el = el; 
     this.len = width/2.5; 
     this.radius = this.len/8; 
    } 

    Needle.prototype.render = function() { 
     this.el.append('circle').attr('class', 'needle-center').attr('cx', 0).attr('cy', 0).attr('r', this.radius); 




     return this.el.append('path').attr('class', 'needle').attr('id', 'client-needle').attr('d', recalcPointerPos.call(this, 0)); 


    }; 

    Needle.prototype.moveTo = function(perc) { 
     var self, 
      oldValue = this.perc || 0; 

     this.perc = perc; 
     self = this; 

     // Reset pointer position 
     this.el.transition().delay(100).ease('quad').duration(200).select('.needle').tween('reset-progress', function() { 
     return function(percentOfPercent) { 
      var progress = (1 - percentOfPercent) * oldValue; 




      repaintGauge(progress); 
      return d3.select(this).attr('d', recalcPointerPos.call(self, progress)); 
     }; 
     }); 

     this.el.transition().delay(300).ease('bounce').duration(1500).select('.needle').tween('progress', function() { 
     return function(percentOfPercent) { 
      var progress = percentOfPercent * perc; 

      repaintGauge(progress); 

      var thetaRad = percToRad(progress/2); 
      var textX = - (self.len + 45) * Math.cos(thetaRad); 
      var textY = - (self.len + 45) * Math.sin(thetaRad); 

      valueText.text(formatValue(progress)) 
      .attr('transform', "translate("+textX+","+textY+")") 

      return d3.select(this).attr('d', recalcPointerPos.call(self, progress)); 
     }; 
     }); 

    }; 


    return Needle; 

    })(); 



    needle = new Needle(chart); 
    needle.render(); 
    needle.moveTo(percent); 

    setTimeout(displayValue, 1350); 



})(); 

Đây là HTML làm việc nhưng không phải là một thành phần

<html> 
    <head> 
     <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
     <style type="text/css" src="gauge.css"> 
      .chart-gauge 
      { 
       width: 400px; 
       margin: 100px auto 
      } 
      .chart-green 
      { 
       fill: #9FBD35; 
      } 
      .chart-yellow 
      { 
       fill: #F2BA3A; 
      } 
      .chart-yellow_ 
      { 
       fill: #F2BA3A; 
      } 
     .chart-red 
     { 
     fill: #FB3033; 
     } 
     .chart-red_ 
     { 
     fill: #FB3033; 
     } 

      .needle, .needle-center 
      { 
       fill: #000000; 
      } 
      .text { 
       color: "#112864"; 
       font-size: 16px; 
      } 


      svg { 
       font: 10px sans-serif; 
      } 


     </style> 

    </head> 
    <body> 


     <div class="chart-gauge"></div> 



     <script type="text/javascript" src="./gaugeClient.js"></script> 
     <script type="text/javascript" src="./labels.js"></script> 
     <script src="https://d3js.org/d3.v3.min.js" charset="utf-8"></script> 
    </body> 

</html> 

Trả lời

13

thành phần đầu tiên được thiết kế để giúp bạn từ viết lại mã của bạn mỗi và mọi thời gian, vậy tại sao không tạo một thành phần cho d3 mà bạn có thể tái sử dụng mỗi và mọi như dưới đây:

phần c3 phổ quát, c3.vue

<template> 
<div :style="style" v-bind:class="class" id="{{ randomid }}" ></div> 
</template> 

<script> 
import c3 from 'c3' 


module.exports = { 
    props: { 
    legend: { 
     type: Object, 


    }, 
    size: { 
     type: Object, 


    }, 
    colour: { 
     type: Object, 
    }, 
    axis: { 
     type: Object, 


    }, 
    bar: { 
     type: Object, 


    }, 

    chartdata:{ 
      type: Object, 
      default: function() { 
      return { 
        columns: [ 
         ['data1', 30, 200, 100, 400, 150, 250], 
         ['data2', 50, 20, 10, 40, 15, 25] 
        ] 
      } 
     } 

    }, 

    class:{ 
      type: Object, 

    }, 
    styles: { 
      type: Object, 

    } 
}, 
    created: function() { 


    }, 
    ready: function(){ 

     this.drawChart(); 
    }, 
    methods : { 

     drawChart: function() { 
      var self = this 
      var chart = c3.generate({ 
       bindto: document.getElementById(self.randomid) , 
       data: self.chartdata, 
       size : self.size, 
       colour : self.colour, 
       legend : self.legend, 
       bar : self.bar, 
       axis : self.axis 
      }); 


     } 

    }, 
    computed: { 
    randomid: function() { 
     return _.uniqueId('c3_') 
    } 
    } 

} 
</script> 

tiếp theo đăng ký thành phần:

Vue.component('c3-chart', require('./c3.vue')) 

bây giờ bạn có thể sử dụng để tạo ra bất kỳ biểu đồ bạn muốn, vâng + đo

<template> 
<div> 
<c3-chart :chartdata="gauge.data" :colour="gauge.colour" :size="gauge.size"></c3-chart> 
</div> 
</template> 

<script> 


module.exports = { 
    props: { 


    }, 
    components: { 


    }, 
    data: function() { 
      return { 
      gauge : { 
        data: { 
        columns: [ 
         ['data', 91.4] 
        ], 
        type: 'gauge', 
        onclick: function (d, i) { console.log("onclick", d, i); }, 
        onmouseover: function (d, i) { console.log("onmouseover", d, i); }, 
        onmouseout: function (d, i) { console.log("onmouseout", d, i); } 
       }, 
      color: { 
       pattern: ['#FF0000', '#F97600', '#F6C600', '#60B044'], 
       threshold: { 
       values: [30, 60, 90, 100] 
       } 
      }, 
      size: { 
       height: 180 
       } 
      } 
      } 
    }, 
    created: function() { 


    }, 
    ready: function(){ 

    }, 
    methods : { 



    }, 
    events: { 

    }, 
    computed: { 

    } 

} 
</script> 
+0

Cảm ơn. Đó là loại câu trả lời tôi đang tìm kiếm! –

+0

@ emil-moe Luôn nhớ đánh dấu câu trả lời đúng là câu trả lời được chấp nhận, goodluck. –

+0

@ emil-moe cũng nhớ bỏ phiếu lên hoặc xuống, điều này sẽ không chỉ giúp người dùng trong tương lai mà còn thêm điểm o danh tiếng của bạn –

Các vấn đề liên quan