Style ContextMenuButton in GoJS - javascript

Hello I have problem with style ContextMenuButton :/
cm.add(this.$("ContextMenuButton",
this.$(go.TextBlock, {
text: 'Usuń',
stroke: '#323232',
background: '#eee',
margin: 0,
alignment: go.Spot.Center
}),
{
click: () => {
this.diagram.commandHandler.deleteSelection();
},
mouseHover: () => {
console.log(this.diagram);
}
}));
How to set new properties for cm object? I mean how to remove blue shadow? (mouse over)

You need to add selectionAdorned: false to your context menu.
Here is an example I did on Codepen.
You can see this is a context menu and when you remove the selectionAdorned property, when you click on the items you will have the selection around the square.
You can find documentation about this here.

Ok, but it's does't work :/ the only place where I found anything about contextMenu is this part of code. As you can see I have added cm.selectionAdorned = false;
private setUpDiagram() {
this.diagram = new go.Diagram();
this.diagram.initialContentAlignment = go.Spot.Center;
this.diagram.undoManager.isEnabled = true;
this.diagram.validCycle = go.Diagram.CycleNotDirected;
this.diagram.toolManager.panningTool.canStart = () => {
return this.diagram.lastInput.control;
};
this.diagram.toolManager.dragSelectingTool.isEnabled = true;
this.diagram.allowCopy = false;
this.diagram.addDiagramListener('SelectionMoved', () => this.shiftNodesToEmptySpaces(this.diagram));
this.diagram.toolManager.draggingTool.isCopyEnabled = false;
this.diagram.toolManager.contextMenuTool.showContextMenu = (cm: Adornment, obj) => {
let data = obj.part.data;
this.diagram.selectCollection(this.diagram.selection.filter(x => x.key != '0'));
while (cm.elements.count > 0) cm.removeAt(0);
cm.selectionAdorned = false;
console.log(cm);
if (data.key != '0') {
cm.add(this.$("ContextMenuButton",
this.$(go.Shape,
{
stroke: null, strokeWidth: 0,
fill: '#323232',
width: 50,
height: 25
},
),
this.$(go.TextBlock, {
text: 'Usuń',
stroke: '#ffffff',
background: '#323232',
margin: 0,
alignment: go.Spot.Center
}),
{
click: () => {
this.diagram.commandHandler.deleteSelection();
}
}));
}
go.ContextMenuTool.prototype.showContextMenu.call(this.diagram.toolManager.contextMenuTool, cm, obj);
};
}

Related

Javascript: I want to save a PDF from material table. After clicking on download PDF, it's taking more than few minutes and screen freezes

I have more than 150k records in my table. what mistake I'm doing?
Function I'm calling.
const exportPDF = () => {
var doc;
if (download_fields.length < 9) {
doc = new jsPDF('p', 'mm', [297, 210]);
}
else {
doc = new jsPDF('l', 'pt', [12000, 12000]);
}
const data = download_data.map(elt => {
let download_arr = []
download_fields.forEach(e => { Object.entries(elt).forEach(entry => <>{e === entry[0] ? download_arr.push(entry[1]) : null}</>) })
// console.log(download_arr)
return (
download_arr
)
});
doc.autoTable(download_headers, data, {
margin: { top: 15 },
styles: { fontSize: 14, halign: 'center' },
theme: "grid",
didParseCell: function (data) {
if (data.row.index === 0 && data.section !== 'body') {
data.cell.styles.fillColor = [0, 102, 204];
data.cell.styles.lineWidth = 2;
}
}
});
doc.save(`${file_name}.pdf`);
}
Line where I'm creating data is taking more time to execute. Till then I'm unable to do any other task on the screen (freeze).
Talking time is fine if we find any solution to do other work while it's generating PDF parallelly.

How to get get name of hospital or street in particular area when draw polyline through Javascript ArcGIS Api?

Actually I am using ArcGIS API for JavaScript 4.7. I want to get name of hospital or street in particular area when draw polyline . How to achieve that ?
Suppose I draw a area through polyline. In this area there are some hospital or street ..etc . Now I need the name of hospitals or street within that area.
the result look like :-
[street1,street2, ...] ,
[hospital1,hospital2, ...]
Update
error :-esri.layers.graphics.QueryEngine", message: "Unsupported query" details: undefined}
this error appear when try to collect hospital name in selected area the user can draw multi polygon,polyline
require([
"esri/views/MapView",
"esri/Map",
"esri/Basemap",
"esri/layers/TileLayer",
"esri/layers/MapImageLayer",
"esri/widgets/Sketch/SketchViewModel",
"esri/geometry/geometryEngine",
"esri/widgets/CoordinateConversion",
"esri/geometry/support/webMercatorUtils",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/config",
"esri/core/urlUtils",
"esri/widgets/Search",
"esri/tasks/Locator",
"esri/layers/FeatureLayer",
"esri/widgets/Expand",
"dojo/domReady!"
], function (
MapView, Map, Basemap, TileLayer, MapImageLayer,
SketchViewModel,
geometryEngine,
CoordinateConversion,
webMercatorUtils,
Graphic, GraphicsLayer, esriConfig,
urlUtils,Search,Locator,FeatureLayer,Expand
) {
const hospitals =new FeatureLayer({
url: 'https://services.arcgis.com/fLeGjb7u4uXqeF9q/ArcGIS/rest/services/Hospitals/Feat
ureServer/0',
renderer: {
type: 'simple',
symbol: {
type: 'text',
color: 'green',
text: '\ue687',
font: {
size: 16,
family: 'CalciteWebCoreIcons'
},
haloColor: 'white',
haloSize: 2
}
},
outFields: ['*']
});
var tempGraphicsLayer = new GraphicsLayer();
var saveGraphicsLayer = new GraphicsLayer();
var updateGraphic;
let hospitalsLayerView = null;
let highlight = null;
var myMap;
myMap = new Map({
basemap: "streets", //satellite
layers: [hospitals,tempGraphicsLayer, saveGraphicsLayer]
});
view = new MapView({
center: [-75.1683665, 39.951817],// [54.49, 24.41] long, lat
container: "viewDiv",
map: myMap,
zoom: 14
});
var ccWidget = new CoordinateConversion({
view: view
});
const searchWidget = new Search({
sources: [{
locator: new Locator({ url:
"https://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer"}),
countryCode:"AE",
singleLineFieldName: "SingleLine",
name: "Custom Geocoding Service",
localSearchOptions: {
minScale: 300000,
distance: 50000
},
placeholder: "Find a place",
maxResults: 3,
maxSuggestions: 6,
suggestionsEnabled: true,
minSuggestCharacters: 0
}],
view: view,
includeDefaultSources: false
});
view.ui.add(searchWidget, {
position: "top-right",
index: 1
});
view.ui.add(ccWidget, "bottom-left");
view.ui.add("topbar", "top-right");
var pointSymbol = { // symbol used for points
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
style: "square",
color: "#8A2BE2",
size: "16px",
outline: { // autocasts as new SimpleLineSymbol()
color: [255, 255, 255],
width: 3 // points
}
}
var polylineSymbol = { // symbol used for polylines
type: "simple-line", // autocasts as new SimpleLineSymbol()
color: "#8A2BE2",
width: "4",
style: "dash"
}
var polygonSymbol = { // symbol used for polygons
type: "simple-fill", // autocasts as new SimpleFillSymbol()
color: "rgba(138,43,226, 0.8)",
style: "solid",
outline: {
color: "white",
width: 1
}
}
var polygonBoundrySymbol = { // symbol used for polygons
type: "simple-line", // autocasts as new SimpleFillSymbol()
color: "red"
}
let drawBoundry = function(){
let boundryJson = $v('P0_USER_LIMITS');
if(boundryJson){
let boundry = Graphic.fromJSON(JSON.parse(boundryJson));
boundry.symbol = polygonBoundrySymbol;
tempGraphicsLayer.add(boundry);
return boundry;
}
}
view.when(function () {
$('.esri-view-root').on('click', '.esri-print__export-button',
function(e){
e.preventDefault();
saveExportedImg();
});
// create a new sketch view model
var sketchViewModel = new SketchViewModel({
view: view,
layer: tempGraphicsLayer,
pointSymbol: pointSymbol,
polylineSymbol: polylineSymbol,
polygonSymbol: polygonSymbol
});
hospitals.when(function () {
view.whenLayerView(hospitals).then(function (layerView){
hospitalsLayerView = layerView;
})
})
.catch(errorCallback);
sketchViewModel.on("draw-complete", addGraphic);
sketchViewModel.on("update-complete", addGraphic);
sketchViewModel.on("update-cancel", addGraphic);
sketchViewModel.on("vertex-add", addGraphic);
function addGraphic(evt) {
// console.log ('graphic.geometry',evt.geometry)
//let currentGraphic = popActiveGraphic(tempGraphicsLayer);
let currentGraphic = saveGraphicsLayer.graphics.items.pop();
selectFeatures(evt.geometry);
var geometry = evt.geometry;
var vertices = evt.vertices;
var symbol;
var attr = {
Name: "Selected Area",
X: $v('P24_X'),
Y: $v('P24_Y')
};
// Choose a valid symbol based on return geometry
switch (geometry.type) {
case "point":
symbol = pointSymbol;
break;
case "polyline":
symbol = polylineSymbol;
break;
default:
symbol = polygonSymbol;
break;
}
geometry = webMercatorUtils.webMercatorToGeographic(geometry)
var within = true;
//}
if(within){
let graphic = new Graphic({
geometry: geometry,
symbol: symbol,
//attributes: attr,
popupTemplate: {
title: "{Name}",
content: [{
type: "fields",
fieldInfos: [{
fieldName: "X"
}, {
fieldName: "Y"
}]
}]
}
});
tempGraphicsLayer.add(graphic);
if(currentGraphic){
geometry.rings.forEach( ring =>
currentGraphic.geometry.addRing(ring));
graphic = currentGraphic;
}
var saveObj = graphic.toJSON();
$x('P24_JSON').value = JSON.stringify(saveObj);
saveGraphicsLayer.add(graphic);
} else {
apex.message.alert('&G_MAP_BOUNDRY_MSG.');
}
updateGraphic = null;
}
window.loadGraphic = function(polygon){
if(polygon===undefined || polygon === ''){
console.error('no polygon');
} else {
var graphic = Graphic.fromJSON(JSON.parse(polygon));
if (graphic.geometry){
addMultiGraph(graphic);
view.center.longitude = graphic.geometry.centroid.longitude;
view.center.latitude = graphic.geometry.centroid.latitude;
view.center = [graphic.geometry.centroid.longitude,
graphic.geometry.centroid.latitude];
view.zoom = 12;
}
}
}
loadGraphic($v('P24_JSON'));
// *************************************
// activate the sketch to create a point
// *************************************
var drawPointButton = document.getElementById("pointButton");
drawPointButton.onclick = function () {
// set the sketch to create a point geometry
sketchViewModel.create("point");
setActiveButton(this);
};
// ****************************************
// activate the sketch to create a polyline
// ****************************************
var drawLineButton = document.getElementById("polylineButton");
drawLineButton.onclick = function () {
// set the sketch to create a polyline geometry
sketchViewModel.create("polyline");
setActiveButton(this);
};
// ***************************************
// activate the sketch to create a polygon
// ***************************************
var drawPolygonButton = document.getElementById("polygonButton");
drawPolygonButton.onclick = function () {
// set the sketch to create a polygon geometry
sketchViewModel.create("polygon");
setActiveButton(this);
};
// ***************************************
// activate the sketch to create a rectangle
// ***************************************
var drawRectangleButton = document.getElementById(
"rectangleButton");
drawRectangleButton.onclick = function () {
// set the sketch to create a polygon geometry
sketchViewModel.create("rectangle");
setActiveButton(this);
};
document.getElementById("resetBtn").onclick = function () {
sketchViewModel.reset();
tempGraphicsLayer.removeAll();
saveGraphicsLayer.removeAll();
setActiveButton();
drawBoundry();
};
function setActiveButton(selectedButton) {
// focus the view to activate keyboard shortcuts for sketching
view.focus();
var elements = document.getElementsByClassName("active");
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove("active");
}
if (selectedButton) {
selectedButton.classList.add("active");
}
}
// ************************************************************************************
// set up logic to handle geometry update and reflect the update on "tempGraphicsLayer"
// ************************************************************************************
function setUpClickHandler() {
view.on("click", function (evt) {
view.hitTest(evt).then(function (response) {
var results = response.results;
// Found a valid graphic
if (results.length && results[results.length - 1]
.graphic) {
// Check if we're already editing a graphic
if (!updateGraphic) {
// Save a reference to the graphic we intend to update
updateGraphic = results[results.length - 1].graphic;
// Remove the graphic from the GraphicsLayer
// Sketch will handle displaying the graphic while being updated
tempGraphicsLayer.remove(updateGraphic);
sketchViewModel.update(updateGraphic.geometry);
}
}
});
});
}
function selectFeatures(geometry) {
if (hospitalsLayerView) {
let query = hospitals.createQuery();
query.returnGeometry = true;
query.outFields = ["*"];
hospitalsLayerView.queryFeatures(query)
.then(function (results) {
console.log ('results.features',results.features);
const graphics = results.features;
if (highlight) {
highlight.remove();
}
highlight = hospitalsLayerView.highlight(graphics);
console.log ('hospitL',graphics.map(g =>
g.attributes.HOSPITAL_NAME).join(','));
// namesDiv.innerHTML = graphics.map(g =>
g.attributes.HOSPITAL_NAME).join(',');
}).catch(errorCallback);
}
}
function errorCallback(error) {
console.log('error:', error);
}
// ************************************************************************************
// returns graphic object if drawn on the map to contcat new graphics to it
// ************************************************************************************
function popActiveGraphic(graphicsLayer){
let length = graphicsLayer.graphics.length;
let count = 0;
if($v('P0_USER_LIMITS').length > 0){
count++;
}
if(length > count){ //active drawing detected
let result = graphicsLayer.graphics.items[length-1];
graphicsLayer.remove(result);
return result;
}
}
});
});
Thanks,
Well, here I made an example for you merging some ArcGIS examples.
Just select the hospitals using a polygon. The selected hospitals are highlighted and the names display in the text section.
In your case do the same thing with any other layer you want to query to get features data.
<html>
<head>
<meta charset='utf-8'>
<meta name='viewport' content='initial-scale=1, maximum-scale=1, user-scalable=no'>
<title>Select Feature With Polygon</title>
<style>
html,
body {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#viewDiv {
padding: 0;
margin: 0;
height: 400px;
width: 100%;
}
#namesDiv {
margin: 10px;
height: 200px;
width: 100%;
font-style: italic;
font-weight: bold;
font-family: Arial, Helvetica, sans-serif;
font-size: 16px;
color: green;
overflow: auto;
}
</style>
<link rel='stylesheet' href='https://js.arcgis.com/4.15/esri/css/main.css'>
<script src='https://js.arcgis.com/4.15/'></script>
<script>
require([
'esri/Map',
'esri/views/MapView',
'esri/layers/FeatureLayer',
'esri/layers/GraphicsLayer',
'esri/widgets/Sketch/SketchViewModel',
'esri/Graphic',
'esri/widgets/Expand'
], function (
Map,
MapView,
FeatureLayer,
GraphicsLayer,
SketchViewModel,
Graphic,
Expand
) {
let hospitalsLayerView = null;
let highlight = null;
const hospitals = new FeatureLayer({
url: 'https://services.arcgis.com/fLeGjb7u4uXqeF9q/ArcGIS/rest/services/Hospitals/FeatureServer/0',
renderer: {
type: 'simple',
symbol: {
type: 'text',
color: 'green',
text: '\ue687',
font: {
size: 16,
family: 'CalciteWebCoreIcons'
},
haloColor: 'white',
haloSize: 2
}
},
outFields: ['*']
});
const polygonGraphicsLayer = new GraphicsLayer();
const map = new Map({
basemap: 'streets',
layers: [hospitals, polygonGraphicsLayer]
});
const view = new MapView({
container: 'viewDiv',
map: map,
center: [-75.1683665, 39.951817],
zoom: 14
});
const sketchViewModel = new SketchViewModel({
view: view,
layer: polygonGraphicsLayer,
pointSymbol: {
type: 'simple-marker',
color: [255, 255, 255, 0],
size: '1px',
outline: {
color: 'gray',
width: 0
}
}
});
sketchViewModel.on('create', function (event) {
if (event.state === 'complete') {
polygonGraphicsLayer.remove(event.graphic);
selectFeatures(event.graphic.geometry);
}
});
hospitals.when(function () {
view.whenLayerView(hospitals).then(function (layerView){
hospitalsLayerView = layerView;
})
})
.catch(errorCallback);
const namesDiv = document.getElementById('namesDiv');
view.ui.add('select-by-polygon', 'top-left');
const selectButton = document.getElementById('select-by-polygon');
selectButton.addEventListener('click', function () {
clearUpSelection();
sketchViewModel.create('polygon');
});
function selectFeatures(geometry) {
view.graphics.removeAll();
if (hospitalsLayerView) {
const query = {
geometry: geometry,
outFields: ['*']
};
hospitalsLayerView
.queryFeatures(query)
.then(function (results) {
const graphics = results.features;
if (highlight) {
highlight.remove();
}
highlight = hospitalsLayerView.highlight(graphics);
namesDiv.innerHTML = graphics.map(g => g.attributes.HOSPITAL_NAME).join(',');
})
.catch(errorCallback);
}
}
function clearUpSelection() {
view.graphics.removeAll();
namesDiv.innerHTML = null;
}
function errorCallback(error) {
console.log('error:', error);
}
});
</script>
</head>
<body>
<div id='viewDiv'>
<div
id="select-by-polygon"
class="esri-widget esri-widget--button esri-widget esri-interactive"
title="Select hospitals by polygon"
>
<span class="esri-icon-checkbox-unchecked"></span>
</div>
</div>
<div id="namesDiv"></div>
</body>
</html>

Pass prop value to dynamically built click event in svg Vue.js component

I'm creating a map component from a JSON array and adding a click event handler to each item. The click event will toggle the css style to colour the item. This works fine. What I'd like to do though, is to choose the colour to toggle from a prop. However, the value is only set when the function is created, not when it fires. I'm not sure how to get to the current value of the prop 'pickColour' when doing the click event function. Alternatively, how do I find the equivalent of the 'this.node' if I use an arrow function?
This is my component,
<template>
<div>
<div>{{pickColour}}</div>
<div :id="svgId" class="svg-container"></div>
</div>
</template>
<script>
import myMap from "../assets/MainMap";
export default {
name: "VenueMapComponent",
props: {
pickColour: String,
},
data: function () {
return {
svgId: "myMap",
mapAttr: {
viewBoxWidth: 1000,
viewBoxHeight: 2500,
imageWidth: 1000,
imageHeight: 2500,
},
svgContainer: null,
};
},
mounted: function () {
this.generateVenueMap();
},
methods: {
generateVenueMap: function () {
const vue = this;
const mapData = myMap.g.path;
const svgContainer = vue
.$svg("myMap")
.size("100%", "100%")
.viewbox(-200, 0, vue.mapAttr.viewBoxWidth, vue.mapAttr.viewBoxHeight);
vue.svgContainer = svgContainer;
mapData.forEach((pathObj) => {
vue.generatePath(svgContainer, pathObj);
});
},
generatePath: function (svgCont, pathObj) {
const vue = this;
const attrs = {
title: pathObj["-title"],
"map-id": pathObj["-id"],
};
const element = svgCont.path(pathObj["-d"]).attr(attrs);
let mapId = "";
let title = "";
element.click(function () {
mapId = this.node.attributes["map-id"].value;
title = this.node.attributes["title"].value;
// need a way to set string from property
this.node.classList.toggle("def");
////
vue.$emit("map-clicked", { mapId, title });
});
element.mouseover(function () {
mapId = this.node.attributes["map-id"].value;
title = this.node.attributes["title"].value;
this.node.classList.add("on");
// vue.$emit("map-over", { mapId, title });
});
element.mouseout(function () {
mapId = this.node.attributes["map-id"].value;
title = this.node.attributes["title"].value;
this.node.classList.remove("on");
// vue.$emit("map-over", { mapId, title });
});
},
},
};
</script>
<style>
path {
fill: #adaf93;
stroke: white;
}
path.on {
fill: rgb(221, 221, 103);
stroke: rgb(128, 98, 16);
}
path.abc {
fill: rgb(47, 80, 48);
stroke: rgb(25, 100, 71);
}
path.abc.on {
fill: rgb(102, 182, 104);
stroke: rgb(25, 100, 71);
}
path.def {
fill: rgb(22, 36, 156);
stroke: rgb(25, 100, 71);
}
path.def.on {
fill: rgb(94, 92, 216);
stroke: rgb(25, 100, 71);
}
</style>
Of course, I did it right after posting! The arrow function was the way to go, if anyone else needs it,
element.click(() => {
mapId = element.node.attributes["map-id"].value;
title = element.node.attributes["title"].value;
// need a way to set string from prop value
element.node.classList.toggle(this.pickColour);
});

How to use a camera stream multiple times

I want to create a PWA which acts as a bar- and QR-code scanner. For detecting QR-codes I use jsQR (see: https://github.com/cozmo/jsQR), for barcodes, I want to use QuaggaJS (see: https://serratus.github.io/quaggaJS/). To select the type of code that should be detected, I have some radio buttons on my site, which call the function "triggerScannerInitialisation()" (see below). Scanning QR-codes is working already, but scanning barcodes causes some problems. The camera image is not loaded properly. If I run the same code on testing site that only uses QuaggaJS, scanning barcodes works as it should do. I assume that opening two camera streams from the same camera may cause a problem. Can anyone give me a hint on how to use both with the same camera stream?
// variables for stopping scanner types on next run
let stopJsQrOnNextRun = true;
function triggerScannerInitialisation() {
// get the selected code type
let codeTypeSelector = document.querySelector('input[name="code_type_selector"]:checked').value;
switch (codeTypeSelector) {
case 'barcode':
stopJsQrOnNextRun = true;
startQuaggaJs();
break;
case 'qr':
stopQuaggaJs();
stopJsQrOnNextRun = false;
startJsQr();
break;
default:
return false;
}
}
function startQuaggaJs() {
document.getElementById("barcode_camera_div").hidden = false;
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
target: document.querySelector('#barcode_camera_div'),
constraints: {
width: 480,
height: 320,
facingMode: "environment"
},
},
decoder: {
readers: [
"code_128_reader",
"ean_reader",
"ean_8_reader",
"code_39_reader",
"code_39_vin_reader",
"codabar_reader",
"upc_reader",
"upc_e_reader",
"i2of5_reader"
],
debug: {
showCanvas: true,
showPatches: true,
showFoundPatches: true,
showSkeleton: true,
showLabels: true,
showPatchLabels: true,
showRemainingPatchLabels: true,
boxFromPatches: {
showTransformed: true,
showTransformedBox: true,
showBB: true
}
}
},
}, function (err) {
if (err) {
console.log(err);
return
}
console.log("Initialization finished. Ready to start");
Quagga.start();
});
Quagga.onProcessed(function (result) {
var drawingCtx = Quagga.canvas.ctx.overlay,
drawingCanvas = Quagga.canvas.dom.overlay;
if (result) {
if (result.boxes) {
drawingCtx.clearRect(0, 0, parseInt(drawingCanvas.getAttribute("width")), parseInt(drawingCanvas.getAttribute("height")));
result.boxes.filter(function (box) {
return box !== result.box;
}).forEach(function (box) {
Quagga.ImageDebug.drawPath(box, { x: 0, y: 1 }, drawingCtx, { color: "green", lineWidth: 2 });
});
}
if (result.box) {
Quagga.ImageDebug.drawPath(result.box, { x: 0, y: 1 }, drawingCtx, { color: "#00F", lineWidth: 2 });
}
if (result.codeResult && result.codeResult.code) {
Quagga.ImageDebug.drawPath(result.line, { x: 'x', y: 'y' }, drawingCtx, { color: 'red', lineWidth: 3 });
}
}
});
Quagga.onDetected(function (result) {
console.log("Barcode detected and processed : [" + result.codeResult.code + "]", result);
});
}
function stopQuaggaJs() {
// stop quagga JS
Quagga.stop();
document.getElementById("barcode_camera_div").hidden = true;
}
function startJsQr() {
let video = document.createElement("video");
let canvasElement = document.getElementById("canvas");
let canvas = canvasElement.getContext("2d");
let loadingMessage = document.getElementById("loadingMessage");
function drawLine(begin, end, color) {
canvas.beginPath();
canvas.moveTo(begin.x, begin.y);
canvas.lineTo(end.x, end.y);
canvas.lineWidth = 4;
canvas.strokeStyle = color;
canvas.stroke();
}
// Use facingMode: environment to attemt to get the front camera on phones
navigator.mediaDevices.getUserMedia({video: {facingMode: "environment"}}).then(function (stream) {
video.srcObject = stream;
video.setAttribute("playsinline", true); // required to tell iOS safari we don't want fullscreen
video.play();
console.log("JSQR triggered");
requestAnimationFrame(tickQRcode);
});
function tickQRcode() {
loadingMessage.innerText = "⌛ Video laden...";
if (video.readyState === video.HAVE_ENOUGH_DATA) {
loadingMessage.hidden = true;
canvasElement.hidden = false;
canvasElement.height = video.videoHeight;
canvasElement.width = video.videoWidth;
canvas.drawImage(video, 0, 0, canvasElement.width, canvasElement.height);
let imageData = canvas.getImageData(0, 0, canvasElement.width, canvasElement.height);
let code = jsQR(imageData.data, imageData.width, imageData.height, {
inversionAttempts: "dontInvert",
});
if (code) {
drawLine(code.location.topLeftCorner, code.location.topRightCorner, "#FF3B58");
drawLine(code.location.topRightCorner, code.location.bottomRightCorner, "#FF3B58");
drawLine(code.location.bottomRightCorner, code.location.bottomLeftCorner, "#FF3B58");
drawLine(code.location.bottomLeftCorner, code.location.topLeftCorner, "#FF3B58");
codeFound(code.data, 'qr');
}
}
if (!stopJsQrOnNextRun) {
requestAnimationFrame(tickQRcode);
} else {
stopJsQr();
}
}
function stopJsQr() {
// stop the stream
video.srcObject.getTracks().forEach(function (track) {
if (track.readyState === 'live') {
track.stop();
}
});
// remove HTML element properties
let canvasElement = document.getElementById('canvas');
canvasElement.setAttribute('hidden', 1);
canvasElement.removeAttribute('height');
canvasElement.removeAttribute('width');
}
}
Thank you for your help!

Why did my JSPdf npm package break my app without any updates?

I am using vue.js and jspdf to generate pdf. without updating the jspdf package my app broke.
I uninstalled the package as a workaround however, can't seem to figure what about this package broke the app.
Here is the error:
Uncaught TypeError: this.thenCore is not a function
at Promise.y.then (webpack-internal:///./node_modules/jspdf/dist/jspdf.min.js:123)
at Promise.<anonymous> (adrum-latest.js:29)
at Promise.catch (<anonymous>)
at z (webpack-internal:///./node_modules/vue-analytics/dist/vue-analytics.js:1)
at S (webpack-internal:///./node_modules/vue-analytics/dist/vue-analytics.js:1)
at Function.Vue.use (webpack-internal:///./node_modules/vue/dist/vue.esm.js:5102)
at eval (webpack-internal:///./src/main.js:53)
at Module../src/main.js (app.js:21185)
at __webpack_require__ (app.js:767)
at fn (app.js:130)
Vue component below that contains jspdf code
<template><!--download href="`${filePath}`"-->
<a class="export-card" #click="downloadImage()">
<span class="export-card-image"><font-awesome-icon :icon="[iconWeight, icon]"/></span>
<span class="export-card-type">{{cardText}}</span>
</a>
</template>
<script>
import htmlToImage from 'html-to-image';
import download from 'downloadjs';
import printJS from 'print-js';
import jsPDF from 'jspdf';
import {mapActions,mapState} from 'vuex';
export default {
name: 'ExportCard',
props: {
icon: String,
iconWeight: String,
cardText: String,
filePath: String,
},
computed: mapState({
selectedMediaType: state => state.brandBuilderEditor.selectedMediaType,
selectedImage: state => state.brandBuilderEditor.selectedImage,
selectedDesign: state => state.brandBuilderEditor.selectedDesign,
state: state => state,
}),
methods: {
...mapActions([
'toggleLoader'
]),
uploadFile(file) {
const url = 'https://api.cloudinary.com/v1_1/uwm/upload';
const xhr = new XMLHttpRequest();
const fd = new FormData();
xhr.open('POST', url, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
// Reset the upload progress bar
/*
document.getElementById('progress').style.width = 0;
*/
// Update progress (can be used to show progress indicator)
xhr.upload.addEventListener('progress', (e) => {
/* var progress = Math.round((e.loaded * 100.0) / e.total);
document.getElementById('progress').style.width = progress + "%"; */
console.log(`fileuploadprogress data.loaded: ${e.loaded},
data.total: ${e.total}`);
});
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
// File uploaded successfully
const response = JSON.parse(xhr.responseText);
console.log('response', response);
download(`https://res.cloudinary.com/uwm/video/upload/eo_10,o_50,l_${response.public_id.replace('/', ':')},so_0/v1566662844/videos/missworld.mp4`, 'my-video.mp4');
}
};
fd.append('upload_preset', 'jlw-test');
fd.append('tags', 'browser_upload'); // Optional - add tag for image admin in Cloudinary
fd.append('file', file);
xhr.send(fd);
},
getFileName() {
let mediaType = '';
switch (this.selectedMediaType) {
case 1:
mediaType = 'flyer';
break;
case 2:
mediaType = 'social-banner';
break;
case 3:
mediaType = 'video';
break;
case 4:
mediaType = 'presentation';
break;
case 6:
mediaType = 'pricing';
break;
default:
mediaType = 'flyer';
}
return `my-${mediaType}`;
},
downloadImage() {
// Only allow the loader and scaling of the template if the export type is not email.
if(this.cardText !== 'Send to Contact') {
this.toggleLoader();
// This allows the Title card scale to be a scale of 1 instead of the viewport size.
document.getElementById('item-container').classList.add('fullscale');
}
// create the target item for the scale check
const targetScale = document.getElementById('item-container');
// Set the target check to an interval
const interval = setInterval(scaleTemplateCheck, 250);
let fileName = this.getFileName();
const _this = this;
function scaleTemplateCheck() {
// This gets the current scale of the title card.
const compStyle = window.getComputedStyle(targetScale);
const transformValue = compStyle.getPropertyValue('transform');
// If the interval does not produce the scale of 1 result redo the interval and once the scale of 1 is confirmed proceed to the htmlToImage checks
if(transformValue !== 'matrix(1, 0, 0, 1, 0, 0)') {
return;
}
clearInterval(interval);
// Checks the scale for the various export types
if (_this.cardText === '.PNG') {
htmlToImage.toPng(document.getElementById('item-container'), { backgroundColor: '#fff', quality: 1 })
.then((dataUrl) => {
download(dataUrl, `${fileName}.png`);
if (_this.selectedMediaType !== 2) {
// This allows the Title card scale to be a scale of 1 instead of the viewport size.
document.getElementById('item-container').classList.remove('fullscale');
} _this.toggleLoader();
});
} else if (_this.cardText === '.JPG') {
htmlToImage.toJpeg(document.getElementById('item-container'), { backgroundColor: '#fff', quality: 1 })
.then((dataUrl) => {
download(dataUrl, `${fileName}.jpg`);
if (_this.selectedMediaType !== 2) {
document.getElementById('item-container').classList.remove('fullscale');
} _this.toggleLoader();
});
} else if (_this.cardText === '.mp4') {
htmlToImage.toPng(document.getElementById('item-container'), { backgroundColor: '#fff', quality: 1 })
.then((dataUrl) => {
_this.uploadFile(dataUrl);
});
} else if (_this.cardText === '.PDF') {
const filename = `${fileName}.pdf`;
htmlToImage.toJpeg(document.getElementById('item-container'), { backgroundColor: '#fff', quality: 1 })
.then((canvas) => {
// eslint-disable-next-line new-cap
const pdf = new jsPDF('p', 'mm', 'letter');
if (_this.selectedMediaType === 1 || _this.selectedMediaType === 6) {
pdf.addImage(canvas, 'JPEG', 8, 8, 200, 258);
} else if ((_this.selectedMediaType === 2)) {
pdf.addImage(canvas, 'JPEG', 8, 8, 200, 200);
}
pdf.save(filename);
if (_this.selectedMediaType !== 2) {
document.getElementById('item-container').classList.remove('fullscale');
}
_this.toggleLoader();
});
} else if (_this.cardText === 'Print') {
htmlToImage.toJpeg(document.getElementById('item-container'), { backgroundColor: '#fff' })
.then((dataUrl) => {
console.log('dataUrl', dataUrl)
function VoucherSourcetoPrint(source) {
return "<html><head><script>function step1(){\n" +
"setTimeout('step2()', 10);}\n" +
"function step2(){window.print();window.close()}\n" +
"</scri" + "pt></head><body onload='step1()'>\n" +
"<img src='" + source + "' style='max-width:100%'/></body></html>";
}
const Pagelink = "about:blank";
const pwa = window.open(Pagelink, "_new");
pwa.document.open();
pwa.document.write(VoucherSourcetoPrint(dataUrl));
pwa.document.close();
if (_this.selectedMediaType !== 2) {
document.getElementById('item-container').classList.remove('fullscale');
}
_this.toggleLoader();
});
} else if (_this.cardText === 'Download') {
window.open(_this.selectedDesign.item.medias[0].uri);
}
}// end of if statement
},
},
};
</script>
<style lang="scss" scoped>
.export-card {
display: flex;
flex-direction: column;
align-items: center;
background-color: $off-white;
border-radius: $b360-border-radius-base;
border: $b360-border-width-thin $border-color-light solid;
#include rem('padding', 19px 0px 18px);
text-decoration: none;
box-shadow: none;
transition: $b360-motion-selection;
cursor: pointer;
&:hover {
border-color: $b360-color--gray__medium;
box-shadow: 0 0 6px $shadow-color;
}
}
.export-card-image {
#include rem('font-size', 30px);
color: $brand-teal;
line-height: 0;
}
.export-card-type {
font-size: $b360-font-size--base;
line-height: 1;
#include rem('margin-top', 15px);
color: $text-base-color;
}
</style>
I think you getting the error because you instrumented appdynamic to your application. You can comment-out appdynamics configuration and your application should be run. I noticed that appdynamics do deep monitoring in libraries, so it will pick up all silly methods and implementation functions.
I don't know why the app broke, however it seems that you're using jsPDF to create a PDF with an image.
Since you're already using Cloudinary, why not use it to transform the image to PDF?
This is an image - https://res.cloudinary.com/demo/sample
This is how you turn it into a PDF - https://res.cloudinary.com/demo/sample.pdf
This is with transformations - https://res.cloudinary.com/demo/c_crop,w_400,g_auto/sample.pdf
If you are getting following error, It is due to appdynamic.
To fix this issue, add following configuration to your appdynamic code.
<script charset="UTF-8" type="text/javascript">
window["adrum-start-time"] = new Date().getTime();
(function (config) {
config.appKey = "YOUR-KEY";
...
config.spa = {"spa2": true};
config.isZonePromise = true;
})(window["adrum-config"] || (window["adrum-config"] = {}));
</script>

Categories

Resources