ankane / chartkick

Create beautiful JavaScript charts with one line of Ruby
https://chartkick.com
MIT License
6.33k stars 565 forks source link

Cannot read properties of undefined (reading 'formatter') #590

Closed MaffooClock closed 2 years ago

MaffooClock commented 2 years ago

I've started a new Rails 7.0 project using Webpack.

The installation instructions don't exactly match up with my environment, but I believe I have the correct setup (for Highcharts):

yum add chartkick highcharts
# Gemfile
...
gem 'chartkick'
...
// app/javascript/application.js
...
import 'chartkick/highcharts'
...

I can create a simple line chart with one or more series of data:

<%= area_chart @data[:volts], id: 'data-voltage', title: 'Voltage' %>

...and it renders to the view just fine.

When I attempt to implement three Y axes, with one having its own Y axis on the left, and the other two sharing the Y axis on the right (yAxis is being set in the dataset):

<%= line_chart @data[:channel1], id: 'data-channel1', title: 'Power Consumption', library: {
  yAxis: [
    {
      // First dataset, on the left
      title: { text: 'Amps' }
    }, {
      // Second and third datasets, on the right
      title: { text: 'Watts/VA' },
      opposite: true
    }
  ]
} %>

...I am met with Error Loading Chart: Cannot read properties of undefined (reading 'formatter'). The error points to if (chartType !== "pie" && !options.yAxis.labels.formatter) in Line 1104 -- I guess options.yAxis.labels is undefined?

I even tried to set the property manually:

<%= line_chart @data[:channel1], id: 'data-channel1', title: 'Power Consumption', library: {
  yAxis: [
    {
      // First dataset, on the left
      title: { text: 'Amps' },
      labels: { formatter: nil }
    }, {
      // Second and third datasets, on the right
      title: { text: 'Watts/VA' },
      labels: { formatter: nil },
      opposite: true
    }
  ]
} %>

... but no change.

When I remove the entire library: {...} piece, then I get Highcharts Error #18, which makes sense because the second and third datasets are specifying yAxis: 1, so I know the library can "see" what I'm trying to do. When I remove yAxis from the datasets, the chart renders fine (except that all three datasets are now sharing one Y axis).

HTML generated by Chartkick

<div id="data-channel1" style="height: 300px; width: 100%; text-align: center; color: #999; line-height: 300px; font-size: 14px; font-family: 'Lucida Grande', 'Lucida Sans Unicode', Verdana, Arial, Helvetica, sans-serif;">Loading...</div>
<script>
    (function() {
        if (document.documentElement.hasAttribute("data-turbolinks-preview"))
            return;
        if (document.documentElement.hasAttribute("data-turbo-preview"))
            return;

        var createChart = function() {
            new Chartkick["LineChart"]("data-channel1",[{
                "name": "Current (Amps)",
                "data": [["2022-04-04T12:53:22.000+00:00", "7.87"], ["2022-04-04T13:08:29.000+00:00", "7.88"], ["2022-04-04T13:24:09.000+00:00", "7.88"], ["2022-04-04T13:39:14.000+00:00", "7.8"], ["2022-04-04T13:54:22.000+00:00", "7.79"], ["2022-04-04T14:09:29.000+00:00", "7.81"], ["2022-04-04T14:24:35.000+00:00", "7.79"], ["2022-04-04T14:39:42.000+00:00", "0.0"], ["2022-04-04T14:54:47.000+00:00", "0.0"], ["2022-04-04T15:09:52.000+00:00", "0.0"], ["2022-04-04T15:24:58.000+00:00", "0.0"], ["2022-04-04T15:40:05.000+00:00", "0.0"], ["2022-04-04T15:55:13.000+00:00", "0.0"], ["2022-04-04T16:10:18.000+00:00", "0.0"], ["2022-04-04T16:25:23.000+00:00", "0.0"], ["2022-04-04T16:40:29.000+00:00", "0.0"], ["2022-04-04T16:55:35.000+00:00", "0.0"], ["2022-04-04T17:10:42.000+00:00", "0.0"], ["2022-04-04T17:25:50.000+00:00", "0.0"], ["2022-04-04T17:40:58.000+00:00", "0.0"], ["2022-04-04T17:56:05.000+00:00", "0.0"], ["2022-04-04T18:11:12.000+00:00", "0.0"], ["2022-04-04T18:26:18.000+00:00", "0.0"], ["2022-04-04T18:49:22.000+00:00", "0.0"], ["2022-04-04T19:04:30.000+00:00", "0.0"], ["2022-04-04T19:19:37.000+00:00", "0.0"], ["2022-04-04T19:34:42.000+00:00", "0.0"], ["2022-04-04T19:51:06.000+00:00", "0.0"], ["2022-04-04T20:06:13.000+00:00", "0.0"], ["2022-04-04T20:21:21.000+00:00", "0.0"], ["2022-04-04T20:36:26.000+00:00", "0.0"], ["2022-04-04T20:51:34.000+00:00", "0.0"], ["2022-04-04T21:06:41.000+00:00", "0.0"]],
                "yAxis": 0
            }, {
                "name": "Apparent Power (Watts)",
                "data": [["2022-04-04T12:53:22.000+00:00", "607.69"], ["2022-04-04T13:08:29.000+00:00", "606.33"], ["2022-04-04T13:24:09.000+00:00", "603.83"], ["2022-04-04T13:39:14.000+00:00", "604.17"], ["2022-04-04T13:54:22.000+00:00", "602.85"], ["2022-04-04T14:09:29.000+00:00", "600.59"], ["2022-04-04T14:24:35.000+00:00", "600.84"], ["2022-04-04T14:39:42.000+00:00", "0.0"], ["2022-04-04T14:54:47.000+00:00", "0.0"], ["2022-04-04T15:09:52.000+00:00", "0.0"], ["2022-04-04T15:24:58.000+00:00", "0.0"], ["2022-04-04T15:40:05.000+00:00", "0.0"], ["2022-04-04T15:55:13.000+00:00", "0.0"], ["2022-04-04T16:10:18.000+00:00", "0.0"], ["2022-04-04T16:25:23.000+00:00", "0.0"], ["2022-04-04T16:40:29.000+00:00", "0.0"], ["2022-04-04T16:55:35.000+00:00", "0.0"], ["2022-04-04T17:10:42.000+00:00", "0.0"], ["2022-04-04T17:25:50.000+00:00", "0.0"], ["2022-04-04T17:40:58.000+00:00", "0.0"], ["2022-04-04T17:56:05.000+00:00", "0.0"], ["2022-04-04T18:11:12.000+00:00", "0.0"], ["2022-04-04T18:26:18.000+00:00", "0.0"], ["2022-04-04T18:49:22.000+00:00", "0.0"], ["2022-04-04T19:04:30.000+00:00", "0.0"], ["2022-04-04T19:19:37.000+00:00", "0.0"], ["2022-04-04T19:34:42.000+00:00", "0.0"], ["2022-04-04T19:51:06.000+00:00", "0.0"], ["2022-04-04T20:06:13.000+00:00", "0.0"], ["2022-04-04T20:21:21.000+00:00", "0.0"], ["2022-04-04T20:36:26.000+00:00", "0.0"], ["2022-04-04T20:51:34.000+00:00", "0.0"], ["2022-04-04T21:06:41.000+00:00", "0.0"]],
                "yAxis": 1
            }, {
                "name": "Real Power (VA)",
                "data": [["2022-04-04T12:53:22.000+00:00", "955.85"], ["2022-04-04T13:08:29.000+00:00", "955.51"], ["2022-04-04T13:24:09.000+00:00", "952.02"], ["2022-04-04T13:39:14.000+00:00", "944.95"], ["2022-04-04T13:54:22.000+00:00", "942.93"], ["2022-04-04T14:09:29.000+00:00", "945.42"], ["2022-04-04T14:24:35.000+00:00", "944.32"], ["2022-04-04T14:39:42.000+00:00", "0.0"], ["2022-04-04T14:54:47.000+00:00", "0.0"], ["2022-04-04T15:09:52.000+00:00", "0.0"], ["2022-04-04T15:24:58.000+00:00", "0.0"], ["2022-04-04T15:40:05.000+00:00", "0.0"], ["2022-04-04T15:55:13.000+00:00", "0.0"], ["2022-04-04T16:10:18.000+00:00", "0.0"], ["2022-04-04T16:25:23.000+00:00", "0.0"], ["2022-04-04T16:40:29.000+00:00", "0.0"], ["2022-04-04T16:55:35.000+00:00", "0.0"], ["2022-04-04T17:10:42.000+00:00", "0.0"], ["2022-04-04T17:25:50.000+00:00", "0.0"], ["2022-04-04T17:40:58.000+00:00", "0.0"], ["2022-04-04T17:56:05.000+00:00", "0.0"], ["2022-04-04T18:11:12.000+00:00", "0.0"], ["2022-04-04T18:26:18.000+00:00", "0.0"], ["2022-04-04T18:49:22.000+00:00", "0.0"], ["2022-04-04T19:04:30.000+00:00", "0.0"], ["2022-04-04T19:19:37.000+00:00", "0.0"], ["2022-04-04T19:34:42.000+00:00", "0.0"], ["2022-04-04T19:51:06.000+00:00", "0.0"], ["2022-04-04T20:06:13.000+00:00", "0.0"], ["2022-04-04T20:21:21.000+00:00", "0.0"], ["2022-04-04T20:36:26.000+00:00", "0.0"], ["2022-04-04T20:51:34.000+00:00", "0.0"], ["2022-04-04T21:06:41.000+00:00", "0.0"]],
                "yAxis": 1
            }],{
                "title": "Power Consumption",
                "library": {
                    "yAxis": [{
                        "title": {
                            "text": "Amps"
                        },
                        "labels": {
                            // This is just a test to see if manually setting this property makes the error go away -- no difference
                            "formatter": null
                        }
                    }, {
                        "title": {
                            "text": "Watts/VA"
                        },
                        "labels": {
                             // This is just a test to see if manually setting this property makes the error go away -- no difference
                            "formatter": null
                        },
                        "opposite": true
                    }]
                }
            });
        };
        if ("Chartkick"in window) {
            createChart();
        } else {
            window.addEventListener("chartkick:load", createChart, true);
        }
    }
    )();
</script>

Just for grits 'n' shins, I decided to comment out the entire chunk that's been giving me trouble: https://github.com/ankane/chartkick/blob/7f86b4040cbd66115ef71d072b9fefe61bf2bfaf/vendor/assets/javascripts/chartkick.js#L1104-L1108 ...and my chart rendered just exactly the way I wanted. Not certain whether there's a bug or f it's still user-error.

ankane commented 2 years ago

Hey @MaffooClock, thanks for reporting! It looks like Chartkick.js isn't expecting yAxis to be an array. Multiple y-axes aren't officially supported, but we could probably update Chartkick.js to handle this situation without throwing an error if you'd like to submit a PR there.

ankane commented 2 years ago

Pushed a fix to Chartkick.js: https://github.com/ankane/chartkick.js/commit/63e4cf31584b651f403627391055c55f4662ebc4