Creating chart with meteor highchart

please help, i want to create charts with package meteor add maazalik:highcharts, using columnDemo but i did’nt know how to get data from databes to this charts, i am using meteor example todos.

There’s an official HighCharts package, it’s better: https://atmospherejs.com/highcharts/highcharts-meteor

Your query is not very specific but in general:

You have to have subscribed to the publication if you’re using pub/sub. I didn’t see that call in your code.

You don’t want to re-render the entire chart over and over, this will burn cpu in the browser. HighCharts exposes an api that lets you pass fresh data to existing charts (see their live examples) and then, once you’ve added all the points or done what you wanted, you can redraw() the chart.

Your click event which calls document.location.reload(true); is almost certainly a bad idea.

HighCharts needs an element to exist on the dom before you try to render the chart into it. So you obviously want the render to happen after the [Template].onRendered() callback. You have that already, just saying it again.

You should think about if you want your chart to be reactive or not, there’s nothing wrong with loading the data when the template is first created and not having live updates if the data isn’t expected to change much. Or you could even drop pub/sub entirely and use methods and have a refresh button, not very Meteor like but possibly wise if the queries getting the data are complicated. It depends on your use case. If you did want it reactive then you’d need something a bit like:

Template.myChart.onCreated({
  // A template var to hold the chart object in;
  this.theChart = new ReactiveVar(null);

  this.getListId = () => FlowRouter.getParam('_id');

  // Builds the HighCharts element in the DOM
  this.initialiseChart = (element, data) => {
    // render the chart to the given element using data
    return element.highcharts({
      // ... etc
    });
  }

  // Takes the HighCharts object and adds new data to the existing array
  this.addPoints = (chart, points) => {
    // add this array of points to the existing chart
    chart.addPoints(...); // Or whatever the HighCharts function is to do this;
    chart.redraw();
  }

  this.autorun(() => {
    this.subscribe('Todos.inList', this.getListId()); // You have to subscribe to access the data;
  });
});

Template.myChart.onRendered({
  // Get the current data
  var initialData = Todos.find({}); // etc
  // Render chart to dom using the data
  this.theChart.set(this.initialiseChart(this.$('#thechartdiv'), initialData));
  this.autorun(() => {
    // this function will rerun when data changes
    var latestData = Todos.find({}); // etc
    this.addPoints(this.theChart.get(), latestData);
  });
});

That’s just rough untested code, think of it like sudo code. You still need to work out the details yourself. Beware making complicated report queries reactive though, this is a very easy area to create hard to fix scaling problems for yourself.

2 Likes

I have to agree with @oliverlloyd (not on the package part :wink: ) but on the way to update the chart data. I have multiple meteorpads (here and here) wich are basicaly doing what @oliverlloyd proposes. However, they are pretty old. Maybe you can get an idea and combine them to get your solution.

(And yes, I am aware of the semi-optimal demo … :frowning: )

1 Like