Occurrences and Arrays positions - javascript

Lets say I have this arrays:
likes = [4,6,42,72,7,4,42,56,6,24];
time = [1,2,3,4,5,6,7,8,9,10];
And when clicking in one of the bar charts I have, I'm forwarded to the current time, according to the array likes position.
this.click(function () {
var pos = result_likes.indexOf(this.bar.value);
var pos2 = result_time[pos];
setCurTime(pos2);
});
However when I have the same likes values, for instance number 4, there will be two positions of it, and the SetCurTime, will only forward me to the first time when "like=4 appears (timecode[0];)
How can I solve this and be forward to the right time position?

You need to embed meta data in the bar elements to solve this problem. For instance, you can use custom data attributes like such:
<div class="bar" data-index"5">4</div>
You would dynamically generate this of course, to create each bar with the proper index and value.
Then in your click handler would be:
this.click(function () {
var pos = this.bar.dataset.index;
var pos2 = result_time[pos];
setCurTime(pos2);
});

In light of you using the gRaphael library, perhaps you could crawl the bar elements to see which element it is within the chart, like this:
this.click(function(evt) {
var pos = 0;
var child = evt.currentTarget;
var type = child.nodeName;
while( (child = child.previousSibling) != null && type === child.nodeName)
pos++;
var pos2 = result_time[pos];
setCurTime(pos2);
});

Reposting comment here for any others who need a simliar solution:
var pos2 = result_time[this.bar.id];

Related

Method push is not adding a value to a vector that previously had the same value

The goal of the code I'm going to present is to create a aux vector that will contain petri nets transitions, arcs and places. I'm dividing a petri net into several groups, each group is a transition with respective input arcs and places.
The issue is the following: After I put the info in the first position of the aux vector, I'm unable to put a place with the same id of the place of the previous group. For example, if I have a transition with place_id=1 and place_id=2, and the next transition have place_id=2 and place_id=3, the code doesn't write the value place_i=2 in the vector for the second group.
function conflict() {
var id = [];
var source = [];
var target = [];
var aux = [];
var cont = [];
var places = pnml.getElementsByTagName("place");
var arcs = pnml.getElementsByTagName("arc");
var transitions = pnml.getElementsByTagName("transition");
for (var i = 0; i < transitions.length; i++) {
target.push(transitions[i].getAttribute("id"));
aux.push([]);
for (var j = 0; j < arcs.length; j++) {
if (arcs[j].getAttribute("target") == transitions[i].getAttribute("id")) {
id.push(arcs[j].getAttribute("id"));
source.push(arcs[j].getAttribute("source"));
//console.log(arcs[j].getAttribute( "source" ));
}
}
//console.log(id);
//console.log(arcs);
//console.log(places);
aux[i].push(id, source, target);
//id.length=0;
target = [];
source = [];
id = [];
}
}
Image of the platform with console open
Thanks in advance
Without knowing a whole lot for the issue, try to change this
aux.push([]);
to this
aux[i]=[];
So that you initialize and fill using an index instead of a push and an index later, for consistency.
Let me know if it helps
EDIT:
Also this
aux[i].push(id, source, target);
to this (maybe? )
aux[i].push({ id: id, source:source, target:target});
You probably want to keep objects in aux, so you need to push an object, not 3 parameters like that

How to left align objects in a group

I am new to fabric js. i am trying to left align all the objects in a group by using this function.
$rootScope.alignLeft = function () {
var activeObject = canvas.pages[canvas.activePageIndex].fabric.getActiveObject();
if (activeObject.type == "group") {
var items = activeObject._objects;
var left = activeObject.getLeft();
var top = activeObject.getTop();
console.log(activeObject);
canvas.pages[canvas.activePageIndex].fabric.remove(activeObject);
console.log(left);
console.log(top);
for (var i = 0; i < items.length; i++) {
canvas.pages[canvas.activePageIndex].fabric.add(items[i].set({left: activeObject.left}));
}
canvas.pages[canvas.activePageIndex].fabric.renderAll();
}
};
The problems that i am facing are
1)if i dont use .remove(activeGroup) it makes a duplicate of the objects in the group. I want to keep the activeGroup and somehow stop it from duplicating itself.
2) The items[i].set({left : activeObject.left} correctly sets the left alignment but the objects top value changes and i don't want that. i have tried to use items[i].set({left : activeObject.left,top:activeObject.top}); but failed to keep it constant.
How can i achieve this functionality?
How i was able to solve these problems. I am sure future newbie's to fabricjs like me will face these basic conceptual problems just like me.
Answers to points 1&2:
1) I used .remove(activeGroup) to remove it and made a new group and added items inside activeGroup into group.
2) Here are some links that really helped me understand the positioning system used in fabricjs stackOverflow link Github link
$rootScope.alignLeft = function(){
var activeObject = canvas.pages[canvas.activePageIndex].fabric.getActiveObject();
var group = new fabric.Group();
if(activeObject.type=="group"){
var items = activeObject._objects;
canvas.pages[canvas.activePageIndex].fabric.remove(activeObject);
for(var i = 0;i<items.length;i++){
var ObjTop = activeObject.top + items[i].top + activeObject.height/2 ;
items[i].set({left :activeObject.left,top:ObjTop});
group.addWithUpdate(activeObject.item(i));
}
canvas.pages[canvas.activePageIndex].fabric.add(group);
canvas.pages[canvas.activePageIndex].fabric.setActiveObject(group);
canvas.pages[canvas.activePageIndex].fabric.renderAll();
}
}

storing local variable then re-running function?

So I'm making an app that, in a nut shell, takes dimensions from the user and spits out the surface area but it's quickly becoming really repetitive.
function calc() {
var dim1main = +document.getElementById("dim1main").value || 0;
var dim2main = +document.getElementById("dim2main").value || 0;
var mainSurA = dim1main * dim2main;
var dim1mainD1 = +document.getElementById("dim1mainD1").value || 0;
var dim2mainD1 = +document.getElementById("dim2mainD1").value || 0;
var mainD1SurA = dim1mainD1 * dim2mainD1;
// ...
var dim1mainD6 = ...
// ...
var totalSurA = mainSurA + mainD1SurA ... + mainD6SurA;
}
So the idea was to have hundreds of text inputs hidden until the user wanted them and everything that was left empty would run through as zero, therefor not messing with the total. I think I'm safe in assuming this is horrible javascript.
I've been looking for a way to run a function multiple times and store each local variable somewhere for later use. I've played with arrays by deleting the input values onClick but each time I run the function with .push it replaces the first value with the second. I've read about localStorage but I'm not sure that's what I'm looking for. Any suggestions? Sorry if this is too vague.
I have read about storing data in objects as well as global variables but I've heard that gets messy.
One way you can do this is instead of hiding many elements you can dynamically create new input elements when needed. You can give your elements a specific class which you can use to get it via a HTMLCollection and compute the total dimension.
For example:
document.getElementById('add').onclick = function()
{
var container = document.getElementById('container');
var subContainer = document.createElement("div");
var dim1 = document.createElement("input");
var dim2 = document.createElement("input");
dim1.className = "dim1";
dim2.className = "dim2";
dim1.value = dim2.value = 0;
subContainer.className = "sub-container";
subContainer.appendChild(dim1);
subContainer.appendChild(dim2);
container.appendChild(subContainer);
}
document.getElementById('calc').onclick = function()
{
var arrayDim1 = document.getElementsByClassName('dim1');
var arrayDim2 = document.getElementsByClassName('dim2');
var totalSurA = 0;
for (var i = 0; i < arrayDim1.length; i++) {
totalSurA += +arrayDim1[i].value * +arrayDim2[i].value;
}
console.log(totalSurA);
}
<div id="container"></div>
<button id="add">Add Dimension</button>
<button id="calc">Calculate</button>
For storing past page sessions you can use localStorage as you said. I would in JavaScript as a 2D array of each row item (or you can use an array of objects with a property for dim1/dim2), like so:
[
[dim1_0, dim2_0],
[dim1_1, dim2_1],
...
]
Although before saving it to local storage you need it in a text format, which you can convert it to using JSON.stringify()

Load SVG from file to canvas and ungroup it

I upload an SVG file to a canvas using FabricJS with the function
fabric.loadSVGFromURL (url, function(objects, options){
group = fabric.util.groupSVGElements(objects, options);
canvas.add(group).centerObject(group).renderAll();
});
This works perfectly. However the next step I want do is to ungroup the recently added group. The reason why I need to ungroup is that I want to be able to select the group's child elements by clicking on them since there is no access to these elements if they are grouped.
I found a snippet to perform an ungroup however when I do it with the group created width groupSVGElements the elements lose their original position scrambling the whole svg that I loaded.
Does anyone knows how to ungroup a loaded SVG and still keep the original positions of the elements?
You can still access each of the element using perPixelTargetFind
When set to true, objects are "found" on canvas on per-pixel basis rather than according to
bounding box.
I'm looking for the same solution. Did you find an answer so far?
Looking at the structure of an SVG element, I would image it should be possible to write a recursive method, which gives the children, the properties of the group and places them one level up. If you keep doing this, you should end up with all groups exploded and all properties intact (which are inherited otherwise).
Looking at SVG-EDIT, there is a function which should do this:
Function: ungroupSelectedElement
// Unwraps all the elements in a selected group (g) element. This requires
// significant recalculations to apply group's transforms, etc to its children
this.ungroupSelectedElement = function() {
var g = selectedElements[0];
if (!g) {
return;
}
if ($(g).data('gsvg') || $(g).data('symbol')) {
// Is svg, so actually convert to group
convertToGroup(g);
return;
}
if (g.tagName === 'use') {
// Somehow doesn't have data set, so retrieve
var symbol = svgedit.utilities.getElem(getHref(g).substr(1));
$(g).data('symbol', symbol).data('ref', symbol);
convertToGroup(g);
return;
}
var parents_a = $(g).parents('a');
if (parents_a.length) {
g = parents_a[0];
}
// Look for parent "a"
if (g.tagName === 'g' || g.tagName === 'a') {
var batchCmd = new svgedit.history.BatchCommand('Ungroup Elements');
var cmd = pushGroupProperties(g, true);
if (cmd) {batchCmd.addSubCommand(cmd);}
var parent = g.parentNode;
var anchor = g.nextSibling;
var children = new Array(g.childNodes.length);
var i = 0;
while (g.firstChild) {
var elem = g.firstChild;
var oldNextSibling = elem.nextSibling;
var oldParent = elem.parentNode;
// Remove child title elements
if (elem.tagName === 'title') {
var nextSibling = elem.nextSibling;
batchCmd.addSubCommand(new svgedit.history.RemoveElementCommand(elem, nextSibling, oldParent));
oldParent.removeChild(elem);
continue;
}
children[i++] = elem = parent.insertBefore(elem, anchor);
batchCmd.addSubCommand(new svgedit.history.MoveElementCommand(elem, oldNextSibling, oldParent));
}
// remove the group from the selection
clearSelection();
// delete the group element (but make undo-able)
var gNextSibling = g.nextSibling;
g = parent.removeChild(g);
batchCmd.addSubCommand(new svgedit.history.RemoveElementCommand(g, gNextSibling, parent));
if (!batchCmd.isEmpty()) {addCommandToHistory(batchCmd);}
// update selection
addToSelection(children);
}
};
See also:
https://code.google.com/p/svg-edit/source/browse/trunk/editor/svgcanvas.js

Find Index of Column(s) after it has been Moved

We are using DHTMLX Grid. Need some help, please.
I have a table and each columns (has filter/dropdown) are allocated an id eg. fac, date, sel, loc, tag ... etc
We have hard coded the index of columns to set and get the cookie elsewhere.
function doInitGrid(){
mygrid.setColumnIds("fac,date,sel,loc,tag"); //set ids
mygrid.attachEvent("onFilterStart",function(ind,data)
{
setCookie("Tray_fac_filter",mygrid.getFilterElement(0).value,365); //column index 0
setCookie("Tray_loc_filter",mygrid.getFilterElement(3).value,365);//column index 3
setCookie("Tray_tag_filter",mygrid.getFilterElement(4).value,365); //column index 4
mygrid.getFilterElement(0).value = getCookie("Tray_fac_filter")
mygrid.getFilterElement(3).value = getCookie("Tray_dep_filter")
mygrid.getFilterElement(4).value = getCookie("Tray_prg_filter")
});
}
But when the columns are moved, the problem arises as the index of the column changes yet it is set in setCookie /getCoookie
DHTMLX allows to get the index of the id using --
var colInd = grid.getColIndexById(id);
eg: var colInd = grid.getColIndexById(date); // outputs 1.
After moving the date column to the end -- fac, sel, loc, tag, date // it will output 4.
However, we have about 14 columns that can be moved/rearranged and I could use the
var colInd = grid.getColIndexById(id); 15 times
var facInd = grid.getColIndexById("fac");
var dateInd = grid.getColIndexById("date");
var selInd = grid.getColIndexById("sel");
var locInd = grid.getColIndexById("loc";
var tagInd = grid.getColIndexById("tag");
and put those variables in the set/get cookie. I was thinking if there was a better way.
To understand the code better, I have put the minimised version of the code in fiddle.
http://jsfiddle.net/19eggs/s5myW/2/
You've got the best answer I think. Do it in a loop and it's easier:
var cookie_prefix = "Fray_filter_";
var cookie_dur = 365;
var num_cols = dhx_grid.getColumnCount();
// filter vals to cookies
for (var col_idx=0; col_idx<num_cols; col_idx++) {
var filter = mygrid.getFilterElement(col_idx)
if (filter) { // not all columns may have a filter
var col_id = dhx_grid.getColumnId(col_idx);
var cookie_name = cookie_prefix+col_id;
setCookie(cookie_name, filter.value, cookie_dur);
}
}
// cookies to filter vals
for (var col_idx=0; col_idx<num_cols; col_idx++) {
var col_id = dhx_grid.getColumnId(col_idx);
var filter_val = getCookie(cookie_prefix+col_id);
var filter = mygrid.getFilterElement(col_idx)
filter.value = filter_val;
}
You can use dhtmlxgrid native event to assign the correct id everytime a column is moved.
The event is called onAfterCMove, you can check the documentation here. onAfterCMove Event
You would do something like:
mygrid.attachEvent('onAfterCMove',function(cInd,posInd){
//Your processing here to change the cookies; where cInd is the index of the column moved
//and posInd, is the position where it Was moved
}):

Categories

Resources