From e8d401b9b785116ac551a21373aa5fddd994fdcf Mon Sep 17 00:00:00 2001 From: Mateusz Kornecki <50931078+mateuszkornecki@users.noreply.github.com> Date: Mon, 15 Jun 2020 15:31:34 +0200 Subject: [PATCH] feat: extracted charts to separate components --- src/app/app.component.css | 23 - src/app/app.component.html | 95 +-- src/app/app.component.ts | 586 +----------------- src/app/app.module.ts | 10 +- src/app/gantt-chart/gantt-chart.component.css | 23 + .../gantt-chart/gantt-chart.component.html | 9 + .../gantt-chart/gantt-chart.component.spec.ts | 25 + src/app/gantt-chart/gantt-chart.component.ts | 52 ++ .../lazy-loading-chart.component.css | 23 + .../lazy-loading-chart.component.html | 10 + .../lazy-loading-chart.component.spec.ts | 25 + .../lazy-loading-chart.component.ts | 112 ++++ src/app/line-chart/line-chart.component.css | 23 + src/app/line-chart/line-chart.component.html | 23 + .../line-chart/line-chart.component.spec.ts | 25 + src/app/line-chart/line-chart.component.ts | 63 ++ src/app/map-chart/map-chart.component.css | 23 + src/app/map-chart/map-chart.component.html | 10 + src/app/map-chart/map-chart.component.spec.ts | 25 + src/app/map-chart/map-chart.component.ts | 297 +++++++++ src/app/stock-chart/stock-chart.component.css | 23 + .../stock-chart/stock-chart.component.html | 27 + .../stock-chart/stock-chart.component.spec.ts | 25 + src/app/stock-chart/stock-chart.component.ts | 114 ++++ tsconfig.json | 5 +- 25 files changed, 975 insertions(+), 701 deletions(-) create mode 100644 src/app/gantt-chart/gantt-chart.component.css create mode 100644 src/app/gantt-chart/gantt-chart.component.html create mode 100644 src/app/gantt-chart/gantt-chart.component.spec.ts create mode 100644 src/app/gantt-chart/gantt-chart.component.ts create mode 100644 src/app/lazy-loading-chart/lazy-loading-chart.component.css create mode 100644 src/app/lazy-loading-chart/lazy-loading-chart.component.html create mode 100644 src/app/lazy-loading-chart/lazy-loading-chart.component.spec.ts create mode 100644 src/app/lazy-loading-chart/lazy-loading-chart.component.ts create mode 100644 src/app/line-chart/line-chart.component.css create mode 100644 src/app/line-chart/line-chart.component.html create mode 100644 src/app/line-chart/line-chart.component.spec.ts create mode 100644 src/app/line-chart/line-chart.component.ts create mode 100644 src/app/map-chart/map-chart.component.css create mode 100644 src/app/map-chart/map-chart.component.html create mode 100644 src/app/map-chart/map-chart.component.spec.ts create mode 100644 src/app/map-chart/map-chart.component.ts create mode 100644 src/app/stock-chart/stock-chart.component.css create mode 100644 src/app/stock-chart/stock-chart.component.html create mode 100644 src/app/stock-chart/stock-chart.component.spec.ts create mode 100644 src/app/stock-chart/stock-chart.component.ts diff --git a/src/app/app.component.css b/src/app/app.component.css index f47a232..e69de29 100644 --- a/src/app/app.component.css +++ b/src/app/app.component.css @@ -1,23 +0,0 @@ -h2 { - font-size: 20px; - color: #eeeaea; - background-color: #47475C; - padding: 10px; -} - -.full-left { - font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; - font-size: 14px; - float: left; - width: 98%; - background-color: #eee; - padding: 5px 1%; -} -.medium-right { - float: right; - width: 65%; -} -.third-left { - width: 30%; - float: left; -} \ No newline at end of file diff --git a/src/app/app.component.html b/src/app/app.component.html index 9b04b41..6e4e434 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,90 +1,7 @@ -
-

Demo #1: Highcharts with a basic editor

-
- -
- -
- -
-
- -
-
- -
- -
-

Demo #2: Highstock with simple updates

-
-

Chart title text:

- -
-

Data sets:

- -
-
- -
-
- -
- -
-

Demo #3: Highmaps map chart

- -
- -
- -
-

Demo #4: Highcharts Gantt chart

- -
- -
-

Demo #5: Lazy loading in Highstock

- +
+ + + + +
\ No newline at end of file diff --git a/src/app/app.component.ts b/src/app/app.component.ts index bf967fc..2c4573e 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -2,38 +2,12 @@ declare var require: any; import { Component } from '@angular/core'; -import $ from 'jquery'; -import proj4 from 'proj4'; -declare global { - interface Window { proj4: any; } -} -window.proj4 = proj4; - -import * as Highcharts from 'highcharts'; - -import StockModule from 'highcharts/modules/stock'; -import MapModule from 'highcharts/modules/map'; -import GanttModule from 'highcharts/modules/gantt'; import ExportingModule from 'highcharts/modules/exporting'; import SunsetTheme from 'highcharts/themes/sunset.src.js'; -const mapWorld = require('@highcharts/map-collection/custom/world.geo.json'); - -import HC_customEvents from 'highcharts-custom-events'; -HC_customEvents(Highcharts); - -// Alternative way of a plugin loading: -// const HC_ce = require('highcharts-custom-events'); -// HC_ce(Highcharts); - -StockModule(Highcharts); -MapModule(Highcharts); -GanttModule(Highcharts); -ExportingModule(Highcharts); -// Legacy way of map loading - see file at the path for more info. -// require('../../js/worldmap')(Highcharts); +import * as Highcharts from "highcharts"; SunsetTheme(Highcharts); @@ -56,563 +30,5 @@ Highcharts.setOptions({ }) export class AppComponent { - // For all demos: - Highcharts: typeof Highcharts = Highcharts; // Highcharts, it's Highcharts - - // Demo #1 - optFromInputString: string = ` - { - "title": { "text": "Highcharts chart" }, - "series": [{ - "data": [11,2,3], - "zones": [{ - "value": 7.2, - "dashStyle": "dot", - "color": "red" - }] - }, { - "data": [5,6,7] - }] - } - `; - - optFromInput: Highcharts.Options = JSON.parse(this.optFromInputString); - updateFromInput: boolean = false; - - // Demonstrate chart instance - logChartInstance(chart: Highcharts.Chart) { - console.log('Chart instance: ', chart); - } - - updateInputChart() { - this.optFromInput = JSON.parse(this.optFromInputString); - } - - seriesTypes: {[key: string]: string} = { - line: 'column', - column: 'scatter', - scatter: 'spline', - spline: 'line' - }; - - toggleSeriesType(index: number = 0) { - this.optFromInput.series[index].type = - this.seriesTypes[this.optFromInput.series[index].type || 'line'] as - 'column' | 'scatter' | 'spline' | 'line'; - // nested change - must trigger update - this.updateFromInput = true; - } - - // ---------------------------------------------------------------------- - // Demo #2 - - // starting values - updateDemo2: boolean = false; - usedIndex: number = 0; - chartTitle: string = 'My chart'; // for init - change through titleChange - - // change in all places - titleChange(event: any) { - var v = event; - this.chartTitle = v; - - this.charts.forEach((el) => { - el.hcOptions.title.text = v; - }); - - // trigger ngOnChanges - this.updateDemo2 = true; - }; - charts = [{ - hcOptions: { - title: { text: this.chartTitle }, - subtitle: { text: '1st data set' }, - plotOptions: { - series: { - pointStart: Date.now(), - pointInterval: 86400000 // 1 day - } - }, - series: [{ - type: 'line', - data: [11, 2, 3], - threshold: 5, - negativeColor: 'red', - events: { - dblclick: function () { - console.log('dblclick - thanks to the Custom Events plugin'); - } - } - }, { - type: 'candlestick', - - data: [ - [0, 15, -6, 7], - [7, 12, -1, 3], - [3, 10, -3, 3] - ] - }] - } as Highcharts.Options, - hcCallback: (chart: Highcharts.Chart) => { - console.log('some variables: ', Highcharts, chart, this.charts); - } - }, { - hcOptions: { - title: { text: this.chartTitle }, - subtitle: { text: '2nd data set' }, - series: [{ - type: 'column', - data: [4, 3, -12], - threshold: -10 - }, { - type: 'ohlc', - data: [ - [0, 15, -6, 7], - [7, 12, -1, 3], - [3, 10, -3, 3] - ] - }] - } as Highcharts.Options, - hcCallback: () => {} - }, { - hcOptions: { - title: { text: this.chartTitle }, - subtitle: { text: '3rd data set' }, - series: [{ - type: 'scatter', - data: [1, 2, 3, 4, 5] - }, { - type: 'areaspline', - data: [ - 5, - 11, - 3, - 6, - 0 - ] - }] - } as Highcharts.Options, - hcCallback: () => {} - }]; - - // ---------------------------------------------------------------------- - // Demo #3 - - chartMap: Highcharts.Options = { - chart: { - map: mapWorld - }, - title: { - text: 'Highmaps basic demo' - }, - subtitle: { - text: 'Source map: World, Miller projection, medium resolution' - }, - mapNavigation: { - enabled: true, - buttonOptions: { - alignTo: 'spacingBox' - } - }, - legend: { - enabled: true - }, - colorAxis: { - min: 0 - }, - series: [{ - name: 'Random data', - states: { - hover: { - color: '#BADA55' - } - }, - dataLabels: { - enabled: true, - format: '{point.name}' - }, - allAreas: false, - data: [ - ['fo', 0], - ['um', 1], - ['us', 2], - ['jp', 3], - ['sc', 4], - ['in', 5], - ['fr', 6], - ['fm', 7], - ['cn', 8], - ['pt', 9], - ['sw', 10], - ['sh', 11], - ['br', 12], - ['ki', 13], - ['ph', 14], - ['mx', 15], - ['es', 16], - ['bu', 17], - ['mv', 18], - ['sp', 19], - ['gb', 20], - ['gr', 21], - ['as', 22], - ['dk', 23], - ['gl', 24], - ['gu', 25], - ['mp', 26], - ['pr', 27], - ['vi', 28], - ['ca', 29], - ['st', 30], - ['cv', 31], - ['dm', 32], - ['nl', 33], - ['jm', 34], - ['ws', 35], - ['om', 36], - ['vc', 37], - ['tr', 38], - ['bd', 39], - ['lc', 40], - ['nr', 41], - ['no', 42], - ['kn', 43], - ['bh', 44], - ['to', 45], - ['fi', 46], - ['id', 47], - ['mu', 48], - ['se', 49], - ['tt', 50], - ['my', 51], - ['pa', 52], - ['pw', 53], - ['tv', 54], - ['mh', 55], - ['cl', 56], - ['th', 57], - ['gd', 58], - ['ee', 59], - ['ag', 60], - ['tw', 61], - ['bb', 62], - ['it', 63], - ['mt', 64], - ['vu', 65], - ['sg', 66], - ['cy', 67], - ['lk', 68], - ['km', 69], - ['fj', 70], - ['ru', 71], - ['va', 72], - ['sm', 73], - ['kz', 74], - ['az', 75], - ['tj', 76], - ['ls', 77], - ['uz', 78], - ['ma', 79], - ['co', 80], - ['tl', 81], - ['tz', 82], - ['ar', 83], - ['sa', 84], - ['pk', 85], - ['ye', 86], - ['ae', 87], - ['ke', 88], - ['pe', 89], - ['do', 90], - ['ht', 91], - ['pg', 92], - ['ao', 93], - ['kh', 94], - ['vn', 95], - ['mz', 96], - ['cr', 97], - ['bj', 98], - ['ng', 99], - ['ir', 100], - ['sv', 101], - ['sl', 102], - ['gw', 103], - ['hr', 104], - ['bz', 105], - ['za', 106], - ['cf', 107], - ['sd', 108], - ['cd', 109], - ['kw', 110], - ['de', 111], - ['be', 112], - ['ie', 113], - ['kp', 114], - ['kr', 115], - ['gy', 116], - ['hn', 117], - ['mm', 118], - ['ga', 119], - ['gq', 120], - ['ni', 121], - ['lv', 122], - ['ug', 123], - ['mw', 124], - ['am', 125], - ['sx', 126], - ['tm', 127], - ['zm', 128], - ['nc', 129], - ['mr', 130], - ['dz', 131], - ['lt', 132], - ['et', 133], - ['er', 134], - ['gh', 135], - ['si', 136], - ['gt', 137], - ['ba', 138], - ['jo', 139], - ['sy', 140], - ['mc', 141], - ['al', 142], - ['uy', 143], - ['cnm', 144], - ['mn', 145], - ['rw', 146], - ['so', 147], - ['bo', 148], - ['cm', 149], - ['cg', 150], - ['eh', 151], - ['rs', 152], - ['me', 153], - ['tg', 154], - ['la', 155], - ['af', 156], - ['ua', 157], - ['sk', 158], - ['jk', 159], - ['bg', 160], - ['qa', 161], - ['li', 162], - ['at', 163], - ['sz', 164], - ['hu', 165], - ['ro', 166], - ['ne', 167], - ['lu', 168], - ['ad', 169], - ['ci', 170], - ['lr', 171], - ['bn', 172], - ['iq', 173], - ['ge', 174], - ['gm', 175], - ['ch', 176], - ['td', 177], - ['kv', 178], - ['lb', 179], - ['dj', 180], - ['bi', 181], - ['sr', 182], - ['il', 183], - ['ml', 184], - ['sn', 185], - ['gn', 186], - ['zw', 187], - ['pl', 188], - ['mk', 189], - ['py', 190], - ['by', 191], - ['cz', 192], - ['bf', 193], - ['na', 194], - ['ly', 195], - ['tn', 196], - ['bt', 197], - ['md', 198], - ['ss', 199], - ['bw', 200], - ['bs', 201], - ['nz', 202], - ['cu', 203], - ['ec', 204], - ['au', 205], - ['ve', 206], - ['sb', 207], - ['mg', 208], - ['is', 209], - ['eg', 210], - ['kg', 211], - ['np', 212] - ] - } as Highcharts.SeriesMapOptions, - { - // Specify points using lat/lon - type: 'mappoint', - name: 'Canada cities', - color: 'tomato', - data: [ - { - name: 'Vancouver', - lat: 49.246292, - lon: -123.116226 - }, - { - name: 'Quebec City', - lat: 46.829853, - lon: -71.254028 - }, - { - name: 'Yellowknife', - lat: 62.4540, - lon: -114.3718 - } - ] - } as Highcharts.SeriesMappointOptions] - }; - - // ---------------------------------------------------------------------- - // Demo #4 - - chartGantt: Highcharts.Options = { - title: { - text: 'Gantt Chart with Progress Indicators' - }, - xAxis: { - min: Date.UTC(2014, 10, 17), - max: Date.UTC(2014, 10, 30) - }, - - series: [{ - name: 'Project 1', - type: 'gantt', - data: [{ - name: 'Start prototype', - start: Date.UTC(2014, 10, 18), - end: Date.UTC(2014, 10, 25), - completed: 0.25 - }, { - name: 'Test prototype', - start: Date.UTC(2014, 10, 27), - end: Date.UTC(2014, 10, 29) - }, { - name: 'Develop', - start: Date.UTC(2014, 10, 20), - end: Date.UTC(2014, 10, 25), - completed: { - amount: 0.12, - fill: '#fa0' - } - }, { - name: 'Run acceptance tests', - start: Date.UTC(2014, 10, 23), - end: Date.UTC(2014, 10, 26) - }] - }] - }; - - - // ---------------------------------------------------------------------- - // Demo #5 - - chartLazyLoading: Highcharts.Options = { - chart: { - type: 'candlestick', - zoomType: 'x', - events: { - load: function() { - var chart = this; - - $.getJSON('https://www.highcharts.com/samples/data/from-sql.php?callback=?', function(data) { - // Add a null value for the end date - data = [].concat(data, [ - [Date.UTC(2011, 9, 14, 19, 59), null, null, null, null] - ]); - - chart.addSeries({ - data: data, - dataGrouping: { - enabled: false - } - } as Highcharts.SeriesOptionsType, false); - - chart.update({ - navigator: { - series: { - data: data - } - } - }); - }); - } - } - }, - - navigator: { - adaptToUpdatedData: false - }, - - scrollbar: { - liveRedraw: false - }, - - title: { - text: 'AAPL history by the minute from 1998 to 2011' - }, - - subtitle: { - text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading' - }, - - rangeSelector: { - buttons: [{ - type: 'hour', - count: 1, - text: '1h' - }, { - type: 'day', - count: 1, - text: '1d' - }, { - type: 'month', - count: 1, - text: '1m' - }, { - type: 'year', - count: 1, - text: '1y' - }, { - type: 'all', - text: 'All' - }], - inputEnabled: false, // it supports only days - selected: 4 // all - }, - - xAxis: { - events: { - afterSetExtremes: function(e) { - var chart = this.chart; - /** - * Load new data depending on the selected min and max - */ - chart.showLoading('Loading data from server...'); - $.getJSON('https://www.highcharts.com/samples/data/from-sql.php?start=' + Math.round(e.min) + - '&end=' + Math.round(e.max) + '&callback=?', - function(data) { - chart.series[0].setData(data); - chart.hideLoading(); - }); - } - }, - minRange: 3600 * 1000 // one hour - }, - - yAxis: { - floor: 0 - } - }; } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 77326aa..7cc9675 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -4,14 +4,18 @@ import { FormsModule } from "@angular/forms"; import { BrowserModule } from "@angular/platform-browser"; import { HighchartsChartModule } from "highcharts-angular"; import { AppComponent } from "./app.component"; - +import { LineChartComponent } from "./line-chart/line-chart.component"; +import { StockChartComponent } from "./stock-chart/stock-chart.component"; +import { MapChartComponent } from "./map-chart/map-chart.component"; +import { GanttChartComponent } from "./gantt-chart/gantt-chart.component"; +import { LazyLoadingChartComponent } from './lazy-loading-chart/lazy-loading-chart.component'; @NgModule({ - declarations: [AppComponent], + declarations: [AppComponent, LineChartComponent, StockChartComponent, MapChartComponent, GanttChartComponent, LazyLoadingChartComponent], imports: [ BrowserModule, FormsModule, HighchartsChartModule, - HttpClientModule + HttpClientModule, ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/gantt-chart/gantt-chart.component.css b/src/app/gantt-chart/gantt-chart.component.css new file mode 100644 index 0000000..2599cc8 --- /dev/null +++ b/src/app/gantt-chart/gantt-chart.component.css @@ -0,0 +1,23 @@ +h2 { + font-size: 20px; + color: #eeeaea; + background-color: #47475C; + padding: 10px; + } + + .full-left { + font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; + font-size: 14px; + float: left; + width: 98%; + background-color: #eee; + padding: 5px 1%; + } + .medium-right { + float: right; + width: 65%; + } + .third-left { + width: 30%; + float: left; + } \ No newline at end of file diff --git a/src/app/gantt-chart/gantt-chart.component.html b/src/app/gantt-chart/gantt-chart.component.html new file mode 100644 index 0000000..c06aa69 --- /dev/null +++ b/src/app/gantt-chart/gantt-chart.component.html @@ -0,0 +1,9 @@ +
+

Demo #4: Highcharts Gantt chart

+ +
\ No newline at end of file diff --git a/src/app/gantt-chart/gantt-chart.component.spec.ts b/src/app/gantt-chart/gantt-chart.component.spec.ts new file mode 100644 index 0000000..bb86a83 --- /dev/null +++ b/src/app/gantt-chart/gantt-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { GanttChartComponent } from './gantt-chart.component'; + +describe('GanttChartComponent', () => { + let component: GanttChartComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ GanttChartComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(GanttChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/gantt-chart/gantt-chart.component.ts b/src/app/gantt-chart/gantt-chart.component.ts new file mode 100644 index 0000000..a6bc83e --- /dev/null +++ b/src/app/gantt-chart/gantt-chart.component.ts @@ -0,0 +1,52 @@ +import { Component } from '@angular/core'; +import * as Highcharts from "highcharts/highcharts-gantt"; +import ExportingModule from 'highcharts/modules/exporting'; + +ExportingModule(Highcharts); + +@Component({ + selector: 'app-gantt-chart', + templateUrl: './gantt-chart.component.html', + styleUrls: ['./gantt-chart.component.css'] +}) +export class GanttChartComponent { + Highcharts: typeof Highcharts = Highcharts; + + chartGantt: Highcharts.Options = { + title: { + text: 'Gantt Chart with Progress Indicators' + }, + xAxis: { + min: Date.UTC(2014, 10, 17), + max: Date.UTC(2014, 10, 30) + }, + + series: [{ + name: 'Project 1', + type: 'gantt', + data: [{ + name: 'Start prototype', + start: Date.UTC(2014, 10, 18), + end: Date.UTC(2014, 10, 25), + completed: 0.25 + }, { + name: 'Test prototype', + start: Date.UTC(2014, 10, 27), + end: Date.UTC(2014, 10, 29) + }, { + name: 'Develop', + start: Date.UTC(2014, 10, 20), + end: Date.UTC(2014, 10, 25), + completed: { + amount: 0.12, + fill: '#fa0' + } + }, { + name: 'Run acceptance tests', + start: Date.UTC(2014, 10, 23), + end: Date.UTC(2014, 10, 26) + }] + }] + }; + +} diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.css b/src/app/lazy-loading-chart/lazy-loading-chart.component.css new file mode 100644 index 0000000..2599cc8 --- /dev/null +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.css @@ -0,0 +1,23 @@ +h2 { + font-size: 20px; + color: #eeeaea; + background-color: #47475C; + padding: 10px; + } + + .full-left { + font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; + font-size: 14px; + float: left; + width: 98%; + background-color: #eee; + padding: 5px 1%; + } + .medium-right { + float: right; + width: 65%; + } + .third-left { + width: 30%; + float: left; + } \ No newline at end of file diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.html b/src/app/lazy-loading-chart/lazy-loading-chart.component.html new file mode 100644 index 0000000..7d27fd5 --- /dev/null +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.html @@ -0,0 +1,10 @@ +
+

Demo #5: Lazy loading in Highstock

+ +
diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.spec.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.spec.ts new file mode 100644 index 0000000..283e764 --- /dev/null +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LazyLoadingChartComponent } from './lazy-loading-chart.component'; + +describe('LazyLoadingChartComponent', () => { + let component: LazyLoadingChartComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ LazyLoadingChartComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LazyLoadingChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/lazy-loading-chart/lazy-loading-chart.component.ts b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts new file mode 100644 index 0000000..15dab8b --- /dev/null +++ b/src/app/lazy-loading-chart/lazy-loading-chart.component.ts @@ -0,0 +1,112 @@ +import { Component } from '@angular/core'; +import * as Highcharts from 'highcharts/highstock'; +import $ from 'jquery'; + +@Component({ + selector: 'app-lazy-loading-chart', + templateUrl: './lazy-loading-chart.component.html', + styleUrls: ['./lazy-loading-chart.component.css'] +}) +export class LazyLoadingChartComponent { + + Highcharts: typeof Highcharts = Highcharts; + + chartLazyLoading: Highcharts.Options = { + chart: { + type: 'candlestick', + zoomType: 'x', + events: { + load: function() { + var chart = this; + + $.getJSON('https://www.highcharts.com/samples/data/from-sql.php?callback=?', function(data) { + // Add a null value for the end date + data = [].concat(data, [ + [Date.UTC(2011, 9, 14, 19, 59), null, null, null, null] + ]); + + chart.addSeries({ + data: data, + dataGrouping: { + enabled: false + } + } as Highcharts.SeriesOptionsType, false); + + chart.update({ + navigator: { + series: { + data: data + } + } + }); + }); + } + } + }, + + navigator: { + adaptToUpdatedData: false + }, + + scrollbar: { + liveRedraw: false + }, + + title: { + text: 'AAPL history by the minute from 1998 to 2011' + }, + + subtitle: { + text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading' + }, + + rangeSelector: { + buttons: [{ + type: 'hour', + count: 1, + text: '1h' + }, { + type: 'day', + count: 1, + text: '1d' + }, { + type: 'month', + count: 1, + text: '1m' + }, { + type: 'year', + count: 1, + text: '1y' + }, { + type: 'all', + text: 'All' + }], + inputEnabled: false, // it supports only days + selected: 4 // all + }, + + xAxis: { + events: { + afterSetExtremes: function(e) { + var chart = this.chart; + /** + * Load new data depending on the selected min and max + */ + chart.showLoading('Loading data from server...'); + $.getJSON('https://www.highcharts.com/samples/data/from-sql.php?start=' + Math.round(e.min) + + '&end=' + Math.round(e.max) + '&callback=?', + function(data) { + chart.series[0].setData(data); + chart.hideLoading(); + }); + } + }, + minRange: 3600 * 1000 // one hour + }, + + yAxis: { + floor: 0 + } + }; + +} diff --git a/src/app/line-chart/line-chart.component.css b/src/app/line-chart/line-chart.component.css new file mode 100644 index 0000000..2599cc8 --- /dev/null +++ b/src/app/line-chart/line-chart.component.css @@ -0,0 +1,23 @@ +h2 { + font-size: 20px; + color: #eeeaea; + background-color: #47475C; + padding: 10px; + } + + .full-left { + font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; + font-size: 14px; + float: left; + width: 98%; + background-color: #eee; + padding: 5px 1%; + } + .medium-right { + float: right; + width: 65%; + } + .third-left { + width: 30%; + float: left; + } \ No newline at end of file diff --git a/src/app/line-chart/line-chart.component.html b/src/app/line-chart/line-chart.component.html new file mode 100644 index 0000000..3989eb2 --- /dev/null +++ b/src/app/line-chart/line-chart.component.html @@ -0,0 +1,23 @@ +
+

Demo #1: Highcharts with a basic editor

+
+ +
+ +
+ +
+
+ +
+
\ No newline at end of file diff --git a/src/app/line-chart/line-chart.component.spec.ts b/src/app/line-chart/line-chart.component.spec.ts new file mode 100644 index 0000000..5c7bda4 --- /dev/null +++ b/src/app/line-chart/line-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { LineChartComponent } from './line-chart.component'; + +describe('LineChartComponent', () => { + let component: LineChartComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ LineChartComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(LineChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/line-chart/line-chart.component.ts b/src/app/line-chart/line-chart.component.ts new file mode 100644 index 0000000..4430302 --- /dev/null +++ b/src/app/line-chart/line-chart.component.ts @@ -0,0 +1,63 @@ +import { Component } from '@angular/core'; +import * as Highcharts from 'highcharts'; +import ExportingModule from 'highcharts/modules/exporting'; +import HC_customEvents from 'highcharts-custom-events'; +ExportingModule(Highcharts); +HC_customEvents(Highcharts); + +@Component({ + selector: 'app-line-chart', + templateUrl: './line-chart.component.html', + styleUrls: ['./line-chart.component.css'] +}) +export class LineChartComponent { + + // For all demos: + Highcharts: typeof Highcharts = Highcharts; // Highcharts, it's Highcharts + + // Demo #1 + optFromInputString: string = ` + { + "title": { "text": "Highcharts chart" }, + "series": [{ + "data": [11,2,3], + "zones": [{ + "value": 7.2, + "dashStyle": "dot", + "color": "red" + }] + }, { + "data": [5,6,7] + }] + } + `; + + optFromInput: Highcharts.Options = JSON.parse(this.optFromInputString); + updateFromInput: boolean = false; + + // Demonstrate chart instance + logChartInstance(chart: Highcharts.Chart) { + console.log('Chart instance: ', chart); + } + + updateInputChart() { + this.optFromInput = JSON.parse(this.optFromInputString); + } + + seriesTypes: {[key: string]: string} = { + line: 'column', + column: 'scatter', + scatter: 'spline', + spline: 'line' + }; + + toggleSeriesType(index: number = 0) { + this.optFromInput.series[index].type = + this.seriesTypes[this.optFromInput.series[index].type || 'line'] as + 'column' | 'scatter' | 'spline' | 'line'; + // nested change - must trigger update + this.updateFromInput = true; + } + + +} diff --git a/src/app/map-chart/map-chart.component.css b/src/app/map-chart/map-chart.component.css new file mode 100644 index 0000000..2599cc8 --- /dev/null +++ b/src/app/map-chart/map-chart.component.css @@ -0,0 +1,23 @@ +h2 { + font-size: 20px; + color: #eeeaea; + background-color: #47475C; + padding: 10px; + } + + .full-left { + font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; + font-size: 14px; + float: left; + width: 98%; + background-color: #eee; + padding: 5px 1%; + } + .medium-right { + float: right; + width: 65%; + } + .third-left { + width: 30%; + float: left; + } \ No newline at end of file diff --git a/src/app/map-chart/map-chart.component.html b/src/app/map-chart/map-chart.component.html new file mode 100644 index 0000000..ab54c17 --- /dev/null +++ b/src/app/map-chart/map-chart.component.html @@ -0,0 +1,10 @@ +
+

Demo #3: Highmaps map chart

+ +
\ No newline at end of file diff --git a/src/app/map-chart/map-chart.component.spec.ts b/src/app/map-chart/map-chart.component.spec.ts new file mode 100644 index 0000000..845abf5 --- /dev/null +++ b/src/app/map-chart/map-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MapChartComponent } from './map-chart.component'; + +describe('MapChartComponent', () => { + let component: MapChartComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ MapChartComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(MapChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/map-chart/map-chart.component.ts b/src/app/map-chart/map-chart.component.ts new file mode 100644 index 0000000..4716175 --- /dev/null +++ b/src/app/map-chart/map-chart.component.ts @@ -0,0 +1,297 @@ +import { Component } from '@angular/core'; +import * as Highcharts from "highcharts/highmaps"; +import ExportingModule from 'highcharts/modules/exporting'; +import worldMap from "@highcharts/map-collection/custom/world.geo.json"; +import proj4 from 'proj4'; +ExportingModule(Highcharts); + +// Legacy way of map loading - see file at the path for more info. +// require('../../js/worldmap')(Highcharts); + +@Component({ + selector: 'app-map-chart', + templateUrl: './map-chart.component.html', + styleUrls: ['./map-chart.component.css'] +}) + +export class MapChartComponent { + + Highcharts: typeof Highcharts = Highcharts; + + chartMap: Highcharts.Options = { + chart: { + map: worldMap as any, + proj4: proj4 + }, + title: { + text: 'Highmaps basic demo' + }, + subtitle: { + text: 'Source map: World, Miller projection, medium resolution' + }, + mapNavigation: { + enabled: true, + buttonOptions: { + alignTo: 'spacingBox' + } + }, + legend: { + enabled: true + }, + colorAxis: { + min: 0 + }, + series: [{ + name: 'Random data', + states: { + hover: { + color: '#BADA55' + } + }, + dataLabels: { + enabled: true, + format: '{point.name}' + }, + allAreas: false, + data: [ + ['fo', 0], + ['um', 1], + ['us', 2], + ['jp', 3], + ['sc', 4], + ['in', 5], + ['fr', 6], + ['fm', 7], + ['cn', 8], + ['pt', 9], + ['sw', 10], + ['sh', 11], + ['br', 12], + ['ki', 13], + ['ph', 14], + ['mx', 15], + ['es', 16], + ['bu', 17], + ['mv', 18], + ['sp', 19], + ['gb', 20], + ['gr', 21], + ['as', 22], + ['dk', 23], + ['gl', 24], + ['gu', 25], + ['mp', 26], + ['pr', 27], + ['vi', 28], + ['ca', 29], + ['st', 30], + ['cv', 31], + ['dm', 32], + ['nl', 33], + ['jm', 34], + ['ws', 35], + ['om', 36], + ['vc', 37], + ['tr', 38], + ['bd', 39], + ['lc', 40], + ['nr', 41], + ['no', 42], + ['kn', 43], + ['bh', 44], + ['to', 45], + ['fi', 46], + ['id', 47], + ['mu', 48], + ['se', 49], + ['tt', 50], + ['my', 51], + ['pa', 52], + ['pw', 53], + ['tv', 54], + ['mh', 55], + ['cl', 56], + ['th', 57], + ['gd', 58], + ['ee', 59], + ['ag', 60], + ['tw', 61], + ['bb', 62], + ['it', 63], + ['mt', 64], + ['vu', 65], + ['sg', 66], + ['cy', 67], + ['lk', 68], + ['km', 69], + ['fj', 70], + ['ru', 71], + ['va', 72], + ['sm', 73], + ['kz', 74], + ['az', 75], + ['tj', 76], + ['ls', 77], + ['uz', 78], + ['ma', 79], + ['co', 80], + ['tl', 81], + ['tz', 82], + ['ar', 83], + ['sa', 84], + ['pk', 85], + ['ye', 86], + ['ae', 87], + ['ke', 88], + ['pe', 89], + ['do', 90], + ['ht', 91], + ['pg', 92], + ['ao', 93], + ['kh', 94], + ['vn', 95], + ['mz', 96], + ['cr', 97], + ['bj', 98], + ['ng', 99], + ['ir', 100], + ['sv', 101], + ['sl', 102], + ['gw', 103], + ['hr', 104], + ['bz', 105], + ['za', 106], + ['cf', 107], + ['sd', 108], + ['cd', 109], + ['kw', 110], + ['de', 111], + ['be', 112], + ['ie', 113], + ['kp', 114], + ['kr', 115], + ['gy', 116], + ['hn', 117], + ['mm', 118], + ['ga', 119], + ['gq', 120], + ['ni', 121], + ['lv', 122], + ['ug', 123], + ['mw', 124], + ['am', 125], + ['sx', 126], + ['tm', 127], + ['zm', 128], + ['nc', 129], + ['mr', 130], + ['dz', 131], + ['lt', 132], + ['et', 133], + ['er', 134], + ['gh', 135], + ['si', 136], + ['gt', 137], + ['ba', 138], + ['jo', 139], + ['sy', 140], + ['mc', 141], + ['al', 142], + ['uy', 143], + ['cnm', 144], + ['mn', 145], + ['rw', 146], + ['so', 147], + ['bo', 148], + ['cm', 149], + ['cg', 150], + ['eh', 151], + ['rs', 152], + ['me', 153], + ['tg', 154], + ['la', 155], + ['af', 156], + ['ua', 157], + ['sk', 158], + ['jk', 159], + ['bg', 160], + ['qa', 161], + ['li', 162], + ['at', 163], + ['sz', 164], + ['hu', 165], + ['ro', 166], + ['ne', 167], + ['lu', 168], + ['ad', 169], + ['ci', 170], + ['lr', 171], + ['bn', 172], + ['iq', 173], + ['ge', 174], + ['gm', 175], + ['ch', 176], + ['td', 177], + ['kv', 178], + ['lb', 179], + ['dj', 180], + ['bi', 181], + ['sr', 182], + ['il', 183], + ['ml', 184], + ['sn', 185], + ['gn', 186], + ['zw', 187], + ['pl', 188], + ['mk', 189], + ['py', 190], + ['by', 191], + ['cz', 192], + ['bf', 193], + ['na', 194], + ['ly', 195], + ['tn', 196], + ['bt', 197], + ['md', 198], + ['ss', 199], + ['bw', 200], + ['bs', 201], + ['nz', 202], + ['cu', 203], + ['ec', 204], + ['au', 205], + ['ve', 206], + ['sb', 207], + ['mg', 208], + ['is', 209], + ['eg', 210], + ['kg', 211], + ['np', 212] + ] + } as Highcharts.SeriesMapOptions, + { + // Specify points using lat/lon + type: 'mappoint', + name: 'Canada cities', + color: 'tomato', + data: [ + { + name: 'Vancouver', + lat: 49.246292, + lon: -123.116226 + }, + { + name: 'Quebec City', + lat: 46.829853, + lon: -71.254028 + }, + { + name: 'Yellowknife', + lat: 62.4540, + lon: -114.3718 + } + ] + } as Highcharts.SeriesMappointOptions] + }; + +} diff --git a/src/app/stock-chart/stock-chart.component.css b/src/app/stock-chart/stock-chart.component.css new file mode 100644 index 0000000..2599cc8 --- /dev/null +++ b/src/app/stock-chart/stock-chart.component.css @@ -0,0 +1,23 @@ +h2 { + font-size: 20px; + color: #eeeaea; + background-color: #47475C; + padding: 10px; + } + + .full-left { + font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif; + font-size: 14px; + float: left; + width: 98%; + background-color: #eee; + padding: 5px 1%; + } + .medium-right { + float: right; + width: 65%; + } + .third-left { + width: 30%; + float: left; + } \ No newline at end of file diff --git a/src/app/stock-chart/stock-chart.component.html b/src/app/stock-chart/stock-chart.component.html new file mode 100644 index 0000000..312a19b --- /dev/null +++ b/src/app/stock-chart/stock-chart.component.html @@ -0,0 +1,27 @@ +
+

Demo #2: Highstock with simple updates

+
+

Chart title text:

+ +
+

Data sets:

+ +
+
+ +
+
diff --git a/src/app/stock-chart/stock-chart.component.spec.ts b/src/app/stock-chart/stock-chart.component.spec.ts new file mode 100644 index 0000000..643911b --- /dev/null +++ b/src/app/stock-chart/stock-chart.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StockChartComponent } from './stock-chart.component'; + +describe('StockChartComponent', () => { + let component: StockChartComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StockChartComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StockChartComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/stock-chart/stock-chart.component.ts b/src/app/stock-chart/stock-chart.component.ts new file mode 100644 index 0000000..ee9cb12 --- /dev/null +++ b/src/app/stock-chart/stock-chart.component.ts @@ -0,0 +1,114 @@ +import { Component } from '@angular/core'; +import * as Highcharts from 'highcharts/highstock'; +import ExportingModule from 'highcharts/modules/exporting'; +import HC_customEvents from 'highcharts-custom-events'; + +ExportingModule(Highcharts); +HC_customEvents(Highcharts); + + +// Alternative way of a plugin loading: +// const HC_ce = require('highcharts-custom-events'); +// HC_ce(Highcharts); + +@Component({ + selector: 'app-stock-chart', + templateUrl: './stock-chart.component.html', + styleUrls: ['./stock-chart.component.css'] +}) +export class StockChartComponent { + + Highcharts: typeof Highcharts = Highcharts; + + // starting values + updateDemo2: boolean = false; + usedIndex: number = 0; + chartTitle: string = 'My chart'; // for init - change through titleChange + + // change in all places + titleChange(event: any) { + var v = event; + this.chartTitle = v; + + this.charts.forEach((el) => { + el.hcOptions.title.text = v; + }); + + // trigger ngOnChanges + this.updateDemo2 = true; + }; + + charts = [{ + hcOptions: { + title: { text: this.chartTitle }, + subtitle: { text: '1st data set' }, + plotOptions: { + series: { + pointStart: Date.now(), + pointInterval: 86400000 // 1 day + } + }, + series: [{ + type: 'line', + data: [11, 2, 3], + threshold: 5, + negativeColor: 'red', + events: { + dblclick: function () { + console.log('dblclick - thanks to the Custom Events plugin'); + } + } + }, { + type: 'candlestick', + + data: [ + [0, 15, -6, 7], + [7, 12, -1, 3], + [3, 10, -3, 3] + ] + }] + } as Highcharts.Options, + hcCallback: (chart: Highcharts.Chart) => { + console.log('some variables: ', Highcharts, chart, this.charts); + } + }, { + hcOptions: { + title: { text: this.chartTitle }, + subtitle: { text: '2nd data set' }, + series: [{ + type: 'column', + data: [4, 3, -12], + threshold: -10 + }, { + type: 'ohlc', + data: [ + [0, 15, -6, 7], + [7, 12, -1, 3], + [3, 10, -3, 3] + ] + }] + } as Highcharts.Options, + hcCallback: () => {} + }, { + hcOptions: { + title: { text: this.chartTitle }, + subtitle: { text: '3rd data set' }, + series: [{ + type: 'scatter', + data: [1, 2, 3, 4, 5] + }, { + type: 'areaspline', + data: [ + 5, + 11, + 3, + 6, + 0 + ] + }] + } as Highcharts.Options, + hcCallback: () => {} + }]; + + +} diff --git a/tsconfig.json b/tsconfig.json index a5d1d0d..4930425 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,7 @@ { "compileOnSave": false, "compilerOptions": { + "allowSyntheticDefaultImports": true, "baseUrl": "./", "downlevelIteration": true, "outDir": "./dist/out-tsc", @@ -11,6 +12,7 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": true, + "resolveJsonModule": true, "target": "es2015", "typeRoots": [ "node_modules/@types" @@ -21,6 +23,7 @@ ] }, "angularCompilerOptions": { - "fullTemplateTypeCheck": true + "fullTemplateTypeCheck": true, + "enableIvy": false } }