Skip to content

Commit

Permalink
Merge pull request #12 from AleksueiR/master
Browse files Browse the repository at this point in the history
`setExtreme` events and chart `refresh` fixes
  • Loading branch information
spencerwahl authored Jan 17, 2018
2 parents 586bc81 + 9dda712 commit a60d9dc
Show file tree
Hide file tree
Showing 13 changed files with 2,296 additions and 1,969 deletions.
3,789 changes: 1,979 additions & 1,810 deletions docs/samples/dqvue.js

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dqvue",
"version": "0.4.0",
"version": "0.4.2",
"description": "",
"main": "./dist/dqvue.js",
"types": "./index.d.ts",
Expand Down Expand Up @@ -42,8 +42,5 @@
"webpack-bundle-analyzer": "^2.9.2",
"wnumb": "^1.1.0",
"yargs": "9.0.1"
},
"dependencies": {
"vue-template-compiler": "^2.5.13"
}
}
7 changes: 3 additions & 4 deletions poi.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ module.exports = {
})
],
extendWebpack(config) {
config.resolve.alias
.set('vue$', 'vue/dist/vue.esm.js') // vue.esm include template compiler; without it all templates need to be pre-compiled
.set('highcharts', 'highcharts/highcharts.src.js'); // include non-minified highcharts into the dev build
config.resolve.alias.set('vue$', 'vue/dist/vue.esm.js'); // vue.esm include template compiler; without it all templates need to be pre-compiled

config.output.set('library', 'DQV').set('libraryExport', 'default'); // exposes the default export directly on the global library variable: https://webpack.js.org/configuration/output/#output-libraryexport

Expand All @@ -40,6 +38,7 @@ module.exports = {
karma: {
mime: {
'text/x-typescript': ['ts']
}
},
karmaTypescriptConfig: undefined
}
};
17 changes: 14 additions & 3 deletions src/api/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DVSection } from './../classes/section';
import { DVChart } from './../classes/chart';
import { sections, charts } from './../store/main';

import { sectionCreatedSubject, chartCreatedSubject } from './../observable-bus';
import { sectionCreated, chartCreated } from './../observable-bus';

import { Observable } from 'rxjs/Observable';

Expand All @@ -32,6 +32,15 @@ function importHighcharts(): void {

// semi-public functionality not exposed on the HC declarations
export namespace DVHighcharts {
export interface Options extends Highcharts.Options {
exporting: ExportingOptions;
}

export interface ExportingOptions extends Highcharts.ExportingOptions {
// `menuItemDefinitions` is not included in the `ExportingOptions` type
menuItemDefinitions: { [name: string]: MenuItem | null };
}

export interface ChartObject extends Highcharts.ChartObject {
// https://api.highcharts.com/highcharts/chart.resetZoomButton
resetZoomButton: Highcharts.ElementObject | undefined;
Expand All @@ -50,6 +59,8 @@ export namespace DVHighcharts {
minRange: number;
}

export interface AxisEvent extends Highcharts.AxisEvent {}

// https://api.highcharts.com/highcharts/exporting.menuItemDefinitions
export interface MenuItem extends Highcharts.MenuItem {
text: string;
Expand All @@ -73,8 +84,8 @@ export default {
Section: DVSection,
Chart: DVChart,

sectionCreated: sectionCreatedSubject.asObservable(),
chartCreated: chartCreatedSubject.asObservable(),
sectionCreated: sectionCreated.asObservable(),
chartCreated: chartCreated.asObservable(),

get sections(): { [name: string]: DVSection } {
// TODO: return a clone instead of original object so users can't mess with it
Expand Down
94 changes: 59 additions & 35 deletions src/classes/chart.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,25 @@
import uniqid from 'uniqid';
import loglevel from 'loglevel';
import deepmerge from 'deepmerge';

import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
import 'rxjs/add/operator/filter';

import { DVHighcharts } from './../api/main';

import { chartCreatedSubject } from './../observable-bus';
import {
chartCreated,
chartRendered,
chartViewData,
chartConfigUpdated,
ChartEvent,
ChartRenderedEvent,
ChartViewDataEvent
} from './../observable-bus';

import { isPromise } from './../utils';
import Chart, { RenderedEvent, ViewDataEvent } from './../components/chart.vue';
import { DVSection } from './section';

const log: loglevel.Logger = loglevel.getLogger('dv-chart');

Expand All @@ -20,42 +29,41 @@ export type SeriesData =

export interface DVChartOptions {
id?: string;
config?: Highcharts.Options | Promise<Highcharts.Options>;
config?: DVHighcharts.Options | Promise<DVHighcharts.Options>;
data?: SeriesData | Promise<SeriesData>;
}

export class DVChart {
private static configDefaults: DVHighcharts.Options = {
xAxis: {
events: {
setExtremes: () => {}
}
},
exporting: {
menuItemDefinitions: {}
}
};

readonly id: string;

private _isConfigValid: boolean = false;

private _config: Highcharts.Options | null = null;
private _configPromise: Promise<Highcharts.Options> | null = null;
private _config: DVHighcharts.Options | null = null;
private _configPromise: Promise<DVHighcharts.Options> | null = null;
private _data: SeriesData | null = null;
private _dataPromise: Promise<SeriesData> | null = null;

private _isTableGenerated: boolean = false;

private _highchartObject: DVHighcharts.ChartObject | null = null;

private _renderedSubject: Subject<DVHighcharts.ChartObject> = new Subject<
DVHighcharts.ChartObject
>();
get rendered(): Observable<DVHighcharts.ChartObject> {
return this._renderedSubject.asObservable();
}

private _configUpdatedSubject: Subject<DVChart> = new Subject<DVChart>();
get configUpdated(): Observable<DVChart> {
return this._configUpdatedSubject.asObservable();
}

constructor({ id = uniqid.time(), config = null, data = null }: DVChartOptions = {}) {
this.id = id;

log.info(`[chart='${this.id}'] new chart is created`);

if (isPromise<Highcharts.Options>(config)) {
if (isPromise<DVHighcharts.Options>(config)) {
this.setConfig(config);
} else if (config !== null) {
this.config = config;
Expand All @@ -69,20 +77,17 @@ export class DVChart {

// TODO: merge observable from the chart view to the rendered observable here
// every time the chart is re-rendered, store the reference to the highchart object
Chart.rendered
.filter(event => event.chartId === this.id)
.subscribe((event: RenderedEvent) => {
this._highchartObject = event.highchartObject;
this._renderedSubject.next(this._highchartObject);
});

Chart.viewData
.filter((event: ViewDataEvent) => {
return event.chartId === this.id;
})
chartRendered
.filter(this._filterStream, this)
.subscribe(
(event: ChartRenderedEvent) => (this._highchartObject = event.highchartObject)
);

chartViewData
.filter(this._filterStream, this)
.subscribe(() => (this._isTableGenerated = true));

chartCreatedSubject.next(this);
chartCreated.next({ chartId: this.id, dvchart: this });
}

get isTableGenerated(): boolean {
Expand All @@ -97,8 +102,8 @@ export class DVChart {
return this._highchartObject;
}

set config(value: Highcharts.Options | null) {
this._config = value;
set config(value: DVHighcharts.Options | null) {
this._config = this._addConfigDefaults(value);
this._configPromise = null;

log.info(`[chart='${this.id}'] config value is set successfully`);
Expand All @@ -107,7 +112,7 @@ export class DVChart {
this._validateConfig();
}

setConfig(value: Promise<Highcharts.Options>): DVChart {
setConfig(value: Promise<DVHighcharts.Options>): DVChart {
log.info(`[chart='${this.id}'] waiting for config promise to resolve`);

this._configPromise = value;
Expand All @@ -120,10 +125,25 @@ export class DVChart {
return this;
}

get config(): Highcharts.Options | null {
get config(): DVHighcharts.Options | null {
return this._config;
}

/**
* apply some default/empty values to the config which are used by internal compoenents
* this makes it easier to access them without have to check if they exist all the time
*
* @private
* @memberof DVChart
*/
private _addConfigDefaults(config: DVHighcharts.Options | null): DVHighcharts.Options | null {
if (!config) {
return null;
}

return deepmerge(DVChart.configDefaults, config);
}

set data(value: SeriesData | null) {
this._data = value;
this._dataPromise = null;
Expand Down Expand Up @@ -212,7 +232,7 @@ export class DVChart {
log.info(`[chart='${this.id}'] chart config is valid`);

this._isConfigValid = true;
this._configUpdatedSubject.next(this);
chartConfigUpdated.next({ chartId: this.id, dvchart: this });
}

get isConfigValid(): boolean {
Expand All @@ -228,4 +248,8 @@ export class DVChart {
return this;
} */

private _filterStream(event: ChartEvent): boolean {
return event.chartId === this.id;
}
}
5 changes: 3 additions & 2 deletions src/classes/section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { DVChart } from './chart';
import Chart from './../components/chart.vue';
import ChartTable from './../components/chart-table.vue';

import { sectionCreatedSubject } from './../observable-bus';
import { sectionCreated } from './../observable-bus';

import { isPromise, isFunction, isString, isObject } from './../utils';
// TODO: constrain logging to 'warn' in production builds
Expand Down Expand Up @@ -60,7 +60,7 @@ export class DVSection {
}

// push the new section through the stream
sectionCreatedSubject.next(this);
sectionCreated.next({ sectionId: this.id, dvsection: this });

if (mount) {
this._mount = mount;
Expand Down Expand Up @@ -287,6 +287,7 @@ export class DVSection {
}

// TODO: when dismouning a section, remove all the chart tables originating from charts in this section, even ones that are in different sections
// TODO: maybe instead of removing all the chart tables in other sections, just hide them and reactivate them if the section with their parent chart is remounted
this._vm.$destroy();
this._isMounted = false;

Expand Down
Loading

0 comments on commit a60d9dc

Please sign in to comment.