Skip to content

Commit e28a293

Browse files
authored
Merge pull request #483 from KxSystems/ee-plot
gg plot first phase
2 parents 3a96804 + 16684d9 commit e28a293

File tree

18 files changed

+553
-153
lines changed

18 files changed

+553
-153
lines changed

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,19 @@
546546
"dark": "./resources/dark/datasource.svg",
547547
"light": "./resources/light/datasource.svg"
548548
}
549+
},
550+
{
551+
"id": "kdbplot",
552+
"aliases": [
553+
"kdbplot"
554+
],
555+
"extensions": [
556+
".plot"
557+
],
558+
"icon": {
559+
"dark": "./resources/dark/plot.svg",
560+
"light": "./resources/light/plot.svg"
561+
}
549562
}
550563
],
551564
"grammars": [
@@ -935,6 +948,16 @@
935948
}
936949
],
937950
"priority": "default"
951+
},
952+
{
953+
"viewType": "kdb.chartEditor",
954+
"displayName": "Chart Viewer",
955+
"selector": [
956+
{
957+
"filenamePattern": "*.plot"
958+
}
959+
],
960+
"priority": "default"
938961
}
939962
]
940963
},

resources/dark/plot.svg

Lines changed: 8 additions & 0 deletions
Loading

resources/evaluate.q

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -117,15 +117,21 @@
117117
(`result; ::);
118118
(`errored; 1b);
119119
(`error; err);
120-
(`backtrace; .Q.sbt userCode))
120+
(`backtrace; .Q.sbt userCode);
121+
(`base64; 0b))
121122
}[suffix; prefix]];
122123
if [isLastLine or result`errored;
123124
system "d ", cachedCtx;
124125
: result];
125126
index +: 1];
126127
};
127-
result: evalInContext[ctx; splitExpression stripTrailingSemi wrapLines removeMultilineComments code];
128-
if [(not result `errored) and stringify;
129-
result[`result]: toString result `result];
128+
result: evalInContext[ctx; splitExpression stripTrailingSemi wrapLines removeMultilineComments code];
129+
if[result `errored; :result];
130+
if[type[result[`result]] = 99h;
131+
if[`output in key result[`result];
132+
if[type[result[`result][`output]] = 99h;
133+
if[`bytes in key result[`result][`output];
134+
result[`base64]:1b; result[`result]: .Q.btoa result[`result][`output][`bytes]; :result]]]];
135+
if [stringify; result[`result]: toString result `result];
130136
result
131137
}

resources/light/plot.svg

Lines changed: 8 additions & 0 deletions
Loading

src/classes/localConnection.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ export class LocalConnection {
175175
isPython?: boolean,
176176
): Promise<any> {
177177
let result;
178+
let base64 = false;
178179
await this.waitForConnection();
179180

180181
if (!this.connection) {
@@ -202,6 +203,7 @@ export class LocalConnection {
202203
);
203204
} else {
204205
result = res.result === null ? "" : res.result;
206+
base64 = res.base64 || false;
205207
}
206208
});
207209

@@ -213,6 +215,10 @@ export class LocalConnection {
213215

214216
this.updateGlobal();
215217

218+
if (base64) {
219+
return { base64, result };
220+
}
221+
216222
if (ext.isResultsTabVisible && stringify) {
217223
if (this.isError) {
218224
this.isError = false;

src/commands/serverCommand.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ import {
8080
ServerType,
8181
} from "../models/connectionsModels";
8282
import * as fs from "fs";
83+
import { ChartEditorProvider } from "../services/chartEditorProvider";
84+
import {
85+
addWorkspaceFile,
86+
openWith,
87+
setUriContent,
88+
workspaceHas,
89+
} from "../utils/workspace";
90+
import { Plot } from "../models/plot";
8391

8492
export async function addNewConnection(): Promise<void> {
8593
NewConnectionPannel.close();
@@ -848,7 +856,25 @@ export async function executeQuery(
848856
);
849857
} else {
850858
/* istanbul ignore next */
851-
if (ext.isResultsTabVisible) {
859+
if (results.base64) {
860+
const active = ext.activeTextEditor;
861+
if (active) {
862+
const data = `data:image/png;base64,${results.result}`;
863+
const plot = <Plot>{
864+
charts: [{ data }],
865+
};
866+
const uri = await addWorkspaceFile(
867+
active.document.uri,
868+
"plot",
869+
".plot",
870+
);
871+
if (!workspaceHas(uri)) {
872+
await workspace.openTextDocument(uri);
873+
await openWith(uri, ChartEditorProvider.viewType, ViewColumn.Beside);
874+
}
875+
await setUriContent(uri, JSON.stringify(plot));
876+
}
877+
} else if (ext.isResultsTabVisible) {
852878
writeQueryResultsToView(
853879
results,
854880
query,

src/extension.ts

Lines changed: 42 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,8 @@ import {
1717
ConfigurationTarget,
1818
EventEmitter,
1919
ExtensionContext,
20-
Range,
2120
TextDocumentContentProvider,
2221
Uri,
23-
WorkspaceEdit,
2422
commands,
2523
extensions,
2624
languages,
@@ -93,7 +91,6 @@ import { DataSourceEditorProvider } from "./services/dataSourceEditorProvider";
9391
import {
9492
FileTreeItem,
9593
WorkspaceTreeProvider,
96-
addWorkspaceFile,
9794
} from "./services/workspaceTreeProvider";
9895
import {
9996
ConnectionLensProvider,
@@ -102,6 +99,7 @@ import {
10299
importOldDSFiles,
103100
pickConnection,
104101
runActiveEditor,
102+
setServerForUri,
105103
} from "./commands/workspaceCommand";
106104
import { createDefaultDataSourceFile } from "./models/dataSource";
107105
import { connectBuildTools, lintCommand } from "./commands/buildToolsCommand";
@@ -116,13 +114,19 @@ import {
116114
renameLabel,
117115
setLabelColor,
118116
} from "./utils/connLabel";
119-
import { activateTextDocument } from "./utils/workspace";
117+
import {
118+
activateTextDocument,
119+
addWorkspaceFile,
120+
openWith,
121+
setUriContent,
122+
} from "./utils/workspace";
120123
import {
121124
InsightDetails,
122125
Insights,
123126
Server,
124127
ServerDetails,
125128
} from "./models/connectionsModels";
129+
import { ChartEditorProvider } from "./services/chartEditorProvider";
126130

127131
let client: LanguageClient;
128132

@@ -472,26 +476,19 @@ export async function activate(context: ExtensionContext) {
472476
"kdb.createDataSource",
473477
async (item: FileTreeItem) => {
474478
if (hasWorkspaceOrShowOption("adding datasources")) {
475-
const uri = await addWorkspaceFile(item, "datasource", ".kdb.json");
476-
477-
if (uri) {
478-
const edit = new WorkspaceEdit();
479-
480-
edit.replace(
481-
uri,
482-
new Range(0, 0, 1, 0),
483-
JSON.stringify(createDefaultDataSourceFile(), null, 2),
484-
);
485-
486-
workspace.applyEdit(edit);
487-
488-
await commands.executeCommand(
489-
"vscode.openWith",
490-
uri,
491-
DataSourceEditorProvider.viewType,
492-
);
493-
await commands.executeCommand("workbench.action.files.save", uri);
494-
}
479+
const uri = await addWorkspaceFile(
480+
item ? item.resourceUri : undefined,
481+
"datasource",
482+
".kdb.json",
483+
);
484+
await workspace.openTextDocument(uri);
485+
await setUriContent(
486+
uri,
487+
JSON.stringify(createDefaultDataSourceFile(), null, 2),
488+
);
489+
await openWith(uri, DataSourceEditorProvider.viewType);
490+
await commands.executeCommand("workbench.action.files.save", uri);
491+
await setServerForUri(uri, undefined);
495492
}
496493
},
497494
),
@@ -502,23 +499,31 @@ export async function activate(context: ExtensionContext) {
502499
"kdb.createScratchpad",
503500
async (item: FileTreeItem) => {
504501
if (hasWorkspaceOrShowOption("adding workbooks")) {
505-
const uri = await addWorkspaceFile(item, "workbook", ".kdb.q");
506-
if (uri) {
507-
await window.showTextDocument(uri);
508-
await commands.executeCommand("workbench.action.files.save", uri);
509-
}
502+
const uri = await addWorkspaceFile(
503+
item ? item.resourceUri : undefined,
504+
"workbook",
505+
".kdb.q",
506+
);
507+
await workspace.openTextDocument(uri);
508+
await window.showTextDocument(uri);
509+
await commands.executeCommand("workbench.action.files.save", uri);
510+
await setServerForUri(uri, undefined);
510511
}
511512
},
512513
),
513514
commands.registerCommand(
514515
"kdb.createPythonScratchpad",
515516
async (item: FileTreeItem) => {
516517
if (hasWorkspaceOrShowOption("adding workbooks")) {
517-
const uri = await addWorkspaceFile(item, "workbook", ".kdb.py");
518-
if (uri) {
519-
await window.showTextDocument(uri);
520-
await commands.executeCommand("workbench.action.files.save", uri);
521-
}
518+
const uri = await addWorkspaceFile(
519+
item ? item.resourceUri : undefined,
520+
"workbook",
521+
".kdb.py",
522+
);
523+
await workspace.openTextDocument(uri);
524+
await window.showTextDocument(uri);
525+
await commands.executeCommand("workbench.action.files.save", uri);
526+
await setServerForUri(uri, undefined);
522527
}
523528
},
524529
),
@@ -534,11 +539,7 @@ export async function activate(context: ExtensionContext) {
534539
commands.registerCommand("kdb.renameFile", async (item: FileTreeItem) => {
535540
if (item && item.resourceUri) {
536541
if (item.resourceUri.path.endsWith(".kdb.json")) {
537-
await commands.executeCommand(
538-
"vscode.openWith",
539-
item.resourceUri,
540-
DataSourceEditorProvider.viewType,
541-
);
542+
await openWith(item.resourceUri, DataSourceEditorProvider.viewType);
542543
} else {
543544
const document = await workspace.openTextDocument(item.resourceUri);
544545
await window.showTextDocument(document);
@@ -550,11 +551,7 @@ export async function activate(context: ExtensionContext) {
550551
commands.registerCommand("kdb.deleteFile", async (item: FileTreeItem) => {
551552
if (item && item.resourceUri) {
552553
if (item.resourceUri.path.endsWith(".kdb.json")) {
553-
await commands.executeCommand(
554-
"vscode.openWith",
555-
item.resourceUri,
556-
DataSourceEditorProvider.viewType,
557-
);
554+
await openWith(item.resourceUri, DataSourceEditorProvider.viewType);
558555
} else {
559556
const document = await workspace.openTextDocument(item.resourceUri);
560557
await window.showTextDocument(document);
@@ -565,6 +562,7 @@ export async function activate(context: ExtensionContext) {
565562
}),
566563

567564
DataSourceEditorProvider.register(context),
565+
ChartEditorProvider.register(context),
568566

569567
languages.registerCodeLensProvider(
570568
{ pattern: "**/*.kdb.{q,py}" },

src/models/plot.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/*
2+
* Copyright (c) 1998-2023 Kx Systems Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the
5+
* License. You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
10+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
11+
* specific language governing permissions and limitations under the License.
12+
*/
13+
14+
export interface Chart {
15+
data: string;
16+
}
17+
18+
export interface Plot {
19+
charts: Chart[];
20+
}

src/models/queryResult.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export type QueryResult = {
2626
text: string;
2727
index: number;
2828
}[];
29+
base64?: boolean;
2930
};
3031

3132
export enum QueryResultType {

0 commit comments

Comments
 (0)