Fabric js Image Filters - fabricjs

Hello i am trying to create img filter there are Range input sliders from which user select filter value and then applied to selected image object its working but every time input changes it added a new filter and multiply how can i resolve this issue below is my code:
$('.img-fillter-controller .range-field').on("change", "input", function () {
t = $(this).data("filter");
v = $(this).val();
o = activeCanvas.getActiveObject();
switch(t) {
case 'brightness':
f = new fabric.Image.filters.Brightness({brightness: v/100 });
applyImgFilter(f);
return;
case 'saturation':
return;
case 'contrast':
return;
case 'blur':
return;
case 'exposure':
return;
case 'colorify':
return;
case 'hue':
}
});
function applyImgFilter(f) {
o.filters.push(f);
o.applyFilters();
activeCanvas.renderAll();
}

For apply filter properly on image, we need to fix filter index or can say that assign filter by static index.
You should replace This funciton :
function applyImgFilter(f) {
o.filters.push(f);
o.applyFilters();
activeCanvas.renderAll();
}
With New funciton :
function applyImgFilter(f) {
o.filters[0] = f
o.applyFilters();
activeCanvas.renderAll();
}

Related

Tabulator - How to set value inside cellEdited function

I am using the Tabulator plugin and am using the editorParams function to select from a list of options. If a value isn't selected (eg: Cancelled) I want it to revert to the old (previous) cell value and do nothing, but calling cell.setValue() keeps retriggering the cellEdit function and it gets stuck in a loop.
table.on('cellEdited', function(cell) {
var cellOldValue = cell.getOldValue();
var cellNewValue = cell.getValue();
var row = cell.getRow();
var index = row.getIndex();
if (cellNewValue == 'none-selected') {
cell.setValue(cellOldValue);
} else {
if (confirm('Are you sure?')) {
// ok, do something
} else {
cell.setValue(cellOldValue);
}
}
});
This just keeps triggering the prompt. Any solutions, thank you?

Cypress get text value from an element

I am trying to get a text from an element with Cypress in the first test from the first domain and then type it in the second test in another domain, here is a code
I have to grab code from h4.
I implemented next part of code:
get studentCouponValue() {
return cy.get('h4').then(($span) => {
const couponValue = $span.text();
cy.log(couponValue);
})
}
in logs, I see the correct coupon's value, but when I am trying to type it into the field I get an error
The chain approach doesn't fit my expectation, cause i am going to use it in different tests.
Try this:
get studentCouponValue() {
return cy.get('h4').then(($span) => {
const couponValue = $span.innerText;
cy.log(couponValue);
})
}
i resolved
initStudentCouponValue() {
const self = this;
return cy.get('main > .container-fluid').find('h4').then((span) => {
self.couponValue = span.text();
cy.log('First log '+ self.couponValue);
return new Cypress.Promise((resolve) => {
return resolve(self.couponValue);
});
});
}
getStudentCouponValue() {
return this.couponValue;
}
in the test where we want to use value
let couponValue;
admin.initStudentCouponValue().then(() => {
couponValue = admin.getStudentCouponValue()
});
and later we can use
coupoValue
for inputs

How do I download data trees to CSV?

How can I export nested tree data as a CSV file when using Tabulator? I tried using the table.download("csv","data.csv") function, however, only the top-level data rows are exported.
It looks like a custom file formatter or another option may be necessary to achieve this. It seems silly to re-write the CSV downloader, so while poking around the csv downloader in the download.js module, it looks like maybe adding a recursive function to the row parser upon finding a "_children" field might work.
I am having difficulty figuring out where to get started.
Ultimately, I need to have the parent-to-child relationship represented in the CSV data with a value in a parent ID field in the child rows (this field can be blank in the top-level parent rows because they have no parent). I think I would need to include an ID and ParentID in the data table to achieve this, and perhaps enforce the validation of that key using some additional functions as data is inserted into the table.
Below is currently how I am exporting nested data tables to CSV. This will insert a new column at the end to include a parent row identifier of your choice. It would be easy to take that out or make it conditional if you do not need it.
// Export CSV file to download
$("#export-csv").click(function(){
table.download(dataTreeCSVfileFormatter, "data.csv",{nested:true, nestedParentTitle:"Parent Name", nestedParentField:"name"});
});
// Modified CSV file formatter for nested data trees
// This is a copy of the CSV formatter in modules/download.js
// with additions to recursively loop through children arrays and add a Parent identifier column
// options: nested:true, nestedParentTitle:"Parent Name", nestedParentField:"name"
var dataTreeCSVfileFormatter = function(columns, data, options, setFileContents, config){
//columns - column definition array for table (with columns in current visible order);
//data - currently displayed table data
//options - the options object passed from the download function
//setFileContents - function to call to pass the formatted data to the downloader
var self = this,
titles = [],
fields = [],
delimiter = options && options.delimiter ? options.delimiter : ",",
nestedParentTitle = options && options.nestedParentTitle ? options.nestedParentTitle : "Parent",
nestedParentField = options && options.nestedParentField ? options.nestedParentField : "id",
fileContents,
output;
//build column headers
function parseSimpleTitles() {
columns.forEach(function (column) {
titles.push('"' + String(column.title).split('"').join('""') + '"');
fields.push(column.field);
});
if(options.nested) {
titles.push('"' + String(nestedParentTitle) + '"');
}
}
function parseColumnGroup(column, level) {
if (column.subGroups) {
column.subGroups.forEach(function (subGroup) {
parseColumnGroup(subGroup, level + 1);
});
} else {
titles.push('"' + String(column.title).split('"').join('""') + '"');
fields.push(column.definition.field);
}
}
if (config.columnGroups) {
console.warn("Download Warning - CSV downloader cannot process column groups");
columns.forEach(function (column) {
parseColumnGroup(column, 0);
});
} else {
parseSimpleTitles();
}
//generate header row
fileContents = [titles.join(delimiter)];
function parseRows(data,parentValue="") {
//generate each row of the table
data.forEach(function (row) {
var rowData = [];
fields.forEach(function (field) {
var value = self.getFieldValue(field, row);
switch (typeof value === "undefined" ? "undefined" : _typeof(value)) {
case "object":
value = JSON.stringify(value);
break;
case "undefined":
case "null":
value = "";
break;
default:
value = value;
}
//escape quotation marks
rowData.push('"' + String(value).split('"').join('""') + '"');
});
if(options.nested) {
rowData.push('"' + String(parentValue).split('"').join('""') + '"');
}
fileContents.push(rowData.join(delimiter));
if(options.nested) {
if(row._children) {
parseRows(row._children, self.getFieldValue(nestedParentField, row));
}
}
});
}
function parseGroup(group) {
if (group.subGroups) {
group.subGroups.forEach(function (subGroup) {
parseGroup(subGroup);
});
} else {
parseRows(group.rows);
}
}
if (config.columnCalcs) {
console.warn("Download Warning - CSV downloader cannot process column calculations");
data = data.data;
}
if (config.rowGroups) {
console.warn("Download Warning - CSV downloader cannot process row groups");
data.forEach(function (group) {
parseGroup(group);
});
} else {
parseRows(data);
}
output = fileContents.join("\n");
if (options.bom) {
output = "\uFEFF" + output;
}
setFileContents(output, "text/csv");
};
as of version 4.2 it is currently not possible to include tree data in downloads, this will be comming in a later release

How to check if cell if empty in Office.js

I have just started with Office Addins and I'm experimenting with the functionalities. I have several VBA Userforms that I would want to replace with popups from the Office add-in.
I am using the following code to enter a string into a cell(nothing fancy, I know) but I would want to check if the cell if empty before passing the value. If it is, enter (arg.message).
the problem I have encountered:
with if (range.value == "") the value is being set in "A4" even if "A3" if empty;
with if (range.value == " ") the value is not being entered in any cells.
Can anyone give me an example of how to check if a cell is empty?
I know it seems trivial but I have only found examples of how to check with col and row numbers for conditional formatting. I am trying to test all these functionalities to be able to start moving stuff from VBA to OfficeJS.
Thanks,
Mike
function processMessage(arg) {
console.log(arg.message);
$('#user-name').text(arg.message);
dialog.close();
Excel.run(function (context) {
var sheet = context.workbook.worksheets.getItem("Sheet1");
var range = sheet.getRange("A3");
if (range.value == "") {
range.values = (arg.message);
range.format.autofitColumns();
return context.sync();
} else {
range.getOffsetRange(1, 0).values = (arg.message)
return context.sync();
}
}).catch(errorHandler);
}
PS: the whole code in case there is something wrong somewhere else
(function () {
"use strict";
// The initialize function must be run each time a new page is loaded.
Office.initialize = function (reason) {
$(document).ready(function () {
// Add a click event handler for the button.
$('#popup-button').click(opensesame);
$('#simple-button').click(function () {
Office.context.document.getSelectedDataAsync(Office.CoercionType.Text,
function (result) {
if (result.status === Office.AsyncResultStatus.Succeeded) {
$("#banner-text").text('The selected text is: "' + result.value + '"');
$("#banner").show(result.value);
console.log()
} else {
$("#banner-text").text('Error: ' + result.error.message);
$("#banner").show();
}
});
});
$("#banner-close").click(function () { $("#banner").hide(); });
$("#banner").hide();
});
}
let dialog = null;
function opensesame() {
Office.context.ui.displayDialogAsync(
'https://localhost:3000/popup.html',
{ height: 35, width: 25 },
function (result) {
dialog = result.value;
dialog.addEventHandler(Microsoft.Office.WebExtension.EventType.DialogMessageReceived, processMessage);
}
);
}
function processMessage(arg) {
console.log(arg.message);
$('#user-name').text(arg.message);
dialog.close();
Excel.run(function (context) {
var sheet = context.workbook.worksheets.getItem("Sheet1");
var range = sheet.getRange("A3");
if (range.value == "") {
range.values = (arg.message);
range.format.autofitColumns();
return context.sync();
} else {
range.getOffsetRange(1, 0).values = (arg.message)
return context.sync();
}
}).catch(errorHandler);
}
})();
The Range object has a values property, but not a value property. So range.value in your condition test is undefined which does not match an empty string; hence the else clause runs.
A couple of other things:
Your condition tries to read a property of the range object. You have to load the property and call context.sync before you can read the property.
The value of the range.values property is a two-dimensional array (although it may have a single value in it if the range is a single cell). It is not a string, so comparing it with an empty string will always be false.
If I understand your goal, I think you should be testing with whether range.values (after you load it and sync) has an empty string in it's only cell. For example, if (range.values[0][0] === ""). Even better from a performance standpoint is to load the range.valueTypes property (and sync) and then compare like this: if (range.valueTypes[0][0] === Excel.RangeValueType.empty).

How to get web element (id) from the element position in D3.js force graph

I am working with the D3.js force graph but I am not able to find out the element id from the element position (which I know).
I am using Leap motion. I need to simulate a mouse event (a click, a move, a drag, etc.) without a mouse. And, if I am right, in order to be able to do this, I need to find out what is the the element id from the coordinates x and y (these coordinates I know from the Leap motion pointer). So from what you wrote above, I need to find out the ('.node’).
Here is what I already tried but it did not work:
Is it possible to use non-mouse, non-touch events to interact with a D3.js graph? If so, what is the most efficient way to go about it?
So I used this function (see below), but I need to know the element id to make it work correctly:
//graph.simulate(document.getElementById("r_1"), 'dblclick', {pointerX: posX, pointerY: posY});
//here id r_1 is hardcoded, but I need to find out id from x and y coordinates.
this.simulate = function (element, eventName) {
function extend(destination, source) {
for (var property in source)
destination[property] = source[property];
return destination;
}
var eventMatchers = {
'HTMLEvents': /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,
'MouseEvents': /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/
};
var defaultOptions = {
pointerX: 0,
pointerY: 0,
button: 0,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
bubbles: true,
cancelable: true
};
var options = extend(defaultOptions, arguments[2] || {});
var oEvent, eventType = null;
for (var name in eventMatchers) {
if (eventMatchers[name].test(eventName)) {
eventType = name;
break;
}
}
if (!eventType)
throw new SyntaxError('Only HTMLEvents and MouseEvents interfaces are supported');
if (document.createEvent) {
oEvent = document.createEvent(eventType);
if (eventType == 'HTMLEvents') {
oEvent.initEvent(eventName, options.bubbles, options.cancelable);
}
else {
oEvent.initMouseEvent(eventName, options.bubbles, options.cancelable, document.defaultView,
options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY,
options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element);
}
element.dispatchEvent(oEvent);
}
else {
options.clientX = options.pointerX;
options.clientY = options.pointerY;
var evt = document.createEventObject();
oEvent = extend(evt, options);
element.fireEvent('on' + eventName, oEvent);
}
return element;
}
Many thanks for your help and ideas.
If you want access to the element, it's implicit in D3's iterators via this.
d3.selectAll('.node').each(function(d) {
console.log(this); // Logs the element attached to d.
});
If you really need access to the id, you can get it with selection.attr():
d3.selectAll('.node').each(function() {
console.log(d3.select(this).attr('id')); // Logs the id attribute.
});
You don't have to use each. Any of the iterators, such as attr or style, etc., have 'this' as the bound element:
d3.selectAll('.node').style('opacity', function(d) {
console.log(this);// Logs the element attached to d.
});
If you want the x and y coordinates of a node, it's part of the data:
d3.selectAll('.node').each(function(d) {
console.log(d.x, d.y); // Logs the x and y position of the datum.
});
If you really need the node attributes themselves, you can use the attr accessor.
d3.selectAll('.node').each(function(d) {
// Logs the cx and cy attributes of a node.
console.log(d3.select(this).attr('cx'), d3.select(this).attr('cy'));
});
EDIT: It looks like you need an element reference, but the only thing you know about the node in context is its position. One solution is to search through all nodes for a node with matching coordinates.
// Brute force search of all nodes.
function search(root, x, y) {
var found;
function recurse(node) {
if (node.x === x && node.y === y)
found = node;
!found && node.children && node.children.forEach(function(child) {
recurse(child);
});
}
recurse(root);
return found;
}
However this only gives you the node object, not the element itself. You will likely need to store the element references on the nodes:
// Give each node a reference to its dom element.
d3.selectAll('.node').each(function(d) {
d.element = this;
});
With that in place, you should be able to access the element and get its id.
var id, node = search(root, x, y);
if (node) {
id = node.element.getAttribute('id');
}
The brute-force search is fine for a small number of nodes, but if you're pushing a large number of nodes you might want to use D3's quadtree (example) to speed up the search.
Use d3.select('#yourElementId')
For more info check this out: https://github.com/mbostock/d3/wiki/Selections

Resources