mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-17 02:51:36 -05:00
Save charting state in SQL notebooks. (#9789)
This commit is contained in:
3
src/sql/azdata.d.ts
vendored
3
src/sql/azdata.d.ts
vendored
@@ -4678,6 +4678,9 @@ declare module 'azdata' {
|
|||||||
|
|
||||||
export interface ICellOutput {
|
export interface ICellOutput {
|
||||||
output_type: OutputTypeName;
|
output_type: OutputTypeName;
|
||||||
|
metadata?: {
|
||||||
|
azdata_chartOptions?: any;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -663,6 +663,7 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
|
|||||||
return NotebookChangeKind.ContentUpdated;
|
return NotebookChangeKind.ContentUpdated;
|
||||||
case NotebookChangeType.KernelChanged:
|
case NotebookChangeType.KernelChanged:
|
||||||
case NotebookChangeType.TrustChanged:
|
case NotebookChangeType.TrustChanged:
|
||||||
|
case NotebookChangeType.CellMetadataUpdated:
|
||||||
return NotebookChangeKind.MetadataUpdated;
|
return NotebookChangeKind.MetadataUpdated;
|
||||||
case NotebookChangeType.Saved:
|
case NotebookChangeType.Saved:
|
||||||
return NotebookChangeKind.Save;
|
return NotebookChangeKind.Save;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import * as nls from 'vs/nls';
|
|||||||
import { find } from 'vs/base/common/arrays';
|
import { find } from 'vs/base/common/arrays';
|
||||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||||
import { DbCellValue } from 'azdata';
|
import { DbCellValue } from 'azdata';
|
||||||
|
import { Event, Emitter } from 'vs/base/common/event';
|
||||||
|
|
||||||
const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution);
|
const insightRegistry = Registry.as<IInsightRegistry>(Extensions.InsightContribution);
|
||||||
|
|
||||||
@@ -61,11 +62,10 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
|
|
||||||
private _state: ChartState;
|
private _state: ChartState;
|
||||||
|
|
||||||
private options: IInsightOptions = {
|
private _options: IInsightOptions = {
|
||||||
type: ChartType.Bar
|
type: ChartType.Bar
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/** parent container */
|
/** parent container */
|
||||||
private container: HTMLElement;
|
private container: HTMLElement;
|
||||||
/** container for the options controls */
|
/** container for the options controls */
|
||||||
@@ -82,6 +82,9 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
private optionDisposables: IDisposable[] = [];
|
private optionDisposables: IDisposable[] = [];
|
||||||
private optionMap: { [x: string]: { element: HTMLElement; set: (val) => void } } = {};
|
private optionMap: { [x: string]: { element: HTMLElement; set: (val) => void } } = {};
|
||||||
|
|
||||||
|
private readonly _onOptionsChange: Emitter<IInsightOptions> = this._register(new Emitter<IInsightOptions>());
|
||||||
|
public readonly onOptionsChange: Event<IInsightOptions> = this._onOptionsChange.event;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly _renderOptionsInline: boolean,
|
private readonly _renderOptionsInline: boolean,
|
||||||
@IContextViewService private _contextViewService: IContextViewService,
|
@IContextViewService private _contextViewService: IContextViewService,
|
||||||
@@ -111,7 +114,7 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
this.options = new Proxy(this.options, {
|
this._options = new Proxy(this._options, {
|
||||||
get: function (target, key) {
|
get: function (target, key) {
|
||||||
return target[key];
|
return target[key];
|
||||||
},
|
},
|
||||||
@@ -128,12 +131,13 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (change) {
|
if (change) {
|
||||||
self.taskbar.context = <IChartActionContext>{ options: self.options, insight: self.insight ? self.insight.insight : undefined };
|
self.taskbar.context = <IChartActionContext>{ options: self._options, insight: self.insight ? self.insight.insight : undefined };
|
||||||
if (key === 'type') {
|
if (key === 'type') {
|
||||||
self.buildOptions();
|
self.buildOptions();
|
||||||
} else {
|
} else {
|
||||||
self.verifyOptions();
|
self.verifyOptions();
|
||||||
}
|
}
|
||||||
|
self._onOptionsChange.fire(self._options);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -176,7 +180,7 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
if (this._renderOptionsInline) {
|
if (this._renderOptionsInline) {
|
||||||
this.chartingContainer.appendChild(this.optionsControl);
|
this.chartingContainer.appendChild(this.optionsControl);
|
||||||
}
|
}
|
||||||
this.insight = new Insight(this.insightContainer, this.options, this._instantiationService);
|
this.insight = new Insight(this.insightContainer, this._options, this._instantiationService);
|
||||||
}
|
}
|
||||||
|
|
||||||
container.appendChild(this.container);
|
container.appendChild(this.container);
|
||||||
@@ -259,11 +263,11 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
DOM.clearNode(this.typeControls);
|
DOM.clearNode(this.typeControls);
|
||||||
|
|
||||||
this.updateActionbar();
|
this.updateActionbar();
|
||||||
ChartOptions[this.options.type].map(o => {
|
this.getChartTypeOptions().map(o => {
|
||||||
this.createOption(o, this.typeControls);
|
this.createOption(o, this.typeControls);
|
||||||
});
|
});
|
||||||
if (this.insight) {
|
if (this.insight) {
|
||||||
this.insight.options = this.options;
|
this.insight.options = this._options;
|
||||||
}
|
}
|
||||||
this.verifyOptions();
|
this.verifyOptions();
|
||||||
}
|
}
|
||||||
@@ -272,9 +276,9 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
this.updateActionbar();
|
this.updateActionbar();
|
||||||
for (let key in this.optionMap) {
|
for (let key in this.optionMap) {
|
||||||
if (this.optionMap.hasOwnProperty(key)) {
|
if (this.optionMap.hasOwnProperty(key)) {
|
||||||
let option = find(ChartOptions[this.options.type], e => e.configEntry === key);
|
let option = find(this.getChartTypeOptions(), e => e.configEntry === key);
|
||||||
if (option && option.if) {
|
if (option && option.if) {
|
||||||
if (option.if(this.options)) {
|
if (option.if(this._options)) {
|
||||||
DOM.show(this.optionMap[key].element);
|
DOM.show(this.optionMap[key].element);
|
||||||
} else {
|
} else {
|
||||||
DOM.hide(this.optionMap[key].element);
|
DOM.hide(this.optionMap[key].element);
|
||||||
@@ -284,10 +288,18 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getChartTypeOptions(): IChartOption[] {
|
||||||
|
let options = ChartOptions[this._options.type];
|
||||||
|
if (!options) {
|
||||||
|
throw new Error(nls.localize('charting.unsupportedType', "Chart type '{0}' is not supported.", this._options.type));
|
||||||
|
}
|
||||||
|
return options;
|
||||||
|
}
|
||||||
|
|
||||||
private updateActionbar() {
|
private updateActionbar() {
|
||||||
let actions: ITaskbarContent[];
|
let actions: ITaskbarContent[];
|
||||||
if (this.insight && this.insight.isCopyable) {
|
if (this.insight && this.insight.isCopyable) {
|
||||||
this.taskbar.context = { insight: this.insight.insight, options: this.options };
|
this.taskbar.context = { insight: this.insight.insight, options: this._options };
|
||||||
actions = [
|
actions = [
|
||||||
{ action: this._createInsightAction },
|
{ action: this._createInsightAction },
|
||||||
{ action: this._copyAction },
|
{ action: this._copyAction },
|
||||||
@@ -318,10 +330,10 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
ariaLabel: option.label,
|
ariaLabel: option.label,
|
||||||
checked: value,
|
checked: value,
|
||||||
onChange: () => {
|
onChange: () => {
|
||||||
if (this.options[option.configEntry] !== checkbox.checked) {
|
if (this._options[option.configEntry] !== checkbox.checked) {
|
||||||
this.options[option.configEntry] = checkbox.checked;
|
this._options[option.configEntry] = checkbox.checked;
|
||||||
if (this.insight) {
|
if (this.insight) {
|
||||||
this.insight.options = this.options;
|
this.insight.options = this._options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,10 +349,10 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
dropdown.select(option.options.indexOf(value));
|
dropdown.select(option.options.indexOf(value));
|
||||||
dropdown.render(optionInput);
|
dropdown.render(optionInput);
|
||||||
dropdown.onDidSelect(e => {
|
dropdown.onDidSelect(e => {
|
||||||
if (this.options[option.configEntry] !== option.options[e.index]) {
|
if (this._options[option.configEntry] !== option.options[e.index]) {
|
||||||
this.options[option.configEntry] = option.options[e.index];
|
this._options[option.configEntry] = option.options[e.index];
|
||||||
if (this.insight) {
|
if (this.insight) {
|
||||||
this.insight.options = this.options;
|
this.insight.options = this._options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -356,10 +368,10 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
input.setAriaLabel(option.label);
|
input.setAriaLabel(option.label);
|
||||||
input.value = value || '';
|
input.value = value || '';
|
||||||
input.onDidChange(e => {
|
input.onDidChange(e => {
|
||||||
if (this.options[option.configEntry] !== e) {
|
if (this._options[option.configEntry] !== e) {
|
||||||
this.options[option.configEntry] = e;
|
this._options[option.configEntry] = e;
|
||||||
if (this.insight) {
|
if (this.insight) {
|
||||||
this.insight.options = this.options;
|
this.insight.options = this._options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -375,10 +387,10 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
numberInput.setAriaLabel(option.label);
|
numberInput.setAriaLabel(option.label);
|
||||||
numberInput.value = value || '';
|
numberInput.value = value || '';
|
||||||
numberInput.onDidChange(e => {
|
numberInput.onDidChange(e => {
|
||||||
if (this.options[option.configEntry] !== Number(e)) {
|
if (this._options[option.configEntry] !== Number(e)) {
|
||||||
this.options[option.configEntry] = Number(e);
|
this._options[option.configEntry] = Number(e);
|
||||||
if (this.insight) {
|
if (this.insight) {
|
||||||
this.insight.options = this.options;
|
this.insight.options = this._options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -394,10 +406,10 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
dateInput.setAriaLabel(option.label);
|
dateInput.setAriaLabel(option.label);
|
||||||
dateInput.value = value || '';
|
dateInput.value = value || '';
|
||||||
dateInput.onDidChange(e => {
|
dateInput.onDidChange(e => {
|
||||||
if (this.options[option.configEntry] !== e) {
|
if (this._options[option.configEntry] !== e) {
|
||||||
this.options[option.configEntry] = e;
|
this._options[option.configEntry] = e;
|
||||||
if (this.insight) {
|
if (this.insight) {
|
||||||
this.insight.options = this.options;
|
this.insight.options = this._options;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -411,25 +423,33 @@ export class ChartView extends Disposable implements IPanelView {
|
|||||||
}
|
}
|
||||||
this.optionMap[option.configEntry] = { element: optionContainer, set: setFunc };
|
this.optionMap[option.configEntry] = { element: optionContainer, set: setFunc };
|
||||||
container.appendChild(optionContainer);
|
container.appendChild(optionContainer);
|
||||||
this.options[option.configEntry] = value;
|
this._options[option.configEntry] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public set state(val: ChartState) {
|
public set state(val: ChartState) {
|
||||||
this._state = val;
|
this._state = val;
|
||||||
if (this.state.options) {
|
this.options = this._state.options;
|
||||||
for (let key in this.state.options) {
|
if (this._state.dataId) {
|
||||||
if (this.state.options.hasOwnProperty(key) && this.optionMap[key]) {
|
this.chart(this._state.dataId);
|
||||||
this.options[key] = this.state.options[key];
|
|
||||||
this.optionMap[key].set(this.state.options[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.state.dataId) {
|
|
||||||
this.chart(this.state.dataId);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public get state(): ChartState {
|
public get state(): ChartState {
|
||||||
return this._state;
|
return this._state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get options(): IInsightOptions {
|
||||||
|
return this._options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set options(newOptions: IInsightOptions) {
|
||||||
|
if (newOptions) {
|
||||||
|
for (let key in newOptions) {
|
||||||
|
if (newOptions.hasOwnProperty(key) && this.optionMap[key]) {
|
||||||
|
this._options[key] = newOptions[key];
|
||||||
|
this.optionMap[key].set(newOptions[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ export class OutputComponent extends CellView implements OnInit, AfterViewInit {
|
|||||||
this._componentInstance = componentRef.instance;
|
this._componentInstance = componentRef.instance;
|
||||||
this._componentInstance.mimeType = mimeType;
|
this._componentInstance.mimeType = mimeType;
|
||||||
this._componentInstance.cellModel = this.cellModel;
|
this._componentInstance.cellModel = this.cellModel;
|
||||||
|
this._componentInstance.cellOutput = this.cellOutput;
|
||||||
this._componentInstance.bundleOptions = options;
|
this._componentInstance.bundleOptions = options;
|
||||||
this._changeref.detectChanges();
|
this._changeref.detectChanges();
|
||||||
let el = <HTMLElement>componentRef.location.nativeElement;
|
let el = <HTMLElement>componentRef.location.nativeElement;
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/commo
|
|||||||
import { ChartView } from 'sql/workbench/contrib/charts/browser/chartView';
|
import { ChartView } from 'sql/workbench/contrib/charts/browser/chartView';
|
||||||
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
import { Orientation } from 'vs/base/browser/ui/splitview/splitview';
|
||||||
import { ToggleableAction } from 'sql/workbench/contrib/notebook/browser/notebookActions';
|
import { ToggleableAction } from 'sql/workbench/contrib/notebook/browser/notebookActions';
|
||||||
|
import { IInsightOptions } from 'sql/workbench/common/editor/query/chartState';
|
||||||
|
import { NotebookChangeType } from 'sql/workbench/services/notebook/common/contracts';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: GridOutputComponent.SELECTOR,
|
selector: GridOutputComponent.SELECTOR,
|
||||||
@@ -49,6 +51,7 @@ export class GridOutputComponent extends AngularDisposable implements IMimeCompo
|
|||||||
|
|
||||||
private _initialized: boolean = false;
|
private _initialized: boolean = false;
|
||||||
private _cellModel: ICellModel;
|
private _cellModel: ICellModel;
|
||||||
|
private _cellOutput: azdata.nb.ICellOutput;
|
||||||
private _bundleOptions: MimeModel.IOptions;
|
private _bundleOptions: MimeModel.IOptions;
|
||||||
private _table: DataResourceTable;
|
private _table: DataResourceTable;
|
||||||
|
|
||||||
@@ -79,6 +82,14 @@ export class GridOutputComponent extends AngularDisposable implements IMimeCompo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get cellOutput(): azdata.nb.ICellOutput {
|
||||||
|
return this._cellOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input() set cellOutput(value: azdata.nb.ICellOutput) {
|
||||||
|
this._cellOutput = value;
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.renderGrid();
|
this.renderGrid();
|
||||||
}
|
}
|
||||||
@@ -90,7 +101,7 @@ export class GridOutputComponent extends AngularDisposable implements IMimeCompo
|
|||||||
if (!this._table) {
|
if (!this._table) {
|
||||||
let source = <IDataResource><any>this._bundleOptions.data[this.mimeType];
|
let source = <IDataResource><any>this._bundleOptions.data[this.mimeType];
|
||||||
let state = new GridTableState(0, 0);
|
let state = new GridTableState(0, 0);
|
||||||
this._table = this.instantiationService.createInstance(DataResourceTable, source, this.cellModel.notebookModel.notebookUri.toString(), state);
|
this._table = this.instantiationService.createInstance(DataResourceTable, source, this.cellModel, this.cellOutput, state);
|
||||||
let outputElement = <HTMLElement>this.output.nativeElement;
|
let outputElement = <HTMLElement>this.output.nativeElement;
|
||||||
outputElement.appendChild(this._table.element);
|
outputElement.appendChild(this._table.element);
|
||||||
this._register(attachTableStyler(this._table, this.themeService));
|
this._register(attachTableStyler(this._table, this.themeService));
|
||||||
@@ -116,7 +127,8 @@ class DataResourceTable extends GridTableBase<any> {
|
|||||||
private _chartContainer: HTMLElement;
|
private _chartContainer: HTMLElement;
|
||||||
|
|
||||||
constructor(source: IDataResource,
|
constructor(source: IDataResource,
|
||||||
public readonly documentUri: string,
|
private cellModel: ICellModel,
|
||||||
|
private cellOutput: azdata.nb.ICellOutput,
|
||||||
state: GridTableState,
|
state: GridTableState,
|
||||||
@IContextMenuService contextMenuService: IContextMenuService,
|
@IContextMenuService contextMenuService: IContextMenuService,
|
||||||
@IInstantiationService protected instantiationService: IInstantiationService,
|
@IInstantiationService protected instantiationService: IInstantiationService,
|
||||||
@@ -125,14 +137,28 @@ class DataResourceTable extends GridTableBase<any> {
|
|||||||
@IConfigurationService configurationService: IConfigurationService
|
@IConfigurationService configurationService: IConfigurationService
|
||||||
) {
|
) {
|
||||||
super(state, createResultSet(source), contextMenuService, instantiationService, editorService, untitledEditorService, configurationService);
|
super(state, createResultSet(source), contextMenuService, instantiationService, editorService, untitledEditorService, configurationService);
|
||||||
this._gridDataProvider = this.instantiationService.createInstance(DataResourceDataProvider, source, this.resultSet, this.documentUri);
|
this._gridDataProvider = this.instantiationService.createInstance(DataResourceDataProvider, source, this.resultSet, this.cellModel.notebookModel.notebookUri.toString());
|
||||||
this._chart = this.instantiationService.createInstance(ChartView, false);
|
this._chart = this.instantiationService.createInstance(ChartView, false);
|
||||||
|
|
||||||
|
if (!this.cellOutput.metadata) {
|
||||||
|
this.cellOutput.metadata = {};
|
||||||
|
} else if (this.cellOutput.metadata.azdata_chartOptions) {
|
||||||
|
this._chart.options = this.cellOutput.metadata.azdata_chartOptions as IInsightOptions;
|
||||||
|
this.updateChartData(this.resultSet.rowCount, this.resultSet.columnInfo.length, this.gridDataProvider);
|
||||||
|
}
|
||||||
|
this._chart.onOptionsChange(options => {
|
||||||
|
this.setChartOptions(options);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get gridDataProvider(): IGridDataProvider {
|
public get gridDataProvider(): IGridDataProvider {
|
||||||
return this._gridDataProvider;
|
return this._gridDataProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public get chartDisplayed(): boolean {
|
||||||
|
return this.cellOutput.metadata.azdata_chartOptions !== undefined;
|
||||||
|
}
|
||||||
|
|
||||||
protected getCurrentActions(): IAction[] {
|
protected getCurrentActions(): IAction[] {
|
||||||
return this.getContextActions();
|
return this.getContextActions();
|
||||||
}
|
}
|
||||||
@@ -158,9 +184,15 @@ class DataResourceTable extends GridTableBase<any> {
|
|||||||
|
|
||||||
if (!this._chartContainer) {
|
if (!this._chartContainer) {
|
||||||
this._chartContainer = document.createElement('div');
|
this._chartContainer = document.createElement('div');
|
||||||
this._chartContainer.style.display = 'none';
|
|
||||||
this._chartContainer.style.width = '100%';
|
this._chartContainer.style.width = '100%';
|
||||||
|
|
||||||
|
if (this.cellOutput.metadata.azdata_chartOptions) {
|
||||||
|
this.tableContainer.style.display = 'none';
|
||||||
|
this._chartContainer.style.display = 'inline-block';
|
||||||
|
} else {
|
||||||
|
this._chartContainer.style.display = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
this.element.appendChild(this._chartContainer);
|
this.element.appendChild(this._chartContainer);
|
||||||
this._chart.render(this._chartContainer);
|
this._chart.render(this._chartContainer);
|
||||||
}
|
}
|
||||||
@@ -170,14 +202,26 @@ class DataResourceTable extends GridTableBase<any> {
|
|||||||
if (this.tableContainer.style.display !== 'none') {
|
if (this.tableContainer.style.display !== 'none') {
|
||||||
this.tableContainer.style.display = 'none';
|
this.tableContainer.style.display = 'none';
|
||||||
this._chartContainer.style.display = 'inline-block';
|
this._chartContainer.style.display = 'inline-block';
|
||||||
|
this.setChartOptions(this._chart.options);
|
||||||
} else {
|
} else {
|
||||||
this.tableContainer.style.display = 'inline-block';
|
|
||||||
this._chartContainer.style.display = 'none';
|
this._chartContainer.style.display = 'none';
|
||||||
|
this.tableContainer.style.display = 'inline-block';
|
||||||
|
this.setChartOptions(undefined);
|
||||||
}
|
}
|
||||||
|
this.layout();
|
||||||
}
|
}
|
||||||
|
|
||||||
public get chart(): ChartView {
|
public updateChartData(rowCount: number, columnCount: number, gridDataProvider: IGridDataProvider): void {
|
||||||
return this._chart;
|
gridDataProvider.getRowData(0, rowCount).then(result => {
|
||||||
|
let range = new Slick.Range(0, 0, rowCount - 1, columnCount - 1);
|
||||||
|
let columns = gridDataProvider.getColumnHeaders(range);
|
||||||
|
this._chart.setData(result.resultSubset.rows, columns);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private setChartOptions(options: IInsightOptions | undefined) {
|
||||||
|
this.cellOutput.metadata.azdata_chartOptions = options;
|
||||||
|
this.cellModel.sendChangeToNotebook(NotebookChangeType.CellMetadataUpdated);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -398,7 +442,7 @@ export class NotebookChartAction extends ToggleableAction {
|
|||||||
toggleOnClass: NotebookChartAction.SHOWTABLE_ICON,
|
toggleOnClass: NotebookChartAction.SHOWTABLE_ICON,
|
||||||
toggleOffLabel: NotebookChartAction.SHOWCHART_LABEL,
|
toggleOffLabel: NotebookChartAction.SHOWCHART_LABEL,
|
||||||
toggleOffClass: NotebookChartAction.SHOWCHART_ICON,
|
toggleOffClass: NotebookChartAction.SHOWCHART_ICON,
|
||||||
isOn: false
|
isOn: resourceTable.chartDisplayed
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,12 +451,8 @@ export class NotebookChartAction extends ToggleableAction {
|
|||||||
this.toggle(!this.state.isOn);
|
this.toggle(!this.state.isOn);
|
||||||
if (this.state.isOn) {
|
if (this.state.isOn) {
|
||||||
let rowCount = context.table.getData().getLength();
|
let rowCount = context.table.getData().getLength();
|
||||||
let range = new Slick.Range(0, 0, rowCount - 1, context.table.columns.length - 1);
|
let columnCount = context.table.columns.length;
|
||||||
let columns = context.gridDataProvider.getColumnHeaders(range);
|
this.resourceTable.updateChartData(rowCount, columnCount, context.gridDataProvider);
|
||||||
|
|
||||||
context.gridDataProvider.getRowData(0, rowCount).then(result => {
|
|
||||||
this.resourceTable.chart.setData(result.resultSubset.rows, columns);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { MimeModel } from 'sql/workbench/services/notebook/browser/outputs/mimem
|
|||||||
import * as types from 'vs/base/common/types';
|
import * as types from 'vs/base/common/types';
|
||||||
import { ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
|
import { ICellModel } from 'sql/workbench/services/notebook/browser/models/modelInterfaces';
|
||||||
import { values } from 'vs/base/common/collections';
|
import { values } from 'vs/base/common/collections';
|
||||||
|
import { nb } from 'azdata';
|
||||||
|
|
||||||
export type FactoryIdentifier = string;
|
export type FactoryIdentifier = string;
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ export interface IMimeComponent {
|
|||||||
bundleOptions: MimeModel.IOptions;
|
bundleOptions: MimeModel.IOptions;
|
||||||
mimeType: string;
|
mimeType: string;
|
||||||
cellModel?: ICellModel;
|
cellModel?: ICellModel;
|
||||||
|
cellOutput?: nb.ICellOutput;
|
||||||
layout(): void;
|
layout(): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ export class CellModel implements ICellModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private sendChangeToNotebook(change: NotebookChangeType): void {
|
public sendChangeToNotebook(change: NotebookChangeType): void {
|
||||||
if (this._options && this._options.notebook) {
|
if (this._options && this._options.notebook) {
|
||||||
this._options.notebook.onCellChange(this, change);
|
this._options.notebook.onCellChange(this, change);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -487,6 +487,7 @@ export interface ICellModel {
|
|||||||
readonly onCellModeChanged: Event<boolean>;
|
readonly onCellModeChanged: Event<boolean>;
|
||||||
modelContentChangedEvent: IModelContentChangedEvent;
|
modelContentChangedEvent: IModelContentChangedEvent;
|
||||||
isEditMode: boolean;
|
isEditMode: boolean;
|
||||||
|
sendChangeToNotebook(change: NotebookChangeType): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IModelFactory {
|
export interface IModelFactory {
|
||||||
|
|||||||
@@ -989,6 +989,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
|
|||||||
case NotebookChangeType.CellOutputUpdated:
|
case NotebookChangeType.CellOutputUpdated:
|
||||||
case NotebookChangeType.CellSourceUpdated:
|
case NotebookChangeType.CellSourceUpdated:
|
||||||
case NotebookChangeType.CellInputVisibilityChanged:
|
case NotebookChangeType.CellInputVisibilityChanged:
|
||||||
|
case NotebookChangeType.CellMetadataUpdated:
|
||||||
changeInfo.isDirty = true;
|
changeInfo.isDirty = true;
|
||||||
changeInfo.modelContentChangedEvent = cell.modelContentChangedEvent;
|
changeInfo.modelContentChangedEvent = cell.modelContentChangedEvent;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -45,5 +45,6 @@ export enum NotebookChangeType {
|
|||||||
Saved,
|
Saved,
|
||||||
CellExecuted,
|
CellExecuted,
|
||||||
CellInputVisibilityChanged,
|
CellInputVisibilityChanged,
|
||||||
CellOutputCleared
|
CellOutputCleared,
|
||||||
|
CellMetadataUpdated
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user