Solution 1 :

To answer your question, your buttons can’t access update because it’s not in their scope. Only stuff in createSvg can access update. One option would be to take the update function out, but then because update relies on several variables, you need to either make the variables global or pass them as well.

On side note, I think you’re using Vue wrong and from the code you’ve provided, it’s not doing anything beneficial, i.e. createSvg won’t be reactive because you haven’t defined any data.

I’ve included a working snippet below, which uses Vue in the intended way. I highly suggest that you read the documentation.

var app = new Vue({
  el: "#app",
  data: () => {
    return {
      data1: [{
          ser1: 0.3,
          ser2: 4
        },
        {
          ser1: 2,
          ser2: 16
        },
        {
          ser1: 3,
          ser2: 8
        }
      ],
      data2: [{
          ser1: 1,
          ser2: 7
        },
        {
          ser1: 4,
          ser2: 1
        },
        {
          ser1: 6,
          ser2: 8
        }
      ],
      margin: {
        top: 10,
        right: 30,
        bottom: 30,
        left: 50
      },
      width: null,
      height: null
    }
  },
  mounted() {
    this.width = 460 - this.margin.left - this.margin.right;
    this.height = 400 - this.margin.top - this.margin.bottom;
    
    this.createSvg();
  },
  methods: {
    createSvg() {
      var svg = d3.select("#my_dataviz")
        .append("svg")
        .attr("width", this.width + this.margin.left + this.margin.right)
        .attr("height", this.height + this.margin.top + this.margin.bottom)
        .attr("fill", "blue")
        .append("g")
        .attr("transform",
          "translate(" + this.margin.left + "," + this.margin.top + ")");

      var x = d3.scaleLinear().range([0, this.width]);
      var xAxis = d3.axisBottom().scale(x);
      svg.append("g")
        .attr("transform", "translate(0," + this.height + ")")
        .attr("class", "myXaxis")

      var y = d3.scaleLinear().range([this.height, 0]);
      var yAxis = d3.axisLeft().scale(y);
      svg.append("g")
        .attr("class", "myYaxis");

      this.update(svg, x, y, xAxis, yAxis, this.data1)
    },
    updateData(data) {
      var svg = d3.select("#my_dataviz");

      var x = d3.scaleLinear().range([0, this.width]);
      var xAxis = d3.axisBottom().scale(x);

      var y = d3.scaleLinear().range([this.height, 0]);
      var yAxis = d3.axisLeft().scale(y);

      this.update(svg, x, y, xAxis, yAxis, data);
    },
    update(svg, x, y, xAxis, yAxis, data) {
      // Create the X axis:
      x.domain([0, d3.max(data, function(d) {
        return d.ser1
      })]);
      svg.selectAll(".myXaxis").transition()
        .duration(3000)
        .call(xAxis);

      // create the Y axis
      y.domain([0, d3.max(data, function(d) {
        return d.ser2
      })]);
      svg.selectAll(".myYaxis")
        .transition()
        .duration(3000)
        .call(yAxis);

      // Create a update selection: bind to the new data
      var u = svg.selectAll(".lineTest")
        .data([data], function(d) {
          return d.ser1
        });

      // Updata the line
      u
        .enter()
        .append("path")
        .attr("class", "lineTest")
        .merge(u)
        .transition()
        .duration(3000)
        .attr("d", d3.line()
          .x(function(d) {
            return x(d.ser1);
          })
          .y(function(d) {
            return y(d.ser2);
          }))
        .attr("fill", "none")
        .attr("stroke", "steelblue")
        .attr("stroke-width", 2.5)
    }
  }
});
<!DOCTYPE html>
<meta charset="utf-8">

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>



<div id="app">
  <button @click="updateData(data1)">Dataset 1</button>
  <button @click="updateData(data2)">Dataset 2</button>

  <div id="my_dataviz"></div>
</div>

Solution 2 :

Did you wrap your code inside a wrapper with id #app i can’t see it

Problem :

In this JS code I made a line chart with d3 library and Vue framework. The line chart follows two data sets data1 and data2. And I have made createSvg() property accessible for HTML file by returning it in methods(see xyz() function).

But when I click on the buttons, which is shown in the output, the graph does not change means the buttons not work.

What is the mistake in my code? Please give me some suggestions.

var app = new Vue({
  el: "#app",
    data(){
    },
methods:{
  xyz:function(data){
    return this.createSvg
  }
},

computed:{
createSvg(){
  var data1 = [
   {ser1: 0.3, ser2: 4},
   {ser1: 2, ser2: 16},
   {ser1: 3, ser2: 8}
];
  var data2 = [
     {ser1: 1, ser2: 7},
     {ser1: 4, ser2: 1},
     {ser1: 6, ser2: 8}
  ];
// set the dimensions and margins of the graph
var margin = {top: 10, right: 30, bottom: 30, left: 50},
    width = 460 - margin.left - margin.right,
    height = 400 - margin.top - margin.bottom;

// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
  .append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .attr("fill", "blue")
  .append("g")
    .attr("transform",
          "translate(" + margin.left + "," + margin.top + ")");

// Initialise a X axis:
var x = d3.scaleLinear().range([0,width]);
var xAxis = d3.axisBottom().scale(x);
svg.append("g")
  .attr("transform", "translate(0," + height + ")")
  .attr("class","myXaxis")

// Initialize an Y axis
var y = d3.scaleLinear().range([height, 0]);
var yAxis = d3.axisLeft().scale(y);
svg.append("g")
  .attr("class","myYaxis")

// Create a function that takes a dataset as input and update the plot:
function update(data) {

  // Create the X axis:
  x.domain([0, d3.max(data, function(d) { return d.ser1 }) ]);
  svg.selectAll(".myXaxis").transition()
    .duration(3000)
    .call(xAxis);

  // create the Y axis
  y.domain([0, d3.max(data, function(d) { return d.ser2  }) ]);
  svg.selectAll(".myYaxis")
    .transition()
    .duration(3000)
    .call(yAxis);

  // Create a update selection: bind to the new data
  var u = svg.selectAll(".lineTest")
    .data([data], function(d){ return d.ser1 });

  // Updata the line
  u
    .enter()
    .append("path")
    .attr("class","lineTest")
    .merge(u)
    .transition()
    .duration(3000)
    .attr("d", d3.line()
      .x(function(d) { return x(d.ser1); })
      .y(function(d) { return y(d.ser2); }))
      .attr("fill", "none")
      .attr("stroke", "steelblue")
      .attr("stroke-width", 2.5)
};
// At the beginning, I run the update function on the first dataset:
update(data1)
}
}
})
app.xyz()
<!DOCTYPE html>
<meta charset="utf-8">

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>

<button @click="xyz(data1)">Dataset 1</button>
<button @click="xyz(data2)">Dataset 2</button>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>


<script src="abcd.js">

</script>

output of my code

Comments

Comment posted by Lakshay Khandelwal

I am unable to figure out why it is showing the garbage values with the output? Can you please tell me?

Comment posted by Shoejep

Just had to remove

Comment posted by Lakshay Khandelwal

Yeah, I wrapped it. I have shown only the basic code here.

By