mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-02 01:25:39 -05:00
Upgrading chartjs to 4.3 and removing ng2-charts from modelview (#23398)
* Upgrading chartjs * Upgrading charjs in exthost and removing ng2-charts * Updating lock file * Fixing paths in workbench for new chartjs * Removing more any * Removing more any * Fixing colors * Fixing more stuff * Updating distro hash
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as chartjs from 'chart.js';
|
||||
import 'chartjs-adapter-moment'; // Importing this library as datetime adapters are not included in the main chart.js bundle.
|
||||
|
||||
import { mixin } from 'sql/base/common/objects';
|
||||
import { localize } from 'vs/nls';
|
||||
@@ -11,8 +12,8 @@ import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||
import { editorLineNumbers } from 'vs/editor/common/core/editorColorRegistry';
|
||||
import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
import { IInsight, IPointDataSet, customMixin } from './interfaces';
|
||||
import { IInsightOptions, DataDirection, ChartType, LegendPosition, DataType } from 'sql/workbench/contrib/charts/common/interfaces';
|
||||
import { IInsight, customMixin } from './interfaces';
|
||||
import { IInsightOptions, DataDirection, ChartType, LegendPosition, DataType, ChartTypeToChartJsType, LegendPositionToChartJsPosition } from 'sql/workbench/contrib/charts/common/interfaces';
|
||||
import { values } from 'vs/base/common/collections';
|
||||
import { IInsightData } from 'sql/platform/dashboard/browser/insightRegistry';
|
||||
|
||||
@@ -20,7 +21,7 @@ const noneLineGraphs = [ChartType.Doughnut, ChartType.Pie];
|
||||
|
||||
const timeSeriesScales: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
x: {
|
||||
type: 'time',
|
||||
display: true,
|
||||
ticks: {
|
||||
@@ -28,11 +29,10 @@ const timeSeriesScales: chartjs.ChartOptions = {
|
||||
maxRotation: 45,
|
||||
minRotation: 45
|
||||
}
|
||||
}],
|
||||
|
||||
yAxes: [{
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -44,7 +44,7 @@ const defaultOptions: IInsightOptions = {
|
||||
export class Graph implements IInsight {
|
||||
private _options: IInsightOptions = { type: ChartType.Bar };
|
||||
private canvas: HTMLCanvasElement;
|
||||
private chartjs?: chartjs;
|
||||
private chartjs?: chartjs.Chart<chartjs.ChartType>;
|
||||
private _data?: IInsightData;
|
||||
|
||||
private originalType?: ChartType;
|
||||
@@ -58,6 +58,10 @@ export class Graph implements IInsight {
|
||||
container: HTMLElement, options: IInsightOptions = defaultOptions,
|
||||
@IThemeService themeService: IThemeService
|
||||
) {
|
||||
|
||||
chartjs.Chart.register(
|
||||
...chartjs.registerables,
|
||||
);
|
||||
this._theme = themeService.getColorTheme();
|
||||
themeService.onDidColorThemeChange(e => {
|
||||
this._theme = e;
|
||||
@@ -94,8 +98,8 @@ export class Graph implements IInsight {
|
||||
return;
|
||||
}
|
||||
this._data = data;
|
||||
let labels: Array<string>;
|
||||
let chartData: Array<Chart.ChartDataSets>;
|
||||
let labels: string[];
|
||||
let chartData: chartjs.ChartDataset[];
|
||||
|
||||
if (this.options.dataDirection === DataDirection.Horizontal) {
|
||||
if (this.options.labelFirstColumn) {
|
||||
@@ -108,14 +112,16 @@ export class Graph implements IInsight {
|
||||
}
|
||||
|
||||
if (this.originalType === ChartType.TimeSeries) {
|
||||
let dataSetMap: { [label: string]: IPointDataSet } = {};
|
||||
let dataSetMap: { [label: string]: chartjs.ChartDataset<'line', any[]> } = {};
|
||||
this._data.rows.map(row => {
|
||||
if (row && row.length >= 3) {
|
||||
let legend = row[0];
|
||||
const dataPoint = { x: row[1], y: Number(row[2]) };
|
||||
if (!dataSetMap[legend]) {
|
||||
dataSetMap[legend] = { label: legend, data: [], fill: false };
|
||||
dataSetMap[legend] = { label: legend, data: [dataPoint] };
|
||||
} else {
|
||||
dataSetMap[legend].data.push((dataPoint));
|
||||
}
|
||||
dataSetMap[legend].data.push({ x: row[1], y: Number(row[2]) });
|
||||
}
|
||||
});
|
||||
chartData = values(dataSetMap);
|
||||
@@ -159,13 +165,18 @@ export class Graph implements IInsight {
|
||||
return mixin(c, getColors(this.options.type, i, c.data!.length), false);
|
||||
});
|
||||
|
||||
if (this.options.type === 'horizontalBar') {
|
||||
this.options.type = ChartType.Bar;
|
||||
this.options.indexAxis = 'y';
|
||||
}
|
||||
if (this.chartjs) {
|
||||
this.chartjs.data.datasets = chartData;
|
||||
this.chartjs.config.type = this.options.type;
|
||||
(<chartjs.ChartConfiguration>this.chartjs.config).type = ChartTypeToChartJsType[this.options.type]
|
||||
// we don't want to include lables for timeSeries
|
||||
this.chartjs.data.labels = this.originalType === 'timeSeries' ? [] : labels;
|
||||
this.chartjs.options = this.transformOptions(this.options);
|
||||
this.chartjs.update({ duration: 0 });
|
||||
|
||||
this.chartjs.update();
|
||||
} else {
|
||||
this.chartjs = new chartjs.Chart(this.canvas.getContext('2d')!, {
|
||||
data: {
|
||||
@@ -173,14 +184,14 @@ export class Graph implements IInsight {
|
||||
labels: this.originalType === 'timeSeries' ? [] : labels,
|
||||
datasets: chartData
|
||||
},
|
||||
type: this.options.type,
|
||||
type: ChartTypeToChartJsType[this.options.type],
|
||||
options: this.transformOptions(this.options)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private transformOptions(options: IInsightOptions): Chart.ChartOptions {
|
||||
let retval: Chart.ChartOptions = {};
|
||||
private transformOptions(options: IInsightOptions): chartjs.ChartOptions {
|
||||
let retval: chartjs.ChartOptions = {};
|
||||
retval.maintainAspectRatio = false;
|
||||
|
||||
let foregroundColor = this._theme.getColor(colors.editorForeground);
|
||||
@@ -194,19 +205,19 @@ export class Graph implements IInsight {
|
||||
retval.scales = {};
|
||||
// we only want to include axis if it is a axis based graph type
|
||||
if (!noneLineGraphs.find(x => x === options.type as ChartType)) {
|
||||
retval.scales.xAxes = [{
|
||||
scaleLabel: {
|
||||
fontColor: foreground,
|
||||
labelString: options.xAxisLabel,
|
||||
display: options.xAxisLabel ? true : false
|
||||
},
|
||||
retval.scales.x = {
|
||||
ticks: {
|
||||
fontColor: foreground
|
||||
color: foreground,
|
||||
},
|
||||
gridLines: {
|
||||
grid: {
|
||||
color: gridLines
|
||||
},
|
||||
title: {
|
||||
color: foreground,
|
||||
text: options.xAxisLabel,
|
||||
display: options.xAxisLabel ? true : false
|
||||
}
|
||||
}];
|
||||
};
|
||||
|
||||
if (options.xAxisMax !== undefined) {
|
||||
retval.scales = mixin(retval.scales, { xAxes: [{ ticks: { max: options.xAxisMax } }] }, true, customMixin);
|
||||
@@ -216,19 +227,19 @@ export class Graph implements IInsight {
|
||||
retval.scales = mixin(retval.scales, { xAxes: [{ ticks: { min: options.xAxisMin } }] }, true, customMixin);
|
||||
}
|
||||
|
||||
retval.scales!.yAxes = [{
|
||||
scaleLabel: {
|
||||
fontColor: foreground,
|
||||
labelString: options.yAxisLabel,
|
||||
display: options.yAxisLabel ? true : false
|
||||
},
|
||||
retval.scales.y = {
|
||||
ticks: {
|
||||
fontColor: foreground
|
||||
color: foreground
|
||||
},
|
||||
gridLines: {
|
||||
grid: {
|
||||
color: gridLines
|
||||
},
|
||||
title: {
|
||||
color: foreground,
|
||||
text: options.yAxisLabel,
|
||||
display: options.yAxisLabel ? true : false
|
||||
}
|
||||
}];
|
||||
};
|
||||
|
||||
if (options.yAxisMax !== undefined) {
|
||||
retval.scales = mixin(retval.scales, { yAxes: [{ ticks: { max: options.yAxisMax } }] }, true, customMixin);
|
||||
@@ -266,13 +277,19 @@ export class Graph implements IInsight {
|
||||
}
|
||||
}
|
||||
|
||||
retval.legend = <Chart.ChartLegendOptions>{
|
||||
position: options.legendPosition as Chart.PositionType,
|
||||
display: options.legendPosition !== LegendPosition.None,
|
||||
labels: {
|
||||
fontColor: foreground
|
||||
retval.plugins = {
|
||||
legend: {
|
||||
position: LegendPositionToChartJsPosition[options.legendPosition],
|
||||
display: options.legendPosition !== LegendPosition.None,
|
||||
labels: {
|
||||
color: foreground
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
if (options.indexAxis === 'y') {
|
||||
retval.indexAxis = 'y';
|
||||
}
|
||||
}
|
||||
|
||||
// these are custom options that will throw compile errors
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as chartjs from 'chart.js';
|
||||
|
||||
export interface IInsightOptions {
|
||||
type: InsightType | ChartType;
|
||||
dataDirection?: DataDirection;
|
||||
@@ -18,6 +20,7 @@ export interface IInsightOptions {
|
||||
xAxisMax?: number;
|
||||
encoding?: string;
|
||||
imageFormat?: string;
|
||||
indexAxis?: string;
|
||||
}
|
||||
|
||||
export enum InsightType {
|
||||
@@ -36,6 +39,16 @@ export enum ChartType {
|
||||
Scatter = 'scatter'
|
||||
}
|
||||
|
||||
export const ChartTypeToChartJsType: { [key in ChartType]: chartjs.ChartType } = {
|
||||
'bar': 'bar',
|
||||
'doughnut': 'doughnut',
|
||||
'horizontalBar': 'bar',
|
||||
'line': 'line',
|
||||
'pie': 'pie',
|
||||
'timeSeries': 'line',
|
||||
'scatter': 'scatter'
|
||||
}
|
||||
|
||||
export enum LegendPosition {
|
||||
Top = 'top',
|
||||
Bottom = 'bottom',
|
||||
@@ -44,6 +57,14 @@ export enum LegendPosition {
|
||||
None = 'none'
|
||||
}
|
||||
|
||||
export const LegendPositionToChartJsPosition: { [key in LegendPosition]: chartjs.LayoutPosition } = {
|
||||
'top': 'top',
|
||||
'bottom': 'bottom',
|
||||
'left': 'left',
|
||||
'right': 'right',
|
||||
'none': 'left' // chart.js doesn't have a 'none' option, so we use 'left' and then hide the legend
|
||||
}
|
||||
|
||||
export enum DataType {
|
||||
Number = 'number',
|
||||
Point = 'point'
|
||||
|
||||
@@ -9,7 +9,6 @@ import { BrowserModule } from '@angular/platform-browser';
|
||||
import { RouterModule, Routes, UrlSerializer, Router, NavigationEnd } from '@angular/router';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { NgGridModule } from 'angular2-grid';
|
||||
import { ChartsModule } from 'ng2-charts';
|
||||
|
||||
import CustomUrlSerializer from 'sql/base/browser/urlSerializer';
|
||||
import { Extensions, IInsightRegistry } from 'sql/platform/dashboard/browser/insightRegistry';
|
||||
@@ -140,7 +139,6 @@ export const DashboardModule = (params, selector: string, instantiationService:
|
||||
BrowserModule,
|
||||
FormsModule,
|
||||
NgGridModule,
|
||||
ChartsModule,
|
||||
RouterModule.forRoot(appRoutes),
|
||||
PanelModule,
|
||||
ScrollableModule,
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<div style="display: block; width: 100%; height: 100%; position: relative">
|
||||
<div #chartContainer *ngIf="_isDataAvailable && _hasInit" style="width: 100%; height: 100%"></div>
|
||||
<div *ngIf="_hasError">{{CHART_ERROR_MESSAGE}}</div>
|
||||
</div>
|
||||
@@ -3,43 +3,35 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Component, Input, Inject, ChangeDetectorRef, forwardRef, ViewChild } from '@angular/core';
|
||||
import { BaseChartDirective } from 'ng2-charts';
|
||||
|
||||
import { Component, Input, Inject, ChangeDetectorRef, forwardRef, ViewChild, ElementRef } from '@angular/core';
|
||||
import * as chartjs from 'chart.js';
|
||||
|
||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys';
|
||||
import { mixin } from 'sql/base/common/objects';
|
||||
import { defaultChartConfig, IChartConfig, IDataSet } from 'sql/workbench/contrib/dashboard/browser/widgets/insights/views/charts/interfaces';
|
||||
import { defaultChartConfig, IChartConfig } from 'sql/workbench/contrib/dashboard/browser/widgets/insights/views/charts/interfaces';
|
||||
|
||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IThemeService, IColorTheme } from 'vs/platform/theme/common/themeService';
|
||||
import { IPointDataSet } from 'sql/workbench/contrib/charts/browser/interfaces';
|
||||
import { IInsightsView, IInsightData } from 'sql/platform/dashboard/browser/insightRegistry';
|
||||
import { ChartType, LegendPosition } from 'sql/workbench/contrib/charts/common/interfaces';
|
||||
import { ChartType, ChartTypeToChartJsType, LegendPosition } from 'sql/workbench/contrib/charts/common/interfaces';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
|
||||
@Component({
|
||||
template: ` <div style="display: block; width: 100%; height: 100%; position: relative">
|
||||
<canvas #canvas *ngIf="_isDataAvailable && _hasInit"
|
||||
baseChart
|
||||
[datasets]="chartData"
|
||||
[labels]="labels"
|
||||
[chartType]="chartType"
|
||||
[colors]="colors"
|
||||
[options]="_options"></canvas>
|
||||
<div *ngIf="_hasError">{{CHART_ERROR_MESSAGE}}</div>
|
||||
</div>`
|
||||
templateUrl: decodeURI(require.toUrl('./chartInsight.component.html'))
|
||||
})
|
||||
export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
private _isDataAvailable: boolean = false;
|
||||
protected _hasInit: boolean = false;
|
||||
protected _hasError: boolean = false;
|
||||
private _options: any = {};
|
||||
private _options: chartjs.ChartOptions = {};
|
||||
private _chart: chartjs.Chart;
|
||||
private _chartCanvas: HTMLCanvasElement;
|
||||
|
||||
@ViewChild(BaseChartDirective) private _chart: BaseChartDirective;
|
||||
@ViewChild('chartContainer') private _chartContainer: ElementRef;
|
||||
|
||||
protected _defaultConfig = defaultChartConfig;
|
||||
protected _config: IChartConfig;
|
||||
@@ -55,6 +47,10 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
@Inject(IAdsTelemetryService) private _telemetryService: IAdsTelemetryService
|
||||
) {
|
||||
super();
|
||||
chartjs.Chart.register(
|
||||
...chartjs.registerables,
|
||||
);
|
||||
chartjs.Chart.register(chartjs.Colors);
|
||||
}
|
||||
|
||||
init() {
|
||||
@@ -73,6 +69,20 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
this._hasError = true;
|
||||
this._changeRef.detectChanges();
|
||||
}
|
||||
this._chartCanvas = document.createElement('canvas');
|
||||
this._chartContainer.nativeElement.appendChild(this._chartCanvas);
|
||||
this._chartCanvas.style.width = '100%';
|
||||
this._chartCanvas.style.height = '100%';
|
||||
this._chart = new chartjs.Chart(this._chartCanvas, {
|
||||
type: ChartTypeToChartJsType[this.chartType],
|
||||
data: {
|
||||
labels: this.labels,
|
||||
datasets: this.chartData,
|
||||
},
|
||||
options: this.options
|
||||
});
|
||||
this.refresh();
|
||||
|
||||
this._telemetryService.createActionEvent(TelemetryKeys.TelemetryView.Shell, TelemetryKeys.TelemetryAction.ChartCreated)
|
||||
.withAdditionalProperties({ type: this.chartType })
|
||||
.send();
|
||||
@@ -81,7 +91,7 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
/**
|
||||
* Sets the options for the chart; handles rerendering the chart if needed
|
||||
*/
|
||||
public set options(options: any) {
|
||||
public set options(options: chartjs.ChartOptions) {
|
||||
this._options = options;
|
||||
if (this._isDataAvailable) {
|
||||
this._options = mixin({}, mixin(this._options, { animation: { duration: 0 } }));
|
||||
@@ -89,24 +99,20 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
}
|
||||
}
|
||||
|
||||
public get options(): any {
|
||||
public get options(): chartjs.ChartOptions {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
protected updateTheme(e: IColorTheme): void {
|
||||
const foregroundColor = e.getColor(colors.editorForeground);
|
||||
const foreground = foregroundColor ? foregroundColor.toString() : null;
|
||||
const backgroundColor = e.getColor(colors.editorBackground);
|
||||
const background = backgroundColor ? backgroundColor.toString() : null;
|
||||
|
||||
const options = {
|
||||
legend: {
|
||||
labels: {
|
||||
fontColor: foreground
|
||||
const options: chartjs.ChartOptions = {
|
||||
plugins: {
|
||||
legend: {
|
||||
labels: {
|
||||
color: foreground
|
||||
}
|
||||
}
|
||||
},
|
||||
viewArea: {
|
||||
backgroundColor: background
|
||||
}
|
||||
};
|
||||
this.options = mixin({}, mixin(this.options, options));
|
||||
@@ -115,13 +121,24 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
public refresh() {
|
||||
// cheaper refresh but causes problems when change data for rerender
|
||||
if (this._chart) {
|
||||
this._chart.ngOnChanges({});
|
||||
this._chart.options = this.options;
|
||||
this._chart.data.datasets = this.chartData;
|
||||
this._chart.data.labels = this.labels;
|
||||
this._chart.config['type'] = ChartTypeToChartJsType[this.chartType];
|
||||
this._chart.update();
|
||||
}
|
||||
}
|
||||
|
||||
public getCanvasData(): string {
|
||||
if (this._chart && this._chart.chart) {
|
||||
return this._chart.chart.toBase64Image();
|
||||
public refreshChartOptions() {
|
||||
if (this._chart) {
|
||||
this._chart.options = this.options;
|
||||
this._chart.update();
|
||||
}
|
||||
}
|
||||
|
||||
public getCanvasData(): string | undefined {
|
||||
if (this._chart) {
|
||||
return this._chart.toBase64Image();
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
@@ -184,8 +201,8 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
|
||||
/* Typescript does not allow you to access getters/setters for super classes.
|
||||
his is a workaround that allows us to still call base getter */
|
||||
private _cachedChartData: Array<IDataSet>;
|
||||
protected getChartData(): Array<IDataSet> {
|
||||
private _cachedChartData: chartjs.ChartDataset[];
|
||||
protected getChartData(): chartjs.ChartDataset[] {
|
||||
if (!this._cachedChartData) {
|
||||
if (this._config.dataDirection === 'horizontal') {
|
||||
if (this._config.labelFirstColumn) {
|
||||
@@ -224,7 +241,7 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
return this._cachedChartData;
|
||||
}
|
||||
|
||||
public get chartData(): Array<IDataSet | IPointDataSet> {
|
||||
public get chartData(): chartjs.ChartDataset[] {
|
||||
return this.getChartData();
|
||||
}
|
||||
|
||||
@@ -265,16 +282,18 @@ export abstract class ChartInsight extends Disposable implements IInsightsView {
|
||||
}
|
||||
|
||||
public set legendPosition(input: LegendPosition) {
|
||||
const options = {
|
||||
legend: {
|
||||
display: true,
|
||||
position: 'top'
|
||||
const options: chartjs.ChartOptions = {
|
||||
plugins: {
|
||||
legend: {
|
||||
position: 'top',
|
||||
display: true
|
||||
}
|
||||
}
|
||||
};
|
||||
if (input === 'none') {
|
||||
options.legend.display = false;
|
||||
options.plugins.legend.display = false;
|
||||
} else {
|
||||
options.legend.position = input;
|
||||
options.plugins.legend.position = input;
|
||||
}
|
||||
this.options = mixin(this.options, options);
|
||||
}
|
||||
@@ -295,13 +314,3 @@ function isValidData(data: IInsightData): boolean {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
chartjs.Chart.pluginService.register({
|
||||
beforeDraw: function (chart) {
|
||||
if ((chart.config.options as any).viewArea && (chart.config.options as any).viewArea.backgroundColor) {
|
||||
let ctx = (chart as any).chart.ctx;
|
||||
ctx.fillStyle = (chart.config.options as any).viewArea.backgroundColor;
|
||||
ctx.fillRect(0, 0, (chart as any).chart.width, (chart as any).chart.height);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import { ChartInsight } from 'sql/workbench/contrib/dashboard/browser/widgets/insights/views/charts/chartInsight.component';
|
||||
import { mixin } from 'sql/base/common/objects';
|
||||
import { IChartConfig } from 'sql/workbench/contrib/dashboard/browser/widgets/insights/views/charts/interfaces';
|
||||
import * as chartjs from 'chart.js';
|
||||
|
||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||
import { editorLineNumbers } from 'vs/editor/common/core/editorColorRegistry';
|
||||
@@ -36,88 +37,80 @@ export default class BarChart extends ChartInsight {
|
||||
}
|
||||
|
||||
public override setConfig(config: IBarChartConfig): void {
|
||||
let options = {};
|
||||
let options: chartjs.ChartOptions = {};
|
||||
if (config.xAxisMax) {
|
||||
const opts = {
|
||||
const opts: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
x: {
|
||||
display: true,
|
||||
ticks: {
|
||||
max: config.xAxisMax
|
||||
}
|
||||
}]
|
||||
max: config.xAxisMax
|
||||
}
|
||||
}
|
||||
};
|
||||
options = mixin({}, mixin(options, opts, true, customMixin));
|
||||
}
|
||||
|
||||
if (config.xAxisMin) {
|
||||
const opts = {
|
||||
const opts: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
x: {
|
||||
display: true,
|
||||
ticks: {
|
||||
min: config.xAxisMin
|
||||
}
|
||||
}]
|
||||
min: config.xAxisMin
|
||||
}
|
||||
}
|
||||
};
|
||||
options = mixin({}, mixin(options, opts, true, customMixin));
|
||||
}
|
||||
|
||||
if (config.xAxisLabel) {
|
||||
const opts = {
|
||||
const opts: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
x: {
|
||||
display: true,
|
||||
scaleLabel: {
|
||||
title: {
|
||||
display: true,
|
||||
labelString: config.xAxisLabel
|
||||
text: config.xAxisLabel
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
options = mixin({}, mixin(options, opts, true, customMixin));
|
||||
}
|
||||
|
||||
if (config.yAxisMax) {
|
||||
const opts = {
|
||||
const opts: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
y: {
|
||||
display: true,
|
||||
ticks: {
|
||||
max: config.yAxisMax
|
||||
}
|
||||
}]
|
||||
max: config.yAxisMax
|
||||
}
|
||||
}
|
||||
};
|
||||
options = mixin({}, mixin(options, opts, true, customMixin));
|
||||
}
|
||||
|
||||
if (config.yAxisMin) {
|
||||
const opts = {
|
||||
const opts: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
y: {
|
||||
display: true,
|
||||
ticks: {
|
||||
min: config.yAxisMin
|
||||
}
|
||||
}]
|
||||
min: config.yAxisMin
|
||||
}
|
||||
}
|
||||
};
|
||||
options = mixin({}, mixin(options, opts, true, customMixin));
|
||||
}
|
||||
|
||||
if (config.yAxisLabel) {
|
||||
const opts = {
|
||||
const opts: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
yAxes: [{
|
||||
y: {
|
||||
display: true,
|
||||
scaleLabel: {
|
||||
title: {
|
||||
display: true,
|
||||
labelString: config.yAxisLabel
|
||||
text: config.yAxisLabel
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
options = mixin({}, mixin(options, opts, true, customMixin));
|
||||
@@ -133,30 +126,30 @@ export default class BarChart extends ChartInsight {
|
||||
const foreground = foregroundColor ? foregroundColor.toString() : null;
|
||||
const gridLinesColor = e.getColor(editorLineNumbers);
|
||||
const gridLines = gridLinesColor ? gridLinesColor.toString() : null;
|
||||
const options = {
|
||||
const options: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
scaleLabel: {
|
||||
fontColor: foreground
|
||||
x: {
|
||||
title: {
|
||||
color: foreground
|
||||
},
|
||||
ticks: {
|
||||
fontColor: foreground
|
||||
color: foreground
|
||||
},
|
||||
gridLines: {
|
||||
grid: {
|
||||
color: gridLines
|
||||
}
|
||||
}],
|
||||
yAxes: [{
|
||||
scaleLabel: {
|
||||
fontColor: foreground
|
||||
},
|
||||
y: {
|
||||
title: {
|
||||
color: foreground
|
||||
},
|
||||
ticks: {
|
||||
fontColor: foreground
|
||||
color: foreground
|
||||
},
|
||||
gridLines: {
|
||||
grid: {
|
||||
color: gridLines
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import BarChart from './barChart.component';
|
||||
import BarChart, { IBarChartConfig } from './barChart.component';
|
||||
import { forwardRef, Inject, ChangeDetectorRef } from '@angular/core';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
import { ChartType } from 'sql/workbench/contrib/charts/common/interfaces';
|
||||
import * as chartjs from 'chart.js';
|
||||
import { mixin } from 'sql/base/common/objects';
|
||||
import { customMixin } from 'sql/workbench/contrib/charts/browser/interfaces';
|
||||
|
||||
export default class HorizontalBarChart extends BarChart {
|
||||
protected override readonly chartType: ChartType = ChartType.HorizontalBar;
|
||||
protected override readonly chartType: ChartType = ChartType.Bar;
|
||||
|
||||
constructor(
|
||||
@Inject(forwardRef(() => ChangeDetectorRef)) _changeRef: ChangeDetectorRef,
|
||||
@@ -19,4 +22,12 @@ export default class HorizontalBarChart extends BarChart {
|
||||
) {
|
||||
super(_changeRef, themeService, telemetryService);
|
||||
}
|
||||
|
||||
public override setConfig(config: IBarChartConfig): void {
|
||||
let options: chartjs.ChartOptions = {
|
||||
indexAxis: 'y'
|
||||
};
|
||||
this.options = mixin({}, mixin(this.options, options, true, customMixin));
|
||||
super.setConfig(config);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { mixin, deepClone } from 'vs/base/common/objects';
|
||||
import * as chartjs from 'chart.js';
|
||||
|
||||
import BarChart, { IBarChartConfig } from './barChart.component';
|
||||
import { defaultChartConfig, IDataSet } from 'sql/workbench/contrib/dashboard/browser/widgets/insights/views/charts/interfaces';
|
||||
import { defaultChartConfig } from 'sql/workbench/contrib/dashboard/browser/widgets/insights/views/charts/interfaces';
|
||||
import { ChangeDetectorRef, Inject, forwardRef } from '@angular/core';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IPointDataSet } from 'sql/workbench/contrib/charts/browser/interfaces';
|
||||
import { DataType, ChartType } from 'sql/workbench/contrib/charts/common/interfaces';
|
||||
import { values } from 'vs/base/common/collections';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
@@ -40,7 +40,7 @@ export default class LineChart extends BarChart {
|
||||
super.init();
|
||||
}
|
||||
|
||||
public override get chartData(): Array<IDataSet | IPointDataSet> {
|
||||
public override get chartData(): chartjs.ChartDataset[] {
|
||||
if (this._config.dataType === DataType.Number) {
|
||||
return super.getChartData();
|
||||
} else {
|
||||
@@ -53,10 +53,10 @@ export default class LineChart extends BarChart {
|
||||
this._cachedPointData = undefined;
|
||||
}
|
||||
|
||||
private _cachedPointData: Array<IPointDataSet>;
|
||||
protected getDataAsPoint(): Array<IPointDataSet> {
|
||||
private _cachedPointData: chartjs.ChartDataset[];
|
||||
protected getDataAsPoint(): chartjs.ChartDataset[] {
|
||||
if (!this._cachedPointData) {
|
||||
const dataSetMap: { [label: string]: IPointDataSet } = {};
|
||||
const dataSetMap: { [label: string]: chartjs.ChartDataset } = {};
|
||||
this._data.rows.map(row => {
|
||||
if (row && row.length >= 3) {
|
||||
const legend = row[0];
|
||||
@@ -82,25 +82,24 @@ export default class LineChart extends BarChart {
|
||||
protected addAxisLabels(): void {
|
||||
const xLabel = this._config.xAxisLabel || this._data.columns[1] || 'x';
|
||||
const yLabel = this._config.yAxisLabel || this._data.columns[2] || 'y';
|
||||
const options = {
|
||||
const options: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
x: {
|
||||
type: 'linear',
|
||||
position: 'bottom',
|
||||
display: true,
|
||||
scaleLabel: {
|
||||
title: {
|
||||
display: true,
|
||||
labelString: xLabel
|
||||
text: xLabel
|
||||
}
|
||||
}],
|
||||
|
||||
yAxes: [{
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
scaleLabel: {
|
||||
title: {
|
||||
display: true,
|
||||
labelString: yLabel,
|
||||
text: yLabel
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
|
||||
import LineChart, { ILineConfig } from './lineChart.component';
|
||||
import { defaultChartConfig } from 'sql/workbench/contrib/dashboard/browser/widgets/insights/views/charts/interfaces';
|
||||
import * as chartjs from 'chart.js';
|
||||
|
||||
import { mixin, deepClone } from 'vs/base/common/objects';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { ChangeDetectorRef, Inject, forwardRef } from '@angular/core';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IPointDataSet } from 'sql/workbench/contrib/charts/browser/interfaces';
|
||||
import { ChartType } from 'sql/workbench/contrib/charts/common/interfaces';
|
||||
import { values } from 'vs/base/common/collections';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry';
|
||||
@@ -32,42 +32,41 @@ export default class TimeSeriesChart extends LineChart {
|
||||
const xLabel = this._config.xAxisLabel || this.getLabels()[1] || 'x';
|
||||
const yLabel = this._config.yAxisLabel || this.getLabels()[2] || 'y';
|
||||
|
||||
const options = {
|
||||
const options: chartjs.ChartOptions = {
|
||||
scales: {
|
||||
xAxes: [{
|
||||
x: {
|
||||
type: 'time',
|
||||
display: true,
|
||||
scaleLabel: {
|
||||
title: {
|
||||
display: true,
|
||||
labelString: xLabel
|
||||
text: xLabel
|
||||
},
|
||||
ticks: {
|
||||
autoSkip: false,
|
||||
maxRotation: 45,
|
||||
minRotation: 45
|
||||
}
|
||||
}],
|
||||
|
||||
yAxes: [{
|
||||
},
|
||||
y: {
|
||||
display: true,
|
||||
scaleLabel: {
|
||||
title: {
|
||||
display: true,
|
||||
labelString: yLabel
|
||||
text: yLabel
|
||||
}
|
||||
}]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.options = Object.assign({}, mixin(this.options, options));
|
||||
}
|
||||
|
||||
protected override getDataAsPoint(): Array<IPointDataSet> {
|
||||
const dataSetMap: { [label: string]: IPointDataSet } = {};
|
||||
protected override getDataAsPoint(): chartjs.ChartDataset[] {
|
||||
const dataSetMap: { [label: string]: chartjs.ChartDataset<'line', any[]> } = {};
|
||||
this._data.rows.map(row => {
|
||||
if (row && row.length >= 3) {
|
||||
const legend = row[0];
|
||||
if (!dataSetMap[legend]) {
|
||||
dataSetMap[legend] = { label: legend, data: [], fill: false };
|
||||
dataSetMap[legend] = { label: legend, data: [] };
|
||||
}
|
||||
dataSetMap[legend].data.push({ x: row[1], y: Number(row[2]) });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user