Related
I have a typescript extension that needs to run a python file. after a file dialog is opened the extension uses exec to run the following command.
python C:\\Users\\schriste\\.vscode\\extensions\\consolidatedExtension\\src\\testingFile.py C:\\EquipVsCode\\5G_ServingCell_Rsrp_Rsrq_Sinr_RSSI_B974_all.isf
I thought exec would work since ive tired exec using the windows command dir and it worked just fine.
all I need is the right function to run the command shown above. has anyone done this? it seems like such a simple and common task but im having so much difficulty finding information on how this can be done.
below is the code from extension.ts
perhaps someone has information on how the following work for what I am trying to accomplish but I have not found a way for these to work as of right now: execFile spawn
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';
import { open } from 'fs';
import * as path from 'path';
import { json } from 'stream/consumers';
const { ChildProcess, exec } = require('child_process');
const { execFile } = require('node:child_process');
const { spawn } = require('node:child_process');
const { stdout, stderr } = require('process');
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
//File Dialog
let disposable = vscode.commands.registerCommand('consolidatedExtension.openFile', function () {
const options = {
canSelectMany: false,
openLabel: 'Open'
};
vscode.window.showOpenDialog(options).then(fileUri => {
if (fileUri && fileUri[0]) {
console.log('Selected file: ' + fileUri[0].fsPath);
let cmd = `python C:\\Users\\schriste\\.vscode\\extensions\\consolidatedExtension\\src\\testingFile.py` + ` ` + fileUri[0].fsPath
exec(cmd2, (...args: any[])=>{
console.log(args);
});
}
});
});
//open graphView
let openWebview = vscode.commands.registerCommand('consolidatedExtension.openWebview', () => {
const panel = vscode.window.createWebviewPanel(
'openWebview', // Identifies the type of the webview. Used internally
'Example Page', // Title of the panel displayed to the user
vscode.ViewColumn.One, // Editor column to show the new webview panel in.
{ // Enable scripts in the webview
enableScripts: true //Set this to true if you want to enable Javascript.
});
//get path to json on disk
const onDiskPath = vscode.Uri.file(
path.join(context.extensionPath, 'src', 'data.json')
);
//get vegaLite js on disk
const JsonDiskPath = vscode.Uri.file(
path.join(context.extensionPath, 'src', 'vegaLiteGraphs.js')
);
//and get the special URI to use with the webview
const jsonSRC = panel.webview.asWebviewUri(onDiskPath);
const jsSRC = panel.webview.asWebviewUri(JsonDiskPath);
panel.webview.html = getWebviewContent(jsonSRC, jsSRC);
});
context.subscriptions.push(openWebview);
context.subscriptions.push(disposable);
}
// this method is called when your extension is deactivated
export function deactivate() {}
function getWebviewContent(jsonSRC:vscode.Uri, jsSRC:vscode.Uri) {
return `<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/vega#5.21.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-lite#5.2.0"></script>
<script src="https://cdn.jsdelivr.net/npm/vega-embed#6.20.2"></script>
</head>
<body>
<script type = "module">
import users from '${jsonSRC}' assert {type: 'json'};
const graphDataContainer = []
let dataPoints = []
for(let i = 0; i < users.length; i += 2)
{
for (let j = 1; j < users[i].length; j++) {
dataPoints.push({
x: users[i][j],
y: users[i + 1][j]
});
}
graphDataContainer.push(dataPoints)
dataPoints = []
}
console.log(graphDataContainer)
window.onload = function() {
let i = 0
var chart1 = new CanvasJS.Chart("chart1", {
animationEnabled: true,
zoomEnabled: true,
theme: "light2",
"title": { "text": "RSRP" },
axisX: {
gridThickness: 0,
tickLength: 0,
lineThickness: 0,
labelFormatter: function(){ return " "; },
crosshair: {
enabled: true,
color: "black",
labelFontColor: "#F8F8F8"
},
//interval: 10,
//intervalType: "millisecond",
//valueFormatString: "##.##.####"
},
axisY: {
crosshair: {
enabled: true,
color: "black",
labelFontColor: "#F8F8F8"
},
title: "Serving Cell RSRP (dBm)",
minimum: -100,
maximum: 0,
interval: 16.67
},
data: [{
type: "line",
//yValueFormatString: "#,### Units",
dataPoints: graphDataContainer[i]
}],
rangeChanged: syncHandler
});
chart1.render();
i++
var rsrqChart = new CanvasJS.Chart("chart2", {
animationEnabled: true,
zoomEnabled: true,
theme: "light2",
axisX: {
valueFormatString:"##:##:##.###",
crosshair: {
enabled: true,
color: "black",
labelFontColor: "#F8F8F8"
},
},
axisY: {
crosshair: {
enabled: true,
color: "black",
labelFontColor: "#F8F8F8"
},
title: "Serving Cell RSRQ",
minimum: -15,
interval: 2.5
},
data: [{
type: "line",
dataPoints: graphDataContainer[i]
}],
rangeChanged: syncHandler
});
rsrqChart.render();
// var chart3 = new CanvasJS.Chart("chartContainer3", {
// animationEnabled: true,
// theme: "light2",
// data: [{
// type: "line",
// dataPoints: sinrPoints
// }]
// });
// chart3.render();
var charts = [chart1, rsrqChart];
function syncHandler(e){
for (var i = 0; i < charts.length; i++) {
var chart = charts[i];
if (!chart.options.axisX)
chart.options.axisX = {};
if (!chart.options.axisY)
chart.options.axisY = {};
if (e.trigger === "reset") {
chart.options.axisX.viewportMinimum = chart.options.axisX.viewportMaximum = null;
chart.options.axisY.viewportMinimum = chart.options.axisY.viewportMaximum = null;
chart.render();
} else if (chart !== e.chart) {
chart.options.axisX.viewportMinimum = e.axisX[0].viewportMinimum;
chart.options.axisX.viewportMaximum = e.axisX[0].viewportMaximum;
chart.options.axisY.viewportMinimum = e.axisY[0].viewportMinimum;
chart.options.axisY.viewportMaximum = e.axisY[0].viewportMaximum;
chart.render();
}
}
}
}
</script>
<script type = "module" src = "${jsSRC}"></script>
<div id="chart1" style="height: 370px; width: 100%;"></div>
<div id="chart2" style="height: 370px; width: 100%;"></div>
<div id="vis"></div>
<!-- <div id="chartContainer3" style="height: 370px; width: 100%;"></div> -->
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"> </script>
</body>
</html>
`;
}
I am using the pdfmake library in a project, but its execution takes about 2-3 min.
Is the library normally slow or do I need to improve the performance of my code ?
It is also possible that performances are impacted by the code being executed in chunks, but I am not sure I understand the role of chunks and why they are used.
var docDefinition = {
footer: function (currentPage, pageCount) {
return {
margin: [40, 0, 0, 0],
columns: [{
fontSize: 8,
text: [
{
text: 'Page ' + currentPage.toString() + ' / ' + pageCount,
}
],
}]
};
},
content: contentAry,
styles: {
clsHeader: {
fontSize: 12,
bold: true
},
clsSubHeader: {
fontSize: 10
},
clsTblHeader: {
fillColor: '#9e9e9e',
color: '#FFFFFF'
},
clsImage: {
margin: [0, 40, 0, 0]
},
clsTable: {
fontSize: 8
}
},
defaultStyle: {
alignment: 'justify'
}
}
var doc = printer.createPdfKitDocument(docDefinition);
var chunks = [];
doc.on('readable', function () {
var chunk;
while ((chunk = doc.read(9007199254740991)) !== null) {
chunks.push(chunk);
}
});
Is it possible to modify the chunk size?
I have this:
Is it possible to animate one section of this chart, a Pie, on hover to make it grow, as in offset by either giving it padding or a different height?
I think this should be possible because on their site it says " Animate everything!", but haven't had any luck yet. Tried using events but not working.
// Doughnut chart
var myDoughnutChart = new Chart(ctx, {
type: 'doughnut',
data: {
datasets: [{
data: [11, 47, 53],
backgroundColor: ['rgb(137, 207, 191)', 'rgb(140, 187, 206)', 'rgb(144, 156, 209)']
}],
labels: [
'Elementary',
'Middle School',
'High School'
],
},
options: {
cutoutPercentage: 60,
title: {
display: true,
text: 'Grade',
position: 'top',
fontFamily: 'sans-serif',
fontSize: 18,
fontColor: 'rgb(97, 98, 116)',
padding: '20'
},
layout: {
padding: {
top: 20,
}
},
legend: {
display: true,
},
onHover: stuff,
slices: {
1: {
offset: .5
}
}
}
});
function stuff(e) {
var activePoints = myDoughnutChart.getElementsAtEvent(e);
console.log(activePoints);
}
Thanks for any help.
Add this code in update function of doughnut
var innerRadius = reset && animationOpts.animateScale ? 0 : me.innerRadius;
if (index == doughnutIndex) {
innerRadius = innerRadius + 10;
}
And add a new function setHoverStyle
setHoverStyle: function(arc) {
doughnutIndex = arc._index;
this.update();
},
If what you are wanting is for the section to move outward on hover, that is done with simply setting hoverOffset with a number. See this example and documentation here.
I'm using chart.js (V2) to try to build a bar chart that has more information available to user without having to hover over or click anywhere. I've provided two examples of how I hope to edit my chart.
Two edited versions of what I hope to achieve
As can be seen, I hope to place (somewhere), some extra information outside of the labels. I had hope that by adding '\n' to the labels I might have been able to get what I was looking for similar to option A.
Some edited code is provided blow:
var barChartData = {
labels: playerNames,
datasets: [{
label: 'Actual Score/Hour',
backgroundColor: "rgba(0, 128, 0,0.5)",
data: playerScores
}, {
label: 'Expected Score/Hour',
backgroundColor: "rgba(255,0,0,0.5)",
data: playerExpected
}]
};
function open_win(linktosite) {
window.open(linktosite)
}
canvas.onclick = function(evt){
var activePoints = myBar.getElementsAtEvent(evt);
console.log(activePoints);
linktosite = 'https://www.mytestsite.com/' + activePoints[1]['_model']['label'];
open_win(linktosite);
};
window.onload = function() {
var ctx = document.getElementById("canvas").getContext("2d");
window.myBar = new Chart(ctx, {
type: 'bar',
data: barChartData,
options: {
title:{
display:true,
text:"Player Expected and Actual Score per Hour"
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: false,
}],
yAxes: [{
stacked: false
}]
},
animation: {
onComplete: function () {
var ctx = this.chart.ctx;
ctx.textAlign = "center";
Chart.helpers.each(this.data.datasets.forEach(function (dataset) {
Chart.helpers.each(dataset.metaData.forEach(function (bar, index) {
// console.log("printing bar" + bar);
ctx.fillText(dataset.data[index], bar._model.x, bar._model.y - 10);
}),this)
}),this);
}
}
}
});
// Chart.helpers.each(myBar.getDatasetMeta(0).data, function(rectangle, index) {
// rectangle.draw = function() {
// myBar.chart.ctx.setLineDash([5, 5]);
// Chart.elements.Rectangle.prototype.draw.apply(this, arguments);
// }
// }, null);
};
At this point I'd be satisfied with having the extradata anywhere on the bar. Any help would be appreciated. Thanks~
Chart.js v2.1.5 allows for multi-line labels using nested arrays (v2.5.0 fixes it for radar graphs):
...
data: {
labels: [["Jake", "Active: 2 hrs", "Score: 1", "Expected: 127", "Attempts: 4"],
["Matt", "Active: 2 hrs", "Score: 4", "Expected: 36", "Attempts: 4"]],
...
However, this does mean that you will have to pre-calculate the label values.
var config = {
type: 'line',
data: {
labels: [["January","First Month","Jellyfish","30 of them"], ["February","Second Month","Foxes","20 of them"], ["March","Third Month","Mosquitoes","None of them"], "April", "May", "June", "July"],
datasets: [{
label: "My First dataset",
data: [65, 40, 80, 81, 56, 85, 45],
backgroundColor: "rgba(255,99,132,0.2)",
}, {
label: "My Second dataset",
data: [40, 80, 21, 56, 85, 45, 65],
backgroundColor: "rgba(99,255,132,0.2)",
}]
},
scales : {
xAxes : [{
gridLines : {
display : false,
lineWidth: 1,
zeroLineWidth: 1,
zeroLineColor: '#666666',
drawTicks: false
},
ticks: {
display:true,
stepSize: 0,
min: 0,
autoSkip: false,
fontSize: 11,
padding: 12
}
}],
yAxes: [{
ticks: {
padding: 5
},
gridLines : {
display : true,
lineWidth: 1,
zeroLineWidth: 2,
zeroLineColor: '#666666'
}
}]
},
spanGaps: true,
responsive: true,
maintainAspectRatio: true
};
var ctx = document.getElementById("myChart").getContext("2d");
new Chart(ctx, config);
<div class="myChart">
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script>
<canvas id="myChart"></canvas>
</div>
If a label is an array as opposed to a string i.e. [["June","2015"], "July"] then each element is treated as a separate line. The appropriate calculations are made to determine the correct height and width, and rotation is still supported.
charJS version 2.7.2 used
this also works in https://github.com/jtblin/angular-chart.js
If you are using Chart.js v2.7.1, the above solution might not work.
The solution that actually worked for us was adding a small plugin right in the data and options level:
const config = {
type: 'bar',
data: {
// ...
},
options: {
// ...
},
plugins: [{
beforeInit: function (chart) {
chart.data.labels.forEach(function (label, index, labelsArr) {
if (/\n/.test(label)) {
labelsArr[index] = label.split(/\n/)
}
})
}
}]
};
A full description of how to fix this issue can be found here.
With Chart.js v2.1, you can write a chart plugin to do this
Preview
Script
Chart.pluginService.register({
beforeInit: function (chart) {
var hasWrappedTicks = chart.config.data.labels.some(function (label) {
return label.indexOf('\n') !== -1;
});
if (hasWrappedTicks) {
// figure out how many lines we need - use fontsize as the height of one line
var tickFontSize = Chart.helpers.getValueOrDefault(chart.options.scales.xAxes[0].ticks.fontSize, Chart.defaults.global.defaultFontSize);
var maxLines = chart.config.data.labels.reduce(function (maxLines, label) {
return Math.max(maxLines, label.split('\n').length);
}, 0);
var height = (tickFontSize + 2) * maxLines + (chart.options.scales.xAxes[0].ticks.padding || 0);
// insert a dummy box at the bottom - to reserve space for the labels
Chart.layoutService.addBox(chart, {
draw: Chart.helpers.noop,
isHorizontal: function () {
return true;
},
update: function () {
return {
height: this.height
};
},
height: height,
options: {
position: 'bottom',
fullWidth: 1,
}
});
// turn off x axis ticks since we are managing it ourselves
chart.options = Chart.helpers.configMerge(chart.options, {
scales: {
xAxes: [{
ticks: {
display: false,
// set the fontSize to 0 so that extra labels are not forced on the right side
fontSize: 0
}
}]
}
});
chart.hasWrappedTicks = {
tickFontSize: tickFontSize
};
}
},
afterDraw: function (chart) {
if (chart.hasWrappedTicks) {
// draw the labels and we are done!
chart.chart.ctx.save();
var tickFontSize = chart.hasWrappedTicks.tickFontSize;
var tickFontStyle = Chart.helpers.getValueOrDefault(chart.options.scales.xAxes[0].ticks.fontStyle, Chart.defaults.global.defaultFontStyle);
var tickFontFamily = Chart.helpers.getValueOrDefault(chart.options.scales.xAxes[0].ticks.fontFamily, Chart.defaults.global.defaultFontFamily);
var tickLabelFont = Chart.helpers.fontString(tickFontSize, tickFontStyle, tickFontFamily);
chart.chart.ctx.font = tickLabelFont;
chart.chart.ctx.textAlign = 'center';
var tickFontColor = Chart.helpers.getValueOrDefault(chart.options.scales.xAxes[0].fontColor, Chart.defaults.global.defaultFontColor);
chart.chart.ctx.fillStyle = tickFontColor;
var meta = chart.getDatasetMeta(0);
var xScale = chart.scales[meta.xAxisID];
var yScale = chart.scales[meta.yAxisID];
chart.config.data.labels.forEach(function (label, i) {
label.split('\n').forEach(function (line, j) {
chart.chart.ctx.fillText(line, xScale.getPixelForTick(i + 0.5), (chart.options.scales.xAxes[0].ticks.padding || 0) + yScale.getPixelForValue(yScale.min) +
// move j lines down
j * (chart.hasWrappedTicks.tickFontSize + 2));
});
});
chart.chart.ctx.restore();
}
}
});
and then
...
data: {
labels: ["January\nFirst Month\nJellyfish\n30 of them", "February\nSecond Month\nFoxes\n20 of them", "March\nThird Month\nMosquitoes\nNone of them", "April", "May", "June", "July"],
...
Note - we assume that the maximum content of one line will fit between the ticks (i.e. that no rotation logic is needed. I'm sure it's possible to incorporate rotation logic too, but it would be a tad more complicated)
You should format the tooltips to not show the x axis label, or format it to show a shorter version of the label.
Fiddle - http://jsfiddle.net/m0q03wpy/
I am stuck in a bit of a problem. You people might have seen an animated line which acts like a scanner in many apps. Well I ned something similar to that but I need it in a graph.
What I actually need is that I need to plt a vertical line which moves from one point to other automatically.
Let me give you a bit more explaination:
1. I have a button
2. I press the button and graph area appears.
3. On the graph area, a vertical line scrolls through the area as if it is scanning the area.
I am able to plot the line but it is coming out to be a little tilted. The logic behind that is provided below:
for(i=0;i<frequencyArray.length;i++){
myTestArray2.push([i,outFrequencyArray[i]]);
}
plot.setData([
{data:myTestArray2,lines:{fill:false,lineWidth:3},shadowSize:10}
]);
function setUpflot(){
// setup plot
//console.log("setUpflot");
var options = {
// series : { shadowSize: 0, splines: {show:true,lineWidth:1}},
series : { },
yaxis : { ticks: 5, tickColor:"rgba(148,129,151,0.5)", min: minGraphY, max:maxGraphY,show: true},
xaxis : { tickLength:0, show: false },
grid : { borderWidth:0,markings:[
{yaxis: { from: 200.0, to: 240.0 },color: "rgba(140,2,28,0.5)"}
]}
};
I put this together in response to a comment yesterday.
Fiddle here.
Produces:
plot = $.plot($("#placeholder"),
[ { data: someData} ], {
series: {
lines: { show: true }
},
crosshair: { mode: "x" }, // turn crosshair on
grid: { hoverable: true, autoHighlight: false },
yaxis: { min: -1.2, max: 1.2 }
});
crossHairPos = plot.getAxes().xaxis.min;
direction = 1;
setCrossHair = function(){
if (direction == 1){
crossHairPos += 0.5;
}
else
{
crossHairPos -= 0.5;
}
if (crossHairPos < plot.getAxes().xaxis.min){
direction = 1;
crossHairPos = plot.getAxes().xaxis.min;
}
else if (crossHairPos > plot.getAxes().xaxis.max)
{
direction = 0;
crossHairPos = plot.getAxes().xaxis.max;
}
plot.setCrosshair({x: crossHairPos})
setTimeout(setCrossHair,100);
}
// kick it off
setTimeout(setCrossHair,100);
var frequencyIndex = 0; //dynamic values stored intialised with 0.
var outFrequencyArray = [];
for(i=0;i<totalPoints;i++){
outFrequencyArray.push(minGraphY-1);
}
opd=Math.tan(Math.PI/2);
outFrequencyArray.splice(frequencyIndex,0,opd);
frequencyIndex++;
for(i=0;i<frequencyArray.length;i++){
myTestArray2.push([i,outFrequencyArray[i]]);
}
plot.setData([
{data:myTestArray2,lines:{fill:false,lineWidth:3},shadowSize:10}
]);
function setUpflot(){
// setup plot
//console.log("setUpflot");
var options = {
// series : { shadowSize: 0, splines: {show:true,lineWidth:1}},
series : { },
yaxis : { ticks: 5, tickColor:"rgba(148,129,151,0.5)", min: minGraphY, max:maxGraphY,show: true},
xaxis : { tickLength:0, show: false },
grid : { borderWidth:0,markings:[
{yaxis: { from: 200.0, to: 240.0 },color: "rgba(140,2,28,0.5)"}
]}
};