2

This is the first time I'm asking a question here, so I hope I can phrase it in a way that makes sense.

I'm just beginning to learn Vue and D3, and I'm making an app that generates a bar chart based on some user data. It is supposed to display a chart representing one user, and then have a list of buttons that you can click to generate the chart that represents each of the other users. Right now, it can generate a chart for each different set of data, but I can't figure out how to make the chart update when a new user is chosen.

The name in the H2 header at the top of the chart updates when bottons are clicked, so I know my "featuredUser" prop is changing, so the buttons with usernames seem to be working (they are in another component):

<template>
  <div id="Chart">
  <h2>{{ featuredUser.firstName }} {{ featuredUser.lastName }}</h2>
       <div class="Chart"></div>
</div>

</template>

<script>
import * as d3 from 'd3';

export default {
 
props: ["featuredUser"],
name: "Chart",

  watch: {
    featuredUser() { 
      this.generateChart();
      // the below console log works, even when the chart doesn't update
      // so it seems that this varaible is being watched for changes
      console.log(this.featuredUser.firstName);
    }
  },

  methods: {
    generateChart() {
      let qualities = this.featuredUser.qualities;

// EDIT: Adding the following two lines solves the problem
// the remove the previous chart before the new one is generated
   d3.select(".Chart")
        .selectAll('div').remove();

      d3.select(".Chart")
        .selectAll('div')
        .data(qualities)
        .enter().append('div')
        .style('width', function (d) { return (d.score * 5)+10 + "em"})
        .text(function (d) { return d.quality })
        .attr("id", function(d) {return d.type}); 
    },
  },

// having the below as 'setup()' allows the chart to be generated on click
// for one user but it doesn't change when another user is clicked, 
// having it set as 'mounted()' generates the chart of the chosen user on load,
// but it will not change again.

  setup() {
    this.generateChart();
  }
};

</script>
  • Can you test once and add at watch: `deep: true`. As described [in this post](https://stackoverflow.com/questions/42133894/vue-js-how-to-properly-watch-for-nested-data). what happens then? – wittgenstein Feb 22 '21 at 14:33
  • it seems to work the same way. – AinsleyFrancis Feb 22 '21 at 16:57
  • 1
    I figured it out, I needed to remove the previous chart as part of my generatedChart() function, then it works. (I've added the lines to my question) – AinsleyFrancis Feb 22 '21 at 23:41
  • great to hear. By the way your script area is a little bit mixed with methods and setup. Check out the [official docs](https://v3.vuejs.org/guide/instance.html#lifecycle-hooks) and use the options API or the composition API (I suggest you use the Options API, so you have to remove the `setup()` and place your `this.generateChart();` in the created or mounted hook) – wittgenstein Feb 23 '21 at 18:48

0 Answers0