I've got this script:
function testchartbuild() {
var sheet = SpreadsheetApp.getActiveSheet();
var chart = sheet.newChart()
.setChartType(Charts.ChartType.LINE)
.asLineChart()
.setOption("useFirstColumnAsDomain", false)
.addRange(sheet.getRange("BA24:BD231"))
.setNumHeaders(1)
.setPosition(5, 5, 0, 0)
.setOption("legend", {position: "bottom"})
.setOption("width", 690)
.setOption("height", 195)
.build();
// create an image from that EmbeddedChart
sheet.insertImage(chart.getBlob(),58,2); // this works
};
It currently works great to create a chart, and display it as an image on my sheet. I am doing it this way because I can't create a chart above a locked row. Each time I run the script, it creates a new image on top of the old image (if the script was run previously). I would like to edit the script so that it looks to see if another image is already there first, deletes it, then replaces it with the new chart image. I've been looking everywhere to find a way to delete the old image first but can't figure it out. Any help would be great! Thanks
In your situation, in order to remove the existing image with the anchor cell "BF2", how about the following modification?
From:
.build();
// create an image from that EmbeddedChart
sheet.insertImage(chart.getBlob(),58,2); // this works
To:
.build();
sheet.getImages().forEach(e => {
if (e.getAnchorCell().getA1Notation() == "BF2") {
e.remove();
}
});
// create an image from that EmbeddedChart
sheet.insertImage(chart.getBlob(),58,2); // this works
Note:
If you want to remove all existing images, please modify the above modification as follows.
sheet.getImages().forEach(e => e.remove());
References:
getImages()
remove()
Related
I've managed to upload images through drag & drop to a SP 2013 library by intercepting the paste and fileUploadrequest events (+ added mandatory headers and used /_api/web/getfolderbyserverrelativeurl(\'/sites/theSite/theLibrary\')/files/add(overwrite=true,%20url=\'aDynamicFilename.jpg\') as the request's URL).
The problem with this approach is that even if the image is uploaded, the image is not inserted in the editor (no error). I'm not setting config.uploadUrl for this approach.
Q#1: Is there any step which I should go through after the image is uploaded? Like telling the CKEDITOR instance to insert the image?
Later on, I've noticed that if I'm setting the config.uploadUrl to the same URL as I'm using above, the editor inserts successfully the image. The problem is that, from my trials, the config.uploadUrl is initialized together with the CKEDITOR instance (therefore, can't be assigned dynamically for each image, in case that multiple images are dragged and dropped on the editor).
Q#2: Is there another way to configure the uploadUrl or maybe some other config property that would allow the custom upload to work and insert the image in the editor?
Eventually made it work by following a similar approach as the on in this repo:
RyanSiu1995/ckeditor-ImageUploader
Use a FileReader and start loading the image when it's pasted to the
CKEditor
On the fileReader's onload event, create a img element in the
editor's document object with some opacity and with the fileReader's
Base64 string as the src
On the fileLoader's uploaded event, remove
the img and re-add it with the actual file's url (changing the src
attribute on the img was not triggering the editor's change event, which I was hooking into,so I chose to replace the whole element)
Here's the relevant section from the ckeditor-ImageUploader plugin:
fileDialog.on('change', function (e) {
var fileTools = CKEDITOR.fileTools,
uploadUrl = fileTools.getUploadUrl( editor.config, 'image' ),
file = e.target.files[0],
loader = editor.uploadRepository.create(file),
reader = new FileReader(),
notification,
img;
// verify
if (!/image/i.test(file.type)) {
notification = editor.showNotification( 'Please check the correct format.', 'warning' );
setTimeout(function() {
notification.hide()
}, 2000);
return false
}
loader.upload(uploadUrl);
// preview image
reader.readAsDataURL(e.target.files[0]);
reader.onload = function (e) {
img = editor.document.createElement('img');
img.setAttribute('src', e.target.result);
img.setStyle('opacity', 0.3);
editor.insertElement(img);
}
loader.on('uploaded', function(evt) {
editor.widgets.initOn(img, 'image', {
src: evt.sender.url
});
img.setAttribute('src', evt.sender.url);
img.setStyle('opacity', 1);
});
loader.on('error', function() {
img.$ && img.$.remove();
});
fileTools.bindNotifications(editor, loader);
// empty input
fileDialog[0].value = "";
I need to dynamically add groups of multiple groups of images to the canvas, these "multi-group" will react differently depending on which of he contained groups has been dragged over by another group. I need these multi-groups to be able to be selected, rotated and dragged around the screen.
Ive chosen to use FabricJS and create images using fabric.Image.fromURL, manipulate, then add them to the canvas in a callback function. To add multiple images to a group, you nest more images in cascading callback functions as shown in this tutorial
I cant find a way to get a reference to a group of images created this way so I can add another group of images. Declaring a variable before any calls to fabric.Image.fromURL and trying to assign a reference to a created image doesnt work. The only way Ive got something working is a horrible desparate hack of adding such a group to the canvas then setting it as the active object then creating a new group and adding that active object to the group, this is soooo wrong and I dont think it will work for 3 groups. Heres my last coding attempt;
fabric.Image.fromURL('images/icon_station.png', function(img) {
var img1 = img;
fabric.Image.fromURL('images/icon_curve.png', function(img) {
img.set({left: 64,top: 64,angle: -90});
var img2 = img;
fabric.Image.fromURL('images/icon_curve.png', function(img) {
var img3 = img;
var tile_loop = new fabric.Group([img1, img2, img3]);
tile_loop.set({left: 0, top: 0, height: 64, width: 64});
canvas.add(tile_loop).setActiveObject(tile_loop);
});
});
});
fabric.Image.fromURL('images/icon_station.png', function(img) {
img.set({left: 64,top: 64});
var img1 = img;
fabric.Image.fromURL('images/icon_straight.png', function(img) {
img.set({left: 64,top: 64});
var img2 = img;
fabric.Image.fromURL('images/icon_curve.png', function(img) {
img.set({left: 64,top: 64});
var img3 = img;
var tile_loop = new fabric.Group([img1,img2,img3,canvas.getActiveObject()]);
tile_loop.set({left: 128, top: 128, height: 128, width: 128});
canvas.add(tile_loop);
});
});
});
The only other way Ive seen is to load images into html tags and create them in fabric from the tags, like this
var imgElement = document.getElementById('my-img');
var imgInstance = new fabric.Image(imgElement, {left: 100,top: 100});
canvas.add(imgInstance);
but that seems like a last resort work around, I would prefer to load images up directly in fabricjs.
Ive tried to do this in Phaser but it doesnt do groups of groups, Fabric has all the other stuff I need so I would like to stay with it, its a shame it does these weird ways of handling images.
Any help is much appreciated, if all else fails Ill use the last resort, it would be great to find a clever correct way.
I created an example in JSFiddle;
http://jsfiddle.net/d7bjbpfb/
Morning,
We have literally searched all over Stackoverflow and Google to find this solutions but still don't have the right answer.
We're trying to auto-set the Base, Small and Thumbnail options on the first uploaded image, so when uploading multiple images the first image will always have all three options checked.
If anyone has tried and succeeded with find this answer and advice, Thank you.
It is very easy. Example's here. Replace in root/js/mage/adminhtml/product.js in the end of handleUploadComplete around 120 row code
this.container.setHasChanges();
this.updateImages();
},
updateImages : function() {
with
this.container.setHasChanges();
this.updateImages();
$$('tr#media_gallery_content-image-1 td.cell-image.a-center input')[0].setAttribute('checked','checked');
$$('tr#media_gallery_content-image-1 td.cell-small_image.a-center input')[0].setAttribute('checked','checked');
$$('tr#media_gallery_content-image-1 td.cell-thumbnail.a-center input')[0].setAttribute('checked','checked');
},
updateImages : function() {
And enjoy autoselect first image after upload
If you have already uploaded your images and need to set the first one as thumb/base/small try the sql command in this post:
Just follow the instructions given by stereo_world and nhahtdh and then refresh your cache.
Thanks to Fabian and Doug for the groundwork. I just published an extension, which does exactly what you are trying to achieve in a clean way: https://github.com/customgento/CustomGento_AutoSelectImages
It simply adds a JS file on the admin product edit page. In the JS file, the mentioned method Product.Gallery.createImageRow is wrapped, so that the radio buttons can be selected after the first image has been uploaded. Here is the JS "magic":
if (typeof Product.Gallery !== 'undefined') {
Product.Gallery.prototype.createImageRow = Product.Gallery.prototype.createImageRow.wrap(function (parentMethod, image) {
// first call the parent method
parentMethod(image);
// auto-select the radio buttons for the first uploaded image
$H(this.imageTypes).each(function (pair) {
if (this.images.length === 1) {
this.getFileElement(image.file, 'cell-' + pair.key + ' input').checked = true;
}
}.bind(this));
this.setProductImages(image.file);
});
}
I would like to two show a Chart and also present an url with a link to a bigger Chart. The small preview-image looks and works fine:
<canvas id="image"></canvas>
var ct1 = document.getElementById("image").getContext("2d");
ct1.canvas.width = document.getElementById("image").offsetWidth;
ct1.canvas.height = document.getElementById("image").offsetHeight;
var Chart1 = new Chart(ct1).Line(lineChartData1,options);
The canvas is wrapped in a div, that's why offsetWidth and offsetHeight (to fill this additional div-element). Cause of the responsive-design there is no fixed image. Anyway, this works perfectly. For the URL to the "bigger" image I want to have the URL. I know the toDataURL() will help.
var url = document.getElementById("image").toDataURL();
document.write(url);
There are two disturbing problems with it:
The URL with this way exisists and, but the image has no content.
I also want to give the canvas-image a new size, like I managed with ct1.canvas.width and ct1.canvas.height, but it seems I cannot add this to the toDataURL.
What's wrong with the code?
Okay, I think I got it. Chart.js is animating the charts, so the toDataURL() I mentioned in my first question rendered only an empty image. We have to initiate the toDataURL, not before the animation is done. We handle that with the options:
var options = {
onAnimationComplete: done
}
and a tiny function:
function done() {
console.log('done');
var url=document.getElementById("canvas").toDataURL();
document.getElementById("canvas_link").href=url;
}
I think that's all.
Here is the problem :
I have a canvas, and four (would be more in future, but 4 for testing...anyway, doesn't matter) images that can be "poped" into the canvas by clicking on it.
Each image can be present multiple times in the canvas.
So far, poping is working fine, images are draggable... But I can't add some resize or zIndex function as I can only select the last image add to the canvas.
In a ideal world, I would like, by clicking/dragging an image, put it on top of the canvas, and kinda "select" it, so that I can connect the resize functions to the image.
But with the array of images, I can't manage to identify properly the item dragged, and can't use (or don't manage to use) the selectors.
Thank you.
EDIT : some code
var imgCpt = 0;
var image = [];
function addDetails(img) {
imgCpt++;
var imageObj = new Image();
imageObj.onload = function() {
image[imgCpt] = new Kinetic.Image({
x: 0,
y: 0,
image: imageObj,
draggable: true,
id:image[imgCpt]
});
image[imgCpt].setX((stage.getWidth()/2) - (image[imgCpt].getWidth()/2));
image[imgCpt].setY((stage.getHeight()/2) - (image[imgCpt].getHeight()/2));
eval(image[imgCpt]).on('click', function() {
alert(eval(imgCpt));
});
layer.add(image[imgCpt]);
stage.add(layer);
};
imageObj.src = 'uploads/'+img;
}
I've already tried different solutions : multiple layer, and acting on it instead of acting on image, working with shapes filled with image instead of image, but it's always the same problem : I can't get the id of the concerned element (instead of the id of the last insert element)
This version works with array, but I tried yersterday to build the image id with eval(); without more success.
Thank you for your help
EDIT² : sorry to insist, but I would really be glad to have some assistance on this point, even if I think it's more JS related than pure KineticJS related.
Thank you.
Ok Guys, just solved the problem :
eval("image["+imgCpt+"].on('click', function() {alert("+imgCpt+");});");
Instead of :
eval(image[imgCpt]).on('click', function() {
alert(eval(imgCpt));
});
Now time to set a true action behind the click.
Thank you for helping ;)