7604 |
25 Feb 19 |
nicklas |
/* $Id $ |
7604 |
25 Feb 19 |
nicklas |
2 |
------------------------------------------------------------------ |
7604 |
25 Feb 19 |
nicklas |
Copyright (C) 2010 Nicklas Nordborg |
7604 |
25 Feb 19 |
nicklas |
4 |
|
7604 |
25 Feb 19 |
nicklas |
This file is part of BASE - BioArray Software Environment. |
7604 |
25 Feb 19 |
nicklas |
Available at http://base.thep.lu.se/ |
7604 |
25 Feb 19 |
nicklas |
7 |
|
7604 |
25 Feb 19 |
nicklas |
BASE is free software; you can redistribute it and/or |
7604 |
25 Feb 19 |
nicklas |
modify it under the terms of the GNU General Public License |
7604 |
25 Feb 19 |
nicklas |
as published by the Free Software Foundation; either version 3 |
7604 |
25 Feb 19 |
nicklas |
of the License, or (at your option) any later version. |
7604 |
25 Feb 19 |
nicklas |
12 |
|
7604 |
25 Feb 19 |
nicklas |
BASE is distributed in the hope that it will be useful, |
7604 |
25 Feb 19 |
nicklas |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
7604 |
25 Feb 19 |
nicklas |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
7604 |
25 Feb 19 |
nicklas |
GNU General Public License for more details. |
7604 |
25 Feb 19 |
nicklas |
17 |
|
7604 |
25 Feb 19 |
nicklas |
You should have received a copy of the GNU General Public License |
7604 |
25 Feb 19 |
nicklas |
along with BASE. If not, see <http://www.gnu.org/licenses/>. |
7604 |
25 Feb 19 |
nicklas |
20 |
------------------------------------------------------------------ |
7604 |
25 Feb 19 |
nicklas |
21 |
|
7604 |
25 Feb 19 |
nicklas |
JavaScript functions for the bioplates and well mapping |
7604 |
25 Feb 19 |
nicklas |
23 |
|
7604 |
25 Feb 19 |
nicklas |
@author Nicklas |
7604 |
25 Feb 19 |
nicklas |
@version 2.16 |
7604 |
25 Feb 19 |
nicklas |
26 |
*/ |
7604 |
25 Feb 19 |
nicklas |
'use strict'; |
7604 |
25 Feb 19 |
nicklas |
28 |
|
7604 |
25 Feb 19 |
nicklas |
29 |
/** |
7604 |
25 Feb 19 |
nicklas |
A list of biomaterial items. The prefix is used |
7604 |
25 Feb 19 |
nicklas |
to find DOM elements for the items in the list. Each |
7604 |
25 Feb 19 |
nicklas |
item should have a prefix.item-id element and may |
7604 |
25 Feb 19 |
nicklas |
also have a prefix.item-id.info and prefix.item-id.label |
7604 |
25 Feb 19 |
nicklas |
elements. |
7604 |
25 Feb 19 |
nicklas |
35 |
|
7604 |
25 Feb 19 |
nicklas |
Use addItem(id, name) to add items to the list. |
7604 |
25 Feb 19 |
nicklas |
37 |
|
7604 |
25 Feb 19 |
nicklas |
38 |
*/ |
7604 |
25 Feb 19 |
nicklas |
function ItemList(prefix) |
7604 |
25 Feb 19 |
nicklas |
40 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.prefix = prefix; |
7604 |
25 Feb 19 |
nicklas |
this.items = new Array(); |
7604 |
25 Feb 19 |
nicklas |
this.selectedItemClass = 'selected'; |
7604 |
25 Feb 19 |
nicklas |
this.linkedItemClass = 'linked'; |
7604 |
25 Feb 19 |
nicklas |
this.mappedItemClass = 'mapped'; |
7604 |
25 Feb 19 |
nicklas |
46 |
|
7604 |
25 Feb 19 |
nicklas |
47 |
/** |
7604 |
25 Feb 19 |
nicklas |
Get the main DOM tag for the item list. It's ID should be |
7604 |
25 Feb 19 |
nicklas |
the same as the list prefix. |
7604 |
25 Feb 19 |
nicklas |
50 |
*/ |
7604 |
25 Feb 19 |
nicklas |
ItemList.prototype.getTag = function() |
7604 |
25 Feb 19 |
nicklas |
52 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.tag) |
7604 |
25 Feb 19 |
nicklas |
54 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.tag = Doc.element(this.prefix); |
7604 |
25 Feb 19 |
nicklas |
56 |
} |
7604 |
25 Feb 19 |
nicklas |
return this.tag; |
7604 |
25 Feb 19 |
nicklas |
58 |
} |
7604 |
25 Feb 19 |
nicklas |
59 |
|
7604 |
25 Feb 19 |
nicklas |
60 |
|
7604 |
25 Feb 19 |
nicklas |
61 |
/** |
7604 |
25 Feb 19 |
nicklas |
Add an item to the list. The DOM should contain an element |
7604 |
25 Feb 19 |
nicklas |
with id=prefix.item-id |
7604 |
25 Feb 19 |
nicklas |
64 |
*/ |
7604 |
25 Feb 19 |
nicklas |
ItemList.prototype.addItem = function(id, name) |
7604 |
25 Feb 19 |
nicklas |
66 |
{ |
7604 |
25 Feb 19 |
nicklas |
var item = new Item(this, id, name); |
7604 |
25 Feb 19 |
nicklas |
this.items[this.items.length] = item; |
7604 |
25 Feb 19 |
nicklas |
this.items['item.' + id] = item; |
7604 |
25 Feb 19 |
nicklas |
return item; |
7604 |
25 Feb 19 |
nicklas |
71 |
} |
7604 |
25 Feb 19 |
nicklas |
72 |
|
7604 |
25 Feb 19 |
nicklas |
73 |
/** |
7604 |
25 Feb 19 |
nicklas |
Get the item with the given id. |
7604 |
25 Feb 19 |
nicklas |
75 |
*/ |
7604 |
25 Feb 19 |
nicklas |
ItemList.prototype.getItem = function(id) |
7604 |
25 Feb 19 |
nicklas |
77 |
{ |
7604 |
25 Feb 19 |
nicklas |
return this.items['item.' + id]; |
7604 |
25 Feb 19 |
nicklas |
79 |
} |
7604 |
25 Feb 19 |
nicklas |
80 |
|
7604 |
25 Feb 19 |
nicklas |
81 |
/** |
7604 |
25 Feb 19 |
nicklas |
Get the next unmapped item after the given item in the list. |
7604 |
25 Feb 19 |
nicklas |
83 |
*/ |
7604 |
25 Feb 19 |
nicklas |
ItemList.prototype.nextUnmappedItem = function(item) |
7604 |
25 Feb 19 |
nicklas |
85 |
{ |
7604 |
25 Feb 19 |
nicklas |
var i = 0; |
7604 |
25 Feb 19 |
nicklas |
// Find the given item |
7604 |
25 Feb 19 |
nicklas |
while (i < this.items.length && this.items[i] != item) |
7604 |
25 Feb 19 |
nicklas |
89 |
{ |
7604 |
25 Feb 19 |
nicklas |
i++; |
7604 |
25 Feb 19 |
nicklas |
91 |
} |
7604 |
25 Feb 19 |
nicklas |
// Move to the next until an unmapped item is found |
7604 |
25 Feb 19 |
nicklas |
i++; |
7604 |
25 Feb 19 |
nicklas |
while (i < this.items.length) |
7604 |
25 Feb 19 |
nicklas |
95 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.items[i].mappedWell) return this.items[i]; |
7604 |
25 Feb 19 |
nicklas |
i++; |
7604 |
25 Feb 19 |
nicklas |
98 |
} |
7604 |
25 Feb 19 |
nicklas |
return null; |
7604 |
25 Feb 19 |
nicklas |
100 |
} |
7604 |
25 Feb 19 |
nicklas |
101 |
|
7604 |
25 Feb 19 |
nicklas |
ItemList.prototype.unmapAll = function(graphics) |
7604 |
25 Feb 19 |
nicklas |
103 |
{ |
7604 |
25 Feb 19 |
nicklas |
for (var i = 0; i < this.items.length; i++) |
7604 |
25 Feb 19 |
nicklas |
105 |
{ |
7604 |
25 Feb 19 |
nicklas |
var item = this.items[i]; |
7604 |
25 Feb 19 |
nicklas |
item.hideLink(graphics); |
7604 |
25 Feb 19 |
nicklas |
item.unmapWell(); |
7604 |
25 Feb 19 |
nicklas |
109 |
} |
7604 |
25 Feb 19 |
nicklas |
110 |
} |
7604 |
25 Feb 19 |
nicklas |
111 |
|
7604 |
25 Feb 19 |
nicklas |
112 |
} |
7604 |
25 Feb 19 |
nicklas |
113 |
|
7604 |
25 Feb 19 |
nicklas |
114 |
/** |
7604 |
25 Feb 19 |
nicklas |
A single item in a list of biomaterial. Use ItemList.addItem() to |
7604 |
25 Feb 19 |
nicklas |
add items to the list. |
7604 |
25 Feb 19 |
nicklas |
@param list The list object |
7604 |
25 Feb 19 |
nicklas |
@param id The id of the item |
7604 |
25 Feb 19 |
nicklas |
@param name The name (label) of the item |
7604 |
25 Feb 19 |
nicklas |
120 |
*/ |
7604 |
25 Feb 19 |
nicklas |
function Item(list, id, name) |
7604 |
25 Feb 19 |
nicklas |
122 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.list = list; |
7604 |
25 Feb 19 |
nicklas |
this.id = id; |
7604 |
25 Feb 19 |
nicklas |
this.name = name; |
7604 |
25 Feb 19 |
nicklas |
this.selected = false; |
7604 |
25 Feb 19 |
nicklas |
this.linked = false; |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell = null; |
7604 |
25 Feb 19 |
nicklas |
129 |
|
7604 |
25 Feb 19 |
nicklas |
130 |
/** |
7604 |
25 Feb 19 |
nicklas |
Get the main DOM tag for the item. It should have and ID combined |
7604 |
25 Feb 19 |
nicklas |
of 'list-prefix.item-id' |
7604 |
25 Feb 19 |
nicklas |
133 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.getTag = function() |
7604 |
25 Feb 19 |
nicklas |
135 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.tag) |
7604 |
25 Feb 19 |
nicklas |
137 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.tag = Doc.element(this.list.prefix+'.'+this.id); |
7604 |
25 Feb 19 |
nicklas |
139 |
} |
7604 |
25 Feb 19 |
nicklas |
return this.tag; |
7604 |
25 Feb 19 |
nicklas |
141 |
} |
7604 |
25 Feb 19 |
nicklas |
142 |
|
7604 |
25 Feb 19 |
nicklas |
143 |
/** |
7604 |
25 Feb 19 |
nicklas |
Add a CSS class to the item's DOM tag. |
7604 |
25 Feb 19 |
nicklas |
145 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.addClass = function(cls) |
7604 |
25 Feb 19 |
nicklas |
147 |
{ |
7604 |
25 Feb 19 |
nicklas |
Doc.addClass(this.getTag(), cls); |
7604 |
25 Feb 19 |
nicklas |
149 |
} |
7604 |
25 Feb 19 |
nicklas |
150 |
|
7604 |
25 Feb 19 |
nicklas |
151 |
/** |
7604 |
25 Feb 19 |
nicklas |
Remove a CSS class from the item's DOM tag. |
7604 |
25 Feb 19 |
nicklas |
153 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.removeClass = function(cls) |
7604 |
25 Feb 19 |
nicklas |
155 |
{ |
7604 |
25 Feb 19 |
nicklas |
Doc.removeClass(this.getTag(), cls); |
7604 |
25 Feb 19 |
nicklas |
157 |
} |
7604 |
25 Feb 19 |
nicklas |
158 |
|
7604 |
25 Feb 19 |
nicklas |
159 |
/** |
7604 |
25 Feb 19 |
nicklas |
Set the contents of the info element. The tag should have an ID combined |
7604 |
25 Feb 19 |
nicklas |
of 'list-prefix.item-id.info'. |
7604 |
25 Feb 19 |
nicklas |
162 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.setInfo = function(info) |
7604 |
25 Feb 19 |
nicklas |
164 |
{ |
7604 |
25 Feb 19 |
nicklas |
var infoTag = Doc.element(this.list.prefix+'.'+this.id + '.info'); |
7604 |
25 Feb 19 |
nicklas |
if (!infoTag) return; |
7604 |
25 Feb 19 |
nicklas |
infoTag.innerHTML = info; |
7604 |
25 Feb 19 |
nicklas |
168 |
} |
7604 |
25 Feb 19 |
nicklas |
169 |
|
7604 |
25 Feb 19 |
nicklas |
170 |
/** |
7604 |
25 Feb 19 |
nicklas |
Mark the item as selected/deselected. |
7604 |
25 Feb 19 |
nicklas |
172 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.setSelected = function(selected) |
7604 |
25 Feb 19 |
nicklas |
174 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.selected = selected; |
7604 |
25 Feb 19 |
nicklas |
Doc.addOrRemoveClass(this.getTag(), this.list.selectedItemClass, selected); |
7604 |
25 Feb 19 |
nicklas |
177 |
} |
7604 |
25 Feb 19 |
nicklas |
178 |
|
7604 |
25 Feb 19 |
nicklas |
179 |
/** |
7604 |
25 Feb 19 |
nicklas |
Mark the item as linked. Do not call this method. Use drawLink/hideLink |
7604 |
25 Feb 19 |
nicklas |
instead. |
7604 |
25 Feb 19 |
nicklas |
182 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.setLinked = function(linked) |
7604 |
25 Feb 19 |
nicklas |
184 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.linked = linked; |
7604 |
25 Feb 19 |
nicklas |
Doc.addOrRemoveClass(this.getTag(), this.list.linkedItemClass, linked); |
7604 |
25 Feb 19 |
nicklas |
187 |
} |
7604 |
25 Feb 19 |
nicklas |
188 |
|
7604 |
25 Feb 19 |
nicklas |
189 |
/** |
7604 |
25 Feb 19 |
nicklas |
Draw a link from the item to the well it is mapped to. If |
7604 |
25 Feb 19 |
nicklas |
the item is not mapped, no link is drawn. |
7604 |
25 Feb 19 |
nicklas |
192 |
|
7604 |
25 Feb 19 |
nicklas |
@param graphics A jsGraphics object |
7604 |
25 Feb 19 |
nicklas |
@param pen A jsGraphics pen object |
7604 |
25 Feb 19 |
nicklas |
@param overwrite TRUE to overwrite existing link, FALSE to not draw if there already is a link |
7604 |
25 Feb 19 |
nicklas |
196 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.drawLink = function(graphics, pen, overwrite) |
7604 |
25 Feb 19 |
nicklas |
198 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.mappedWell) return; |
7604 |
25 Feb 19 |
nicklas |
if (this.linkDiv) |
7604 |
25 Feb 19 |
nicklas |
201 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!overwrite) return; |
7604 |
25 Feb 19 |
nicklas |
this.hideLink(graphics); |
7604 |
25 Feb 19 |
nicklas |
204 |
} |
7604 |
25 Feb 19 |
nicklas |
205 |
|
7604 |
25 Feb 19 |
nicklas |
var itemPos = Doc.getElementPosition(this.getTag()); |
7604 |
25 Feb 19 |
nicklas |
var wellPos = Doc.getElementPosition(this.mappedWell.getTag()); |
7604 |
25 Feb 19 |
nicklas |
var listPos = Doc.getElementPosition(this.list.getTag()); |
7604 |
25 Feb 19 |
nicklas |
// Do not draw the link if the item is not visible |
7604 |
25 Feb 19 |
nicklas |
if (itemPos.top < listPos.top || (itemPos.bottom) > (listPos.bottom)) return; |
7604 |
25 Feb 19 |
nicklas |
211 |
|
7604 |
25 Feb 19 |
nicklas |
var points = new Array(); |
7604 |
25 Feb 19 |
nicklas |
points[0] = new jsPoint(itemPos.right, itemPos.top+itemPos.height/2); |
7604 |
25 Feb 19 |
nicklas |
points[1] = new jsPoint(wellPos.left, wellPos.top+wellPos.height/2); |
7604 |
25 Feb 19 |
nicklas |
this.linkDiv = graphics.drawLine(pen, points[0], points[1]); |
7604 |
25 Feb 19 |
nicklas |
this.setLinked(true); |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.setLinked(true); |
7604 |
25 Feb 19 |
nicklas |
218 |
} |
7604 |
25 Feb 19 |
nicklas |
219 |
|
7604 |
25 Feb 19 |
nicklas |
220 |
/** |
7604 |
25 Feb 19 |
nicklas |
Hide the link from the item to the well it is mapped to. |
7604 |
25 Feb 19 |
nicklas |
222 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.hideLink = function(graphics) |
7604 |
25 Feb 19 |
nicklas |
224 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.linkDiv) return; |
7604 |
25 Feb 19 |
nicklas |
graphics.clearDrawing(this.linkDiv); |
7604 |
25 Feb 19 |
nicklas |
this.linkDiv = null; |
7604 |
25 Feb 19 |
nicklas |
this.setLinked(false); |
7604 |
25 Feb 19 |
nicklas |
if (this.mappedWell) |
7604 |
25 Feb 19 |
nicklas |
230 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.setLinked(false); |
7604 |
25 Feb 19 |
nicklas |
232 |
} |
7604 |
25 Feb 19 |
nicklas |
233 |
} |
7604 |
25 Feb 19 |
nicklas |
234 |
|
7604 |
25 Feb 19 |
nicklas |
235 |
/** |
7604 |
25 Feb 19 |
nicklas |
Map the item to the given well. Existing mapping for the |
7604 |
25 Feb 19 |
nicklas |
current item and well are automatically removed. The |
7604 |
25 Feb 19 |
nicklas |
item's info tag is updated with the coordinate of the well. |
7604 |
25 Feb 19 |
nicklas |
239 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.mapToWell = function(well) |
7604 |
25 Feb 19 |
nicklas |
241 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.unmapWell(); |
7604 |
25 Feb 19 |
nicklas |
well.unmapItem(); |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell = well; |
7604 |
25 Feb 19 |
nicklas |
well.mappedItem = this; |
7604 |
25 Feb 19 |
nicklas |
this.setInfo(well.getCoordinate()); |
7604 |
25 Feb 19 |
nicklas |
this.addClass(this.list.mappedItemClass); |
7604 |
25 Feb 19 |
nicklas |
well.addClass(well.plate.mappedWellClass); |
7604 |
25 Feb 19 |
nicklas |
249 |
} |
7604 |
25 Feb 19 |
nicklas |
250 |
|
7604 |
25 Feb 19 |
nicklas |
251 |
/** |
7604 |
25 Feb 19 |
nicklas |
Remove the current mapping. |
7604 |
25 Feb 19 |
nicklas |
253 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.unmapWell = function() |
7604 |
25 Feb 19 |
nicklas |
255 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.mappedWell) return; |
7604 |
25 Feb 19 |
nicklas |
this.setInfo(''); |
7604 |
25 Feb 19 |
nicklas |
this.removeClass(this.list.mappedItemClass); |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.removeClass(this.mappedWell.plate.mappedWellClass); |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.mappedItem = null; |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell = null; |
7604 |
25 Feb 19 |
nicklas |
262 |
} |
7604 |
25 Feb 19 |
nicklas |
263 |
|
7604 |
25 Feb 19 |
nicklas |
264 |
/** |
7604 |
25 Feb 19 |
nicklas |
Scroll the list so that this item comes into view. If the item is already visible |
7604 |
25 Feb 19 |
nicklas |
nothing is changed |
7604 |
25 Feb 19 |
nicklas |
267 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Item.prototype.scrollIntoView = function() |
7604 |
25 Feb 19 |
nicklas |
269 |
{ |
7604 |
25 Feb 19 |
nicklas |
var itemTag = this.getTag(); |
7604 |
25 Feb 19 |
nicklas |
var itemPos = Doc.getElementPosition(itemTag); |
7604 |
25 Feb 19 |
nicklas |
var listTag = this.list.getTag(); |
7604 |
25 Feb 19 |
nicklas |
var listPos = Doc.getElementPosition(listTag); |
7604 |
25 Feb 19 |
nicklas |
274 |
|
7604 |
25 Feb 19 |
nicklas |
if (itemPos.top < listPos.top) |
7604 |
25 Feb 19 |
nicklas |
276 |
{ |
7604 |
25 Feb 19 |
nicklas |
// Scroll up |
7604 |
25 Feb 19 |
nicklas |
listTag.scrollTop = listTag.scrollTop - (listPos.top - itemPos.top); |
7604 |
25 Feb 19 |
nicklas |
279 |
} |
7604 |
25 Feb 19 |
nicklas |
else if (itemPos.bottom > listPos.bottom) |
7604 |
25 Feb 19 |
nicklas |
281 |
{ |
7604 |
25 Feb 19 |
nicklas |
// Scroll down |
7604 |
25 Feb 19 |
nicklas |
listTag.scrollTop = listTag.scrollTop + (itemPos.bottom - listPos.bottom); |
7604 |
25 Feb 19 |
nicklas |
284 |
} |
7604 |
25 Feb 19 |
nicklas |
285 |
} |
7604 |
25 Feb 19 |
nicklas |
286 |
} |
7604 |
25 Feb 19 |
nicklas |
287 |
|
7604 |
25 Feb 19 |
nicklas |
288 |
/** |
7604 |
25 Feb 19 |
nicklas |
Represents a plate for storing biomaterial. |
7604 |
25 Feb 19 |
nicklas |
290 |
|
7604 |
25 Feb 19 |
nicklas |
@param prefix Prefix used to find DOM tags for the wells |
7604 |
25 Feb 19 |
nicklas |
@param id The id of the plate |
7604 |
25 Feb 19 |
nicklas |
@param name The name of the plate |
7604 |
25 Feb 19 |
nicklas |
@param rows The number of rows on the plate |
7604 |
25 Feb 19 |
nicklas |
@param columns The number of columns on the plate |
7604 |
25 Feb 19 |
nicklas |
@param isSourcePlate If the given plate is a source plate or destination plate |
7604 |
25 Feb 19 |
nicklas |
297 |
*/ |
7604 |
25 Feb 19 |
nicklas |
function Plate(prefix, id, name, rows, columns, isSourcePlate) |
7604 |
25 Feb 19 |
nicklas |
299 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.prefix = prefix; |
7604 |
25 Feb 19 |
nicklas |
this.id = id; |
7604 |
25 Feb 19 |
nicklas |
this.name = name; |
7604 |
25 Feb 19 |
nicklas |
this.rows = rows; |
7604 |
25 Feb 19 |
nicklas |
this.columns = columns; |
7604 |
25 Feb 19 |
nicklas |
this.isSourcePlate = isSourcePlate; |
7604 |
25 Feb 19 |
nicklas |
this.selectedWellClass = 'selected'; |
7604 |
25 Feb 19 |
nicklas |
this.linkedWellClass = 'linked'; |
7604 |
25 Feb 19 |
nicklas |
this.mappedWellClass = 'mapped'; |
7604 |
25 Feb 19 |
nicklas |
this.wells = new Array(); |
7604 |
25 Feb 19 |
nicklas |
310 |
|
7604 |
25 Feb 19 |
nicklas |
311 |
/** |
7604 |
25 Feb 19 |
nicklas |
Get the well on the given coordinate. If the coordinate it outside the |
7604 |
25 Feb 19 |
nicklas |
plate boundaries, null is returned, otherwise a Well object. |
7604 |
25 Feb 19 |
nicklas |
314 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Plate.prototype.getWell = function(row, column) |
7604 |
25 Feb 19 |
nicklas |
316 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (row < 0 || row >= this.rows) return null; |
7604 |
25 Feb 19 |
nicklas |
if (column < 0 || column >= this.columns) return null; |
7604 |
25 Feb 19 |
nicklas |
var well = this.wells[row+':'+column]; |
7604 |
25 Feb 19 |
nicklas |
if (!well) |
7604 |
25 Feb 19 |
nicklas |
321 |
{ |
7604 |
25 Feb 19 |
nicklas |
well = new Well(this, row, column); |
7604 |
25 Feb 19 |
nicklas |
this.wells[this.wells.length] = well; |
7604 |
25 Feb 19 |
nicklas |
this.wells[row + ':' + column] = well; |
7604 |
25 Feb 19 |
nicklas |
325 |
} |
7604 |
25 Feb 19 |
nicklas |
return well; |
7604 |
25 Feb 19 |
nicklas |
327 |
} |
7604 |
25 Feb 19 |
nicklas |
328 |
|
7604 |
25 Feb 19 |
nicklas |
Plate.prototype.unmapAll = function(graphics) |
7604 |
25 Feb 19 |
nicklas |
330 |
{ |
7604 |
25 Feb 19 |
nicklas |
for (var i = 0; i < this.wells.length; i++) |
7604 |
25 Feb 19 |
nicklas |
332 |
{ |
7604 |
25 Feb 19 |
nicklas |
var well = this.wells[i]; |
7604 |
25 Feb 19 |
nicklas |
well.hideLink(graphics); |
7604 |
25 Feb 19 |
nicklas |
well.unmapWell(); |
7604 |
25 Feb 19 |
nicklas |
336 |
} |
7604 |
25 Feb 19 |
nicklas |
337 |
} |
7604 |
25 Feb 19 |
nicklas |
338 |
|
7604 |
25 Feb 19 |
nicklas |
339 |
} |
7604 |
25 Feb 19 |
nicklas |
340 |
|
7604 |
25 Feb 19 |
nicklas |
341 |
/** |
7604 |
25 Feb 19 |
nicklas |
A well on a plate. |
7604 |
25 Feb 19 |
nicklas |
@param plate The plate |
7604 |
25 Feb 19 |
nicklas |
@param row The well's row coordinate |
7604 |
25 Feb 19 |
nicklas |
@param column The well's column coordinate |
7604 |
25 Feb 19 |
nicklas |
@returns |
7604 |
25 Feb 19 |
nicklas |
347 |
*/ |
7604 |
25 Feb 19 |
nicklas |
function Well(plate, row, column) |
7604 |
25 Feb 19 |
nicklas |
349 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.plate = plate; |
7604 |
25 Feb 19 |
nicklas |
this.row = row; |
7604 |
25 Feb 19 |
nicklas |
this.column = column; |
7604 |
25 Feb 19 |
nicklas |
this.selected = false; |
7604 |
25 Feb 19 |
nicklas |
this.linked = false; |
7604 |
25 Feb 19 |
nicklas |
this.mappedItem = null; |
7604 |
25 Feb 19 |
nicklas |
356 |
|
7604 |
25 Feb 19 |
nicklas |
357 |
/** |
7604 |
25 Feb 19 |
nicklas |
Get the DOM tag that represents the well. The element should have an |
7604 |
25 Feb 19 |
nicklas |
ID combined of 'plate-prefix.row.column'. |
7604 |
25 Feb 19 |
nicklas |
360 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.getTag = function() |
7604 |
25 Feb 19 |
nicklas |
362 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.tag) |
7604 |
25 Feb 19 |
nicklas |
364 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.tag = Doc.element(this.plate.prefix+'.'+this.row+'.'+this.column); |
7604 |
25 Feb 19 |
nicklas |
366 |
} |
7604 |
25 Feb 19 |
nicklas |
return this.tag; |
7604 |
25 Feb 19 |
nicklas |
368 |
} |
7604 |
25 Feb 19 |
nicklas |
369 |
|
7604 |
25 Feb 19 |
nicklas |
370 |
/** |
7604 |
25 Feb 19 |
nicklas |
Add a CSS class to the well DOM tag. |
7604 |
25 Feb 19 |
nicklas |
372 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.addClass = function(cls) |
7604 |
25 Feb 19 |
nicklas |
374 |
{ |
7604 |
25 Feb 19 |
nicklas |
Doc.addClass(this.getTag(), cls); |
7604 |
25 Feb 19 |
nicklas |
376 |
} |
7604 |
25 Feb 19 |
nicklas |
377 |
|
7604 |
25 Feb 19 |
nicklas |
378 |
/** |
7604 |
25 Feb 19 |
nicklas |
Remove a CSS class from the item's DOM tag. |
7604 |
25 Feb 19 |
nicklas |
380 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.removeClass = function(cls) |
7604 |
25 Feb 19 |
nicklas |
382 |
{ |
7604 |
25 Feb 19 |
nicklas |
Doc.removeClass(this.getTag(), cls); |
7604 |
25 Feb 19 |
nicklas |
384 |
} |
7604 |
25 Feb 19 |
nicklas |
385 |
|
7604 |
25 Feb 19 |
nicklas |
386 |
/** |
7604 |
25 Feb 19 |
nicklas |
Get the coordinate of the well as a string. Rows are alphabetically |
7604 |
25 Feb 19 |
nicklas |
numbered. |
7604 |
25 Feb 19 |
nicklas |
389 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.getCoordinate = function() |
7604 |
25 Feb 19 |
nicklas |
391 |
{ |
7604 |
25 Feb 19 |
nicklas |
return Plates.toAlphaCoordinate[this.row] + (this.column+1); |
7604 |
25 Feb 19 |
nicklas |
393 |
} |
7604 |
25 Feb 19 |
nicklas |
394 |
|
7604 |
25 Feb 19 |
nicklas |
395 |
/** |
7604 |
25 Feb 19 |
nicklas |
Set the contents of the well element. The tag should have an ID combined |
7604 |
25 Feb 19 |
nicklas |
of 'plate-prefix.row.column.info'. |
7604 |
25 Feb 19 |
nicklas |
398 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.setInfo = function(info) |
7604 |
25 Feb 19 |
nicklas |
400 |
{ |
7604 |
25 Feb 19 |
nicklas |
var infoTag = Doc.element(this.plate.prefix+'.'+this.row+'.'+this.column + '.info'); |
7604 |
25 Feb 19 |
nicklas |
if (!infoTag) return; |
7604 |
25 Feb 19 |
nicklas |
infoTag.innerHTML = info; |
7604 |
25 Feb 19 |
nicklas |
404 |
} |
7604 |
25 Feb 19 |
nicklas |
405 |
|
7604 |
25 Feb 19 |
nicklas |
406 |
/** |
7604 |
25 Feb 19 |
nicklas |
Mark the well as selected/deselected. |
7604 |
25 Feb 19 |
nicklas |
408 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.setSelected = function(selected) |
7604 |
25 Feb 19 |
nicklas |
410 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.selected = selected; |
7604 |
25 Feb 19 |
nicklas |
Doc.addOrRemoveClass(this.getTag(), this.plate.selectedWellClass, selected); |
7604 |
25 Feb 19 |
nicklas |
413 |
} |
7604 |
25 Feb 19 |
nicklas |
414 |
|
7604 |
25 Feb 19 |
nicklas |
415 |
/** |
7604 |
25 Feb 19 |
nicklas |
Mark the well as linked. Do not call this method. Use drawLink/hideLink |
7604 |
25 Feb 19 |
nicklas |
instead. |
7604 |
25 Feb 19 |
nicklas |
418 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.setLinked = function(linked) |
7604 |
25 Feb 19 |
nicklas |
420 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.linked = linked; |
7604 |
25 Feb 19 |
nicklas |
Doc.addOrRemoveClass(this.getTag(), this.plate.linkedWellClass, linked); |
7604 |
25 Feb 19 |
nicklas |
423 |
} |
7604 |
25 Feb 19 |
nicklas |
424 |
|
7604 |
25 Feb 19 |
nicklas |
425 |
|
7604 |
25 Feb 19 |
nicklas |
426 |
/** |
7604 |
25 Feb 19 |
nicklas |
Draw a link from the well to the item it is mapped to. If |
7604 |
25 Feb 19 |
nicklas |
the well is not mapped, no link is drawn. |
7604 |
25 Feb 19 |
nicklas |
429 |
|
7604 |
25 Feb 19 |
nicklas |
@param graphics A jsGraphics object |
7604 |
25 Feb 19 |
nicklas |
@param pen A jsGraphics pen object |
7604 |
25 Feb 19 |
nicklas |
@param overwrite TRUE to overwrite existing link, FALSE to not draw if there already is a link |
7604 |
25 Feb 19 |
nicklas |
433 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.drawLink = function(graphics, pen, overwrite) |
7604 |
25 Feb 19 |
nicklas |
435 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (this.mappedItem) |
7604 |
25 Feb 19 |
nicklas |
437 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.mappedItem.drawLink(graphics, pen, overwrite); |
7604 |
25 Feb 19 |
nicklas |
439 |
} |
7604 |
25 Feb 19 |
nicklas |
else if (this.mappedWell) |
7604 |
25 Feb 19 |
nicklas |
441 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (this.mappedWell.plate.isSourcePlate) |
7604 |
25 Feb 19 |
nicklas |
443 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.drawLink(graphics, pen, overwrite); |
7604 |
25 Feb 19 |
nicklas |
445 |
} |
7604 |
25 Feb 19 |
nicklas |
else |
7604 |
25 Feb 19 |
nicklas |
447 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (this.linkDiv) |
7604 |
25 Feb 19 |
nicklas |
449 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!overwrite) return; |
7604 |
25 Feb 19 |
nicklas |
this.hideLink(graphics); |
7604 |
25 Feb 19 |
nicklas |
452 |
} |
7604 |
25 Feb 19 |
nicklas |
453 |
|
7604 |
25 Feb 19 |
nicklas |
var srcPos = Doc.getElementPosition(this.getTag()); |
7604 |
25 Feb 19 |
nicklas |
var destPos = Doc.getElementPosition(this.mappedWell.getTag()); |
7604 |
25 Feb 19 |
nicklas |
var points = new Array(); |
7604 |
25 Feb 19 |
nicklas |
points[0] = new jsPoint(srcPos.left + srcPos.width, srcPos.top+srcPos.height/2); |
7604 |
25 Feb 19 |
nicklas |
points[1] = new jsPoint(destPos.left, destPos.top+destPos.height/2); |
7604 |
25 Feb 19 |
nicklas |
this.linkDiv = graphics.drawLine(pen, points[0], points[1]); |
7604 |
25 Feb 19 |
nicklas |
this.setLinked(true); |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.setLinked(true); |
7604 |
25 Feb 19 |
nicklas |
462 |
} |
7604 |
25 Feb 19 |
nicklas |
463 |
} |
7604 |
25 Feb 19 |
nicklas |
464 |
} |
7604 |
25 Feb 19 |
nicklas |
465 |
|
7604 |
25 Feb 19 |
nicklas |
466 |
/** |
7604 |
25 Feb 19 |
nicklas |
Hide the link from the well to the item/well it is mapped to. |
7604 |
25 Feb 19 |
nicklas |
468 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.hideLink = function(graphics) |
7604 |
25 Feb 19 |
nicklas |
470 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (this.mappedItem) |
7604 |
25 Feb 19 |
nicklas |
472 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.mappedItem.hideLink(graphics); |
7604 |
25 Feb 19 |
nicklas |
474 |
} |
7604 |
25 Feb 19 |
nicklas |
if (this.linkDiv) |
7604 |
25 Feb 19 |
nicklas |
476 |
{ |
7604 |
25 Feb 19 |
nicklas |
graphics.clearDrawing(this.linkDiv); |
7604 |
25 Feb 19 |
nicklas |
this.linkDiv = null; |
7604 |
25 Feb 19 |
nicklas |
this.setLinked(false); |
7604 |
25 Feb 19 |
nicklas |
if (this.mappedWell) |
7604 |
25 Feb 19 |
nicklas |
481 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.setLinked(false); |
7604 |
25 Feb 19 |
nicklas |
483 |
} |
7604 |
25 Feb 19 |
nicklas |
484 |
} |
7604 |
25 Feb 19 |
nicklas |
else if (this.mappedWell && this.mappedWell.plate.isSourcePlate) |
7604 |
25 Feb 19 |
nicklas |
486 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.hideLink(graphics); |
7604 |
25 Feb 19 |
nicklas |
488 |
} |
7604 |
25 Feb 19 |
nicklas |
489 |
} |
7604 |
25 Feb 19 |
nicklas |
490 |
|
7604 |
25 Feb 19 |
nicklas |
491 |
/** |
7604 |
25 Feb 19 |
nicklas |
Remove the current mapping. |
7604 |
25 Feb 19 |
nicklas |
493 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.unmapItem = function() |
7604 |
25 Feb 19 |
nicklas |
495 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.mappedItem) return; |
7604 |
25 Feb 19 |
nicklas |
this.mappedItem.unmapWell(this); |
7604 |
25 Feb 19 |
nicklas |
498 |
} |
7604 |
25 Feb 19 |
nicklas |
499 |
|
7604 |
25 Feb 19 |
nicklas |
500 |
/** |
7604 |
25 Feb 19 |
nicklas |
Map this *source* well to the other *destination* well. |
7604 |
25 Feb 19 |
nicklas |
An existing mapping for the current well is automatically removed. |
7604 |
25 Feb 19 |
nicklas |
503 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.mapToWell = function(well) |
7604 |
25 Feb 19 |
nicklas |
505 |
{ |
7604 |
25 Feb 19 |
nicklas |
this.unmapWell(); |
7604 |
25 Feb 19 |
nicklas |
well.unmapWell(); |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell = well; |
7604 |
25 Feb 19 |
nicklas |
well.mappedWell = this; |
7604 |
25 Feb 19 |
nicklas |
this.addClass(this.plate.mappedWellClass); |
7604 |
25 Feb 19 |
nicklas |
well.addClass(well.plate.mappedWellClass); |
7604 |
25 Feb 19 |
nicklas |
well.setInfo(this.getCoordinate()); |
7604 |
25 Feb 19 |
nicklas |
513 |
} |
7604 |
25 Feb 19 |
nicklas |
514 |
|
7604 |
25 Feb 19 |
nicklas |
515 |
/** |
7604 |
25 Feb 19 |
nicklas |
Remove the current mapping to another well. |
7604 |
25 Feb 19 |
nicklas |
517 |
*/ |
7604 |
25 Feb 19 |
nicklas |
Well.prototype.unmapWell = function() |
7604 |
25 Feb 19 |
nicklas |
519 |
{ |
7604 |
25 Feb 19 |
nicklas |
if (!this.mappedWell) return; |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.setInfo(''); |
7604 |
25 Feb 19 |
nicklas |
this.removeClass(this.plate.mappedWellClass); |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.removeClass(this.mappedWell.plate.mappedWellClass); |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell.mappedWell = null; |
7604 |
25 Feb 19 |
nicklas |
this.mappedWell = null; |
7604 |
25 Feb 19 |
nicklas |
526 |
} |
7604 |
25 Feb 19 |
nicklas |
527 |
|
7604 |
25 Feb 19 |
nicklas |
528 |
} |
7604 |
25 Feb 19 |
nicklas |
529 |
|
7604 |
25 Feb 19 |
nicklas |
// Namespace for utility functions |
7604 |
25 Feb 19 |
nicklas |
var Plates = {}; |
7604 |
25 Feb 19 |
nicklas |
532 |
|
7604 |
25 Feb 19 |
nicklas |
Plates.toAlphaCoordinate = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', |
7604 |
25 Feb 19 |
nicklas |
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']; |
7604 |
25 Feb 19 |
nicklas |
535 |
|
7604 |
25 Feb 19 |
nicklas |
536 |
|
7604 |
25 Feb 19 |
nicklas |
537 |
|