{"action":"created","comment":{"url":"https://api.github.com/repos/juttle/juttle-viz/pulls/comments/57351477","id":57351477,"diff_hunk":"@@ -0,0 +1,169 @@\n+'use strict';\n+\n+let SeriesDetector = require('../lib/series-detector');\n+let Highcharts = require('highcharts');\n+let JuttleView = require('./juttle-view');\n+let _ = require('underscore');\n+\n+var objectValidation = require('../lib/object-validation');\n+\n+class HighchartView extends JuttleView {\n+    constructor(options) {\n+        super(options);\n+        options = options || {};\n+        options = this._applyOptionDefaults(options.params);\n+\n+        this._verifyOptionsAreValid(options);\n+\n+        this._attributes = this._convertUserOptionsToAttributes(options);\n+\n+        this._series = {};\n+\n+        this._seriesDetector = new SeriesDetector({\n+            fieldsToIgnore: [ this._attributes.xField ],\n+            keyField: this._attributes._keyField\n+        });\n+\n+        // Inject this view's el into the user-provided\n+        // highchart constructor options.\n+        let highchartConfig = _.extend(options.highchartOptions, {\n+            chart: _.extend({ renderTo: this.sinkBodyEl }, options.highchartOptions.chart )\n+        });\n+\n+        this.chart = Highcharts.chart(highchartConfig);\n+    }\n+\n+    _applyOptionDefaults(options) {\n+        options = options || {};\n+\n+        return _.extend({\n+            xField: 'time',\n+            highchartOptions: this._applyHighchartOptionsDefaults(options.highchartOptions)\n+        }, options);\n+    }\n+\n+    _applyHighchartOptionsDefaults(highchartOptions) {\n+        highchartOptions = highchartOptions || {};\n+\n+        return _.extend({\n+            xAxis: _.extend({\n+                type: 'datetime'\n+            }, highchartOptions.xAxis),\n+            chart: _.extend({}, highchartOptions.chart)\n+        }, highchartOptions);\n+    }\n+\n+    _addSeries(series) {\n+        let seriesLabel = this._seriesDetector.getSeriesLabel(series.id);\n+        let config = this._findMatchingSeriesConfig(series.keys);\n+        seriesLabel = seriesLabel !== '' ? seriesLabel : this._attributes.valueField;\n+\n+        this.chart.addSeries(_.extend({\n+            id: 'series-' + series.id,\n+            name: seriesLabel\n+        }, config));\n+\n+        this._series[series.id] = series;\n+    }\n+\n+    _convertUserOptionsToAttributes(options) {\n+        return _.pick(options, 'valueField', 'keyField', 'xField', 'series');\n+    }\n+\n+    _consume(points) {\n+        if (points.length === 0) {\n+            return;\n+        }\n+\n+        if (!this._attributes.valueField) {\n+            this._attributes.valueField = this._findValueField(points[0]);\n+        }\n+\n+        points.forEach((point) => {\n+            let series = this._seriesDetector.getSeriesForPoint(point);\n+\n+            if (!this._series[series.id]) {\n+                this._addSeries(series);\n+            }\n+\n+            let xFieldValue = point[this._attributes.xField];\n+\n+            this.chart.get('series-' + series.id).addPoint([\n+                _.isDate(xFieldValue) ? xFieldValue.getTime() : xFieldValue,\n+                point[this._attributes.valueField] ]);\n+        });\n+    }\n+\n+    _findMatchingSeriesConfig(keys) {\n+        let keyValues = _.values(keys);\n+        let seriesConfig = {};\n+        if (this._attributes.series) {\n+            let seriesConfigKeys = Object.keys(this._attributes.series);\n+            for(let i = 0; i < seriesConfigKeys.length; i++) {\n+                let configKey = seriesConfigKeys[i];\n+                let config = this._attributes.series[configKey];\n+\n+                if (_.contains(keyValues, configKey)) {\n+                    seriesConfig = config;","path":"src/views/highchart.js","position":107,"original_position":107,"commit_id":"e9fb3374dc60621e62452ff73720d6ca7862d0db","original_commit_id":"e9fb3374dc60621e62452ff73720d6ca7862d0db","user":{"login":"go-oleg","id":3344137,"avatar_url":"https://avatars.githubusercontent.com/u/3344137?v=3","gravatar_id":"","url":"https://api.github.com/users/go-oleg","html_url":"https://github.com/go-oleg","followers_url":"https://api.github.com/users/go-oleg/followers","following_url":"https://api.github.com/users/go-oleg/following{/other_user}","gists_url":"https://api.github.com/users/go-oleg/gists{/gist_id}","starred_url":"https://api.github.com/users/go-oleg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-oleg/subscriptions","organizations_url":"https://api.github.com/users/go-oleg/orgs","repos_url":"https://api.github.com/users/go-oleg/repos","events_url":"https://api.github.com/users/go-oleg/events{/privacy}","received_events_url":"https://api.github.com/users/go-oleg/received_events","type":"User","site_admin":false},"body":"Right, it checks to see if the user specified a series configuration that matches a series with keys `keys`. _Matches_ here means one of the key values matches the series configuration key. I'll add a comment to the code explaining this.","created_at":"2016-03-24T17:10:33Z","updated_at":"2016-03-24T17:10:33Z","html_url":"https://github.com/juttle/juttle-viz/pull/82#discussion_r57351477","pull_request_url":"https://api.github.com/repos/juttle/juttle-viz/pulls/82","_links":{"self":{"href":"https://api.github.com/repos/juttle/juttle-viz/pulls/comments/57351477"},"html":{"href":"https://github.com/juttle/juttle-viz/pull/82#discussion_r57351477"},"pull_request":{"href":"https://api.github.com/repos/juttle/juttle-viz/pulls/82"}}},"pull_request":{"url":"https://api.github.com/repos/juttle/juttle-viz/pulls/82","id":63132525,"html_url":"https://github.com/juttle/juttle-viz/pull/82","diff_url":"https://github.com/juttle/juttle-viz/pull/82.diff","patch_url":"https://github.com/juttle/juttle-viz/pull/82.patch","issue_url":"https://api.github.com/repos/juttle/juttle-viz/issues/82","number":82,"state":"open","locked":false,"title":"highchart view","user":{"login":"go-oleg","id":3344137,"avatar_url":"https://avatars.githubusercontent.com/u/3344137?v=3","gravatar_id":"","url":"https://api.github.com/users/go-oleg","html_url":"https://github.com/go-oleg","followers_url":"https://api.github.com/users/go-oleg/followers","following_url":"https://api.github.com/users/go-oleg/following{/other_user}","gists_url":"https://api.github.com/users/go-oleg/gists{/gist_id}","starred_url":"https://api.github.com/users/go-oleg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/go-oleg/subscriptions","organizations_url":"https://api.github.com/users/go-oleg/orgs","repos_url":"https://api.github.com/users/go-oleg/repos","events_url":"https://api.github.com/users/go-oleg/events{/privacy}","received_events_url":"https://api.github.com/users/go-oleg/received_events","type":"User","site_admin":false},"body":"Usage\r\n```\r\n| view highchart\r\n  -highchartOptions // passed through to highchart constructor\r\n  -valueField/-keyField  // same as in timechart\r\n  -xField // defaults to 'time'\r\n  -series // object mapping a key field value to the series-specific config that should be used for that series\r\n```\r\n\r\n@mnibecker","created_at":"2016-03-16T20:43:55Z","updated_at":"2016-03-24T17:10:33Z","closed_at":null,"merged_at":null,"merge_commit_sha":"11b2c7ea4b84f5f935072b777f2e68a96834c341","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/juttle/juttle-viz/pulls/82/commits","review_comments_url":"https://api.github.com/repos/juttle/juttle-viz/pulls/82/comments","review_comment_url":"https://api.github.com/repos/juttle/juttle-viz/pulls/comments{/number}","comments_url":"https://api.github.com/repos/juttle/juttle-viz/issues/82/comments","statuses_url":"https://api.github.com/repos/juttle/juttle-viz/statuses/e9fb3374dc60621e62452ff73720d6ca7862d0db","head":{"label":"juttle:highchart-view","ref":"highchart-view","sha":"e9fb3374dc60621e62452ff73720d6ca7862d0db","user":{"login":"juttle","id":8988633,"avatar_url":"https://avatars.githubusercontent.com/u/8988633?v=3","gravatar_id":"","url":"https://api.github.com/users/juttle","html_url":"https://github.com/juttle","followers_url":"https://api.github.com/users/juttle/followers","following_url":"https://api.github.com/users/juttle/following{/other_user}","gists_url":"https://api.github.com/users/juttle/gists{/gist_id}","starred_url":"https://api.github.com/users/juttle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juttle/subscriptions","organizations_url":"https://api.github.com/users/juttle/orgs","repos_url":"https://api.github.com/users/juttle/repos","events_url":"https://api.github.com/users/juttle/events{/privacy}","received_events_url":"https://api.github.com/users/juttle/received_events","type":"Organization","site_admin":false},"repo":{"id":48262224,"name":"juttle-viz","full_name":"juttle/juttle-viz","owner":{"login":"juttle","id":8988633,"avatar_url":"https://avatars.githubusercontent.com/u/8988633?v=3","gravatar_id":"","url":"https://api.github.com/users/juttle","html_url":"https://github.com/juttle","followers_url":"https://api.github.com/users/juttle/followers","following_url":"https://api.github.com/users/juttle/following{/other_user}","gists_url":"https://api.github.com/users/juttle/gists{/gist_id}","starred_url":"https://api.github.com/users/juttle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juttle/subscriptions","organizations_url":"https://api.github.com/users/juttle/orgs","repos_url":"https://api.github.com/users/juttle/repos","events_url":"https://api.github.com/users/juttle/events{/privacy}","received_events_url":"https://api.github.com/users/juttle/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/juttle/juttle-viz","description":"Juttle Visualization Library","fork":false,"url":"https://api.github.com/repos/juttle/juttle-viz","forks_url":"https://api.github.com/repos/juttle/juttle-viz/forks","keys_url":"https://api.github.com/repos/juttle/juttle-viz/keys{/key_id}","collaborators_url":"https://api.github.com/repos/juttle/juttle-viz/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/juttle/juttle-viz/teams","hooks_url":"https://api.github.com/repos/juttle/juttle-viz/hooks","issue_events_url":"https://api.github.com/repos/juttle/juttle-viz/issues/events{/number}","events_url":"https://api.github.com/repos/juttle/juttle-viz/events","assignees_url":"https://api.github.com/repos/juttle/juttle-viz/assignees{/user}","branches_url":"https://api.github.com/repos/juttle/juttle-viz/branches{/branch}","tags_url":"https://api.github.com/repos/juttle/juttle-viz/tags","blobs_url":"https://api.github.com/repos/juttle/juttle-viz/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/juttle/juttle-viz/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/juttle/juttle-viz/git/refs{/sha}","trees_url":"https://api.github.com/repos/juttle/juttle-viz/git/trees{/sha}","statuses_url":"https://api.github.com/repos/juttle/juttle-viz/statuses/{sha}","languages_url":"https://api.github.com/repos/juttle/juttle-viz/languages","stargazers_url":"https://api.github.com/repos/juttle/juttle-viz/stargazers","contributors_url":"https://api.github.com/repos/juttle/juttle-viz/contributors","subscribers_url":"https://api.github.com/repos/juttle/juttle-viz/subscribers","subscription_url":"https://api.github.com/repos/juttle/juttle-viz/subscription","commits_url":"https://api.github.com/repos/juttle/juttle-viz/commits{/sha}","git_commits_url":"https://api.github.com/repos/juttle/juttle-viz/git/commits{/sha}","comments_url":"https://api.github.com/repos/juttle/juttle-viz/comments{/number}","issue_comment_url":"https://api.github.com/repos/juttle/juttle-viz/issues/comments{/number}","contents_url":"https://api.github.com/repos/juttle/juttle-viz/contents/{+path}","compare_url":"https://api.github.com/repos/juttle/juttle-viz/compare/{base}...{head}","merges_url":"https://api.github.com/repos/juttle/juttle-viz/merges","archive_url":"https://api.github.com/repos/juttle/juttle-viz/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/juttle/juttle-viz/downloads","issues_url":"https://api.github.com/repos/juttle/juttle-viz/issues{/number}","pulls_url":"https://api.github.com/repos/juttle/juttle-viz/pulls{/number}","milestones_url":"https://api.github.com/repos/juttle/juttle-viz/milestones{/number}","notifications_url":"https://api.github.com/repos/juttle/juttle-viz/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/juttle/juttle-viz/labels{/name}","releases_url":"https://api.github.com/repos/juttle/juttle-viz/releases{/id}","deployments_url":"https://api.github.com/repos/juttle/juttle-viz/deployments","created_at":"2015-12-19T00:11:08Z","updated_at":"2016-02-19T18:20:56Z","pushed_at":"2016-03-24T16:02:37Z","git_url":"git://github.com/juttle/juttle-viz.git","ssh_url":"git@github.com:juttle/juttle-viz.git","clone_url":"https://github.com/juttle/juttle-viz.git","svn_url":"https://github.com/juttle/juttle-viz","homepage":null,"size":2759,"stargazers_count":6,"watchers_count":6,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"open_issues_count":15,"forks":1,"open_issues":15,"watchers":6,"default_branch":"master"}},"base":{"label":"juttle:master","ref":"master","sha":"fc98e1c0477ab4e1c50a89aadb5717a5b1225168","user":{"login":"juttle","id":8988633,"avatar_url":"https://avatars.githubusercontent.com/u/8988633?v=3","gravatar_id":"","url":"https://api.github.com/users/juttle","html_url":"https://github.com/juttle","followers_url":"https://api.github.com/users/juttle/followers","following_url":"https://api.github.com/users/juttle/following{/other_user}","gists_url":"https://api.github.com/users/juttle/gists{/gist_id}","starred_url":"https://api.github.com/users/juttle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juttle/subscriptions","organizations_url":"https://api.github.com/users/juttle/orgs","repos_url":"https://api.github.com/users/juttle/repos","events_url":"https://api.github.com/users/juttle/events{/privacy}","received_events_url":"https://api.github.com/users/juttle/received_events","type":"Organization","site_admin":false},"repo":{"id":48262224,"name":"juttle-viz","full_name":"juttle/juttle-viz","owner":{"login":"juttle","id":8988633,"avatar_url":"https://avatars.githubusercontent.com/u/8988633?v=3","gravatar_id":"","url":"https://api.github.com/users/juttle","html_url":"https://github.com/juttle","followers_url":"https://api.github.com/users/juttle/followers","following_url":"https://api.github.com/users/juttle/following{/other_user}","gists_url":"https://api.github.com/users/juttle/gists{/gist_id}","starred_url":"https://api.github.com/users/juttle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/juttle/subscriptions","organizations_url":"https://api.github.com/users/juttle/orgs","repos_url":"https://api.github.com/users/juttle/repos","events_url":"https://api.github.com/users/juttle/events{/privacy}","received_events_url":"https://api.github.com/users/juttle/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/juttle/juttle-viz","description":"Juttle Visualization Library","fork":false,"url":"https://api.github.com/repos/juttle/juttle-viz","forks_url":"https://api.github.com/repos/juttle/juttle-viz/forks","keys_url":"https://api.github.com/repos/juttle/juttle-viz/keys{/key_id}","collaborators_url":"https://api.github.com/repos/juttle/juttle-viz/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/juttle/juttle-viz/teams","hooks_url":"https://api.github.com/repos/juttle/juttle-viz/hooks","issue_events_url":"https://api.github.com/repos/juttle/juttle-viz/issues/events{/number}","events_url":"https://api.github.com/repos/juttle/juttle-viz/events","assignees_url":"https://api.github.com/repos/juttle/juttle-viz/assignees{/user}","branches_url":"https://api.github.com/repos/juttle/juttle-viz/branches{/branch}","tags_url":"https://api.github.com/repos/juttle/juttle-viz/tags","blobs_url":"https://api.github.com/repos/juttle/juttle-viz/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/juttle/juttle-viz/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/juttle/juttle-viz/git/refs{/sha}","trees_url":"https://api.github.com/repos/juttle/juttle-viz/git/trees{/sha}","statuses_url":"https://api.github.com/repos/juttle/juttle-viz/statuses/{sha}","languages_url":"https://api.github.com/repos/juttle/juttle-viz/languages","stargazers_url":"https://api.github.com/repos/juttle/juttle-viz/stargazers","contributors_url":"https://api.github.com/repos/juttle/juttle-viz/contributors","subscribers_url":"https://api.github.com/repos/juttle/juttle-viz/subscribers","subscription_url":"https://api.github.com/repos/juttle/juttle-viz/subscription","commits_url":"https://api.github.com/repos/juttle/juttle-viz/commits{/sha}","git_commits_url":"https://api.github.com/repos/juttle/juttle-viz/git/commits{/sha}","comments_url":"https://api.github.com/repos/juttle/juttle-viz/comments{/number}","issue_comment_url":"https://api.github.com/repos/juttle/juttle-viz/issues/comments{/number}","contents_url":"https://api.github.com/repos/juttle/juttle-viz/contents/{+path}","compare_url":"https://api.github.com/repos/juttle/juttle-viz/compare/{base}...{head}","merges_url":"https://api.github.com/repos/juttle/juttle-viz/merges","archive_url":"https://api.github.com/repos/juttle/juttle-viz/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/juttle/juttle-viz/downloads","issues_url":"https://api.github.com/repos/juttle/juttle-viz/issues{/number}","pulls_url":"https://api.github.com/repos/juttle/juttle-viz/pulls{/number}","milestones_url":"https://api.github.com/repos/juttle/juttle-viz/milestones{/number}","notifications_url":"https://api.github.com/repos/juttle/juttle-viz/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/juttle/juttle-viz/labels{/name}","releases_url":"https://api.github.com/repos/juttle/juttle-viz/releases{/id}","deployments_url":"https://api.github.com/repos/juttle/juttle-viz/deployments","created_at":"2015-12-19T00:11:08Z","updated_at":"2016-02-19T18:20:56Z","pushed_at":"2016-03-24T16:02:37Z","git_url":"git://github.com/juttle/juttle-viz.git","ssh_url":"git@github.com:juttle/juttle-viz.git","clone_url":"https://github.com/juttle/juttle-viz.git","svn_url":"https://github.com/juttle/juttle-viz","homepage":null,"size":2759,"stargazers_count":6,"watchers_count":6,"language":"JavaScript","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":1,"mirror_url":null,"open_issues_count":15,"forks":1,"open_issues":15,"watchers":6,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/juttle/juttle-viz/pulls/82"},"html":{"href":"https://github.com/juttle/juttle-viz/pull/82"},"issue":{"href":"https://api.github.com/repos/juttle/juttle-viz/issues/82"},"comments":{"href":"https://api.github.com/repos/juttle/juttle-viz/issues/82/comments"},"review_comments":{"href":"https://api.github.com/repos/juttle/juttle-viz/pulls/82/comments"},"review_comment":{"href":"https://api.github.com/repos/juttle/juttle-viz/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/juttle/juttle-viz/pulls/82/commits"},"statuses":{"href":"https://api.github.com/repos/juttle/juttle-viz/statuses/e9fb3374dc60621e62452ff73720d6ca7862d0db"}}}}