首页 > 解决方案 > D3 图表集成到 Vuejs

问题描述

我正在尝试将此D3 区域图集成到 Vuejs 中,我从代码中得到的只是带有黑色区域的轴。似乎 CSS 属性对我的图表没有影响,到目前为止我尝试过的所有内容都没有改变任何东西。我用 Vuejs 尝试过的大多数 D3 图表都有类似的问题。有什么想法吗?

<template>
  <div class="line-chart"></div>
</template>

<script>
  import * as d3 from 'd3' 

  export default {
    name: 'line-chart',
    mounted () {
      this.renderChart()
    },
    data() {
      return {
        data: [
          { date: '1-May-12', close: 58.13 },
          { date: '30-Apr-12', close: 53.98 },
          { date: '27-Apr-12', close: 67.00 },
          { date: '26-Apr-12', close: 89.70 },
          { date: '25-Apr-12', close: 99.00 },
          { date: '24-Apr-12', close: 130.28 },
          { date: '23-Apr-12', close: 166.70 },
          { date: '20-Apr-12', close: 234.98 },
          { date: '19-Apr-12', close: 345.44 },
          { date: '18-Apr-12', close: 443.34 },
          { date: '17-Apr-12', close: 543.70 },
          { date: '16-Apr-12', close: 580.13 },
          { date: '13-Apr-12', close: 605.23 },
          { date: '12-Apr-12', close: 622.77 },
          { date: '11-Apr-12', close: 626.20 },
          { date: '10-Apr-12', close: 628.44 },
          { date: '9-Apr-12', close: 636.23 },
          { date: '5-Apr-12', close: 633.68 },
          { date: '4-Apr-12', close: 624.31 },
          { date: '3-Apr-12', close: 629.32 },
          { date: '2-Apr-12', close: 618.63 },
          { date: '30-Mar-12', close: 599.55 },
          { date: '29-Mar-12', close: 609.86 },
          { date: '28-Mar-12', close: 617.62 },
          { date: '27-Mar-12', close: 614.48 },
          { date: '26-Mar-12', close: 606.98 }
        ],
        width: 960,
        height: 500 
      }
    },
    methods: {
      renderChart() {
        var data = this.data;
        var margin = { top: 20, right: 20, bottom: 30, left: 50 }
        var width = this.width - margin.left - margin.right;
        var height = this.height - margin.top - margin.bottom;
        var parseTime = d3.timeParse('%d-%b-%y');

        // parse the date / time
        var parseTime = d3.timeParse("%d-%b-%y");

        // set the ranges
        var x = d3.scaleTime().range([0, width]);
        var y = d3.scaleLinear().range([height, 0]);

        // define the area
        var area = d3.area()
          .x(function(d) { return x(d.date); })
          .y0(height)
          .y1(function(d) { return y(d.close); });

        // define the line
        var valueline = d3.line()
          .x(function(d) { return x(d.date); })
          .y(function(d) { return y(d.close); });

        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 + ")");

        // format the data
        data.forEach(function(d) {
          d.date = parseTime(d.date);
          d.close = +d.close;
        });

        // scale the range of the data
        x.domain(d3.extent(data, function(d) { return d.date; }));
        y.domain([0, d3.max(data, function(d) { return d.close; })]);

        // add the area
        svg.append("path")
          .data([data])
          .attr("class", "area")
          .attr("d", area);

        // add the valueline path.
        svg.append("path")
          .data([data])
          .attr("class", "line")
          .attr("d", valueline);

        // add the X Axis
        svg.append("g")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));

        // add the Y Axis
        svg.append("g")
          .call(d3.axisLeft(y));
      },
    }
  };
</script>

<style scoped>
  .line {
    fill: none;
    stroke: steelblue;
    stroke-width: 2px;
  }

  .area {
    fill: lightsteelblue;
  }
</style>

标签: d3.jsvue.js

解决方案


我会将您的 div 从一类折线图更改为折线图的 id,然后,在您拥有的地方d3.select('body'),将其更改为d3.select('#line-chart'). 那应该将图表附加到写入位置。

另外,请确保您安装了 d3v4 而不是 d3v3。有严重的突破性变化。

编辑添加:这是 Stack Overflow 片段运行器中的一个工作示例。它不再是单文件组件,但本质上是相同的。

new Vue({
      el: '#line-chart',
      mounted () {
        this.renderChart()
        setTimeout(()=>{
              this.data = [
              { date: '1-May-12', close: 58.13 },
              { date: '30-Apr-12', close: 53.98 },
              { date: '27-Apr-12', close: 67.00 },
              { date: '26-Apr-12', close: 89.70 },
              { date: '25-Apr-12', close: 99.00 },
              { date: '24-Apr-12', close: 130.28 },
              { date: '23-Apr-12', close: 166.70 },
              { date: '20-Apr-12', close: 234.98 },
              { date: '19-Apr-12', close: 345.44 },
              { date: '18-Apr-12', close: 443.34 },
              { date: '17-Apr-12', close: 543.70 },
              { date: '16-Apr-12', close: 580.13 },
              { date: '13-Apr-12', close: 605.23 },
              { date: '12-Apr-12', close: 622.77 },
              { date: '11-Apr-12', close: 626.20 },
              { date: '10-Apr-12', close: 628.44 },
              { date: '9-Apr-12', close: 636.23 },
              { date: '5-Apr-12', close: 633.68 },
              { date: '4-Apr-12', close: 624.31 },
              { date: '3-Apr-12', close: 629.32 },
              { date: '2-Apr-12', close: 618.63 },
              { date: '30-Mar-12', close: 599.55 },
              { date: '29-Mar-12', close: 609.86 },
              { date: '28-Mar-12', close: 617.62 },
              { date: '27-Mar-12', close: 614.48 },
              { date: '26-Mar-12', close: 606.98 }
             ]}, 1000)
      },
      data() {
        return {
              data: [],
              width: 960,
              height: 500 
          }
      },
      methods: {
        renderChart() {
          if (document.getElementsByTagName('svg')){
              d3.selectAll('svg').remove()
          }
          var data = this.data;
          var margin = { top: 20, right: 20, bottom: 30, left: 50 }
          var width = this.width - margin.left - margin.right;
          var height = this.height - margin.top - margin.bottom;
          var parseTime = d3.timeParse('%d-%b-%y');

          // parse the date / time
    var parseTime = d3.timeParse("%d-%b-%y");

    
    // set the ranges
    var x = d3.scaleTime().range([0, width]);
    var y = d3.scaleLinear().range([height, 0]);

    // define the area
    var area = d3.area()
        .x(function(d) { return x(d.date); })
        .y0(height)
        .y1(function(d) { return y(d.close); });

    // define the line
    var valueline = d3.line()
        .x(function(d) { return x(d.date); })
        .y(function(d) { return y(d.close); });

    var svg = d3.select("#line-chart").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 + ")");

      // format the data
      data.forEach(function(d) {
          d.date = parseTime(d.date);
          d.close = +d.close;
      });

      // scale the range of the data
        x.domain(d3.extent(data, function(d) { return d.date; }));
        y.domain([0, d3.max(data, function(d) { return d.close; })]);

      // add the area
        svg.append("path")
           .data([data])
           .attr("class", "area")
           .attr("d", area);

      // add the valueline path.
      svg.append("path")
          .data([data])
          .attr("class", "line")
          .attr("d", valueline);

      // add the X Axis
      svg.append("g")
          .attr("transform", "translate(0," + height + ")")
          .call(d3.axisBottom(x));

      // add the Y Axis
      svg.append("g")
          .call(d3.axisLeft(y));
      },
     },
     watch: {
     data(val) {
      if (val){
        this.renderChart()
      }
     }
    }
})
.line {
      fill: none;
      stroke: steelblue;
      stroke-width: 2px;
    }

    .area {
      fill: lightsteelblue;
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>

<div id="line-chart"></div>


推荐阅读