2016-10-01 8 views
8

Ich möchte eine Spur von d3.js als eine Komponente machen, die ich in Vue verwenden kann. Aber ich habe Mühe, es richtig zu importieren, damit ich es in eine benutzerdefinierte Komponente verpacken kann.d3 als Vue-Komponente

Neben installiert der d3 von npm: npm install d3. Ich habe dies für die Spur

// 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); 



})(); 

Dies ist der HTML-Code aber nicht als Bestandteil

<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> 

Antwort

13

Erste Komponente ist so konzipiert, Ihnen Umschreiben Code jedes Mal helfen, also warum nicht erstellen eine Komponente für d3, die Sie unter jeder und jedes Mal wie wiederverwenden können:

universal c3 Komponente, 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> 

neben der Komponente registrieren:

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

jetzt können Sie diese verwenden, jede Tabelle, die Sie erstellen möchten, ja + Lehren

<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

Dank. Das war die Art von Antwort, die ich suchte! –

+0

@ emil-moe Immer daran denken, die richtige Antwort als akzeptierte Antwort zu markieren, goodluck. –

+0

@ emil-moe auch nicht vergessen, nach oben oder unten zu wählen, dies wird nicht nur zukünftigen Nutzern helfen, sondern wird Punkt Ihren Ruf hinzufügen –