Merge pull request #9 from lambdacasserole/feature-custom-labels

Feature custom labels
This commit is contained in:
Saul Johnson
2017-08-15 18:20:58 +01:00
committed by GitHub
4 changed files with 127 additions and 14 deletions
+57 -1
View File
@@ -15,6 +15,10 @@ class MoleculeRenderer
{
private $sourireUrl;
private $renderChiralLabels;
private $customLabel;
/**
* Initializes a new instance of a molecule rendering service.
*
@@ -30,6 +34,10 @@ class MoleculeRenderer
// Configure GD as image driver.
Image::configure(array('driver' => 'gd'));
// Set some defaults.
$this->renderChiralLabels = true;
$this->customLabel = '';
}
/**
@@ -42,7 +50,11 @@ class MoleculeRenderer
public function renderMolecule($smiles, $color)
{
// Proxy into Sourire for molecule render.
$img = Image::make($this->sourireUrl . 'molecule/' . urlencode($smiles));
$img = Image::make($this->sourireUrl
. 'molecule/' . urlencode($smiles)
. '?render-stereo-style=' . ($this->renderChiralLabels ? 'old' : 'none') // Label chiral atoms?
. '&render-comment-offset=16' // Give some space between label and molecule.
. ($this->customLabel === '' ? '' : ('&render-comment=' . urlencode($this->customLabel))));
// Colorize molecule.
list($r, $g, $b) = sscanf($color, "%02x%02x%02x");
@@ -109,4 +121,48 @@ class MoleculeRenderer
return $img;
}
/**
* Gets whether or not to render the chiral labels next to each chiral center.
*
* @return bool
*/
public function getRenderChiralLabels()
{
return $this->renderChiralLabels;
}
/**
* Sets whether or not to render the chiral labels next to each chiral center.
*
* @param bool $renderChiralLabels true if labels should be rendered, otherwise false
* @return MoleculeRenderer
*/
public function setRenderChiralLabels($renderChiralLabels)
{
$this->renderChiralLabels = $renderChiralLabels;
return $this;
}
/**
* Gets the custom label to be displayed alongside the molecule.
*
* @return string
*/
public function getCustomLabel()
{
return $this->customLabel;
}
/**
* Sets the custom label to be displayed alongside the molecule.
*
* @param string $customLabel the label to display
* @return MoleculeRenderer
*/
public function setCustomLabel($customLabel)
{
$this->customLabel = $customLabel;
return $this;
}
}
+36 -7
View File
@@ -7,6 +7,9 @@ $(document).ready ->
foregroundColor = 'ce3838'
backgroundColor = '5f0000'
# Custom label for molecule.
customLabel = ''
# Data about current molecule.
smilesMode = true
currentCompoundName = ''
@@ -15,6 +18,7 @@ $(document).ready ->
# Text entry fields for molecules.
compoundTextBox = $ '.comp-name'
smilesTextBox = $ '.comp-smiles'
customLabelTextBox = $ '.cust-lbl-tbox'
# Element to use for wallpaper preview.
previewElement = $ 'body, html'
@@ -37,6 +41,11 @@ $(document).ready ->
getCompoundSmiles = ->
encodeURIComponent smilesTextBox.val()
# Gets the sanitized custom molecule label as entered by the user.
#
getCustomLabel = ->
encodeURIComponent customLabelTextBox.val()
# URL builder functions for API.
# Builds a URL to generate a wallpaper image from a compound name.
@@ -48,7 +57,9 @@ $(document).ready ->
# @param [name] name the compound name
#
buildUrl = (width, height, foreground, background, name) ->
"/api/name/#{width}/#{height}/#{background}/#{foreground}/#{name}"
url = "/api/name/#{width}/#{height}/#{background}/#{foreground}/#{name}"
if customLabel != '' then url += "?label=#{customLabel}"
return url
# Builds a URL to generate a molecule-only image from a compound name.
#
@@ -58,7 +69,9 @@ $(document).ready ->
# @param [name] name the compound name
#
buildMoleculeOnlyUrl = (width, height, foreground, name) ->
"/api/name/#{width}/#{height}/#{foreground}/#{name}"
url = "/api/name/#{width}/#{height}/#{foreground}/#{name}"
if customLabel != '' then url += "?label=#{customLabel}"
return url
# Builds a URL to generate a wallpaper image from a SMILES structure.
#
@@ -69,7 +82,9 @@ $(document).ready ->
# @param [name] name the SMILES structure
#
buildSmilesUrl = (width, height, foreground, background, smiles) ->
"/api/smiles/#{width}/#{height}/#{background}/#{foreground}/#{smiles}"
url = "/api/smiles/#{width}/#{height}/#{background}/#{foreground}/#{smiles}"
if customLabel != '' then url += "?label=#{customLabel}"
return url
# Builds a URL to generate a molecule-only image from a SMILES structure.
#
@@ -79,7 +94,9 @@ $(document).ready ->
# @param [name] smiles the SMILES structure
#
buildSmilesMoleculeOnlyUrl = (width, height, foreground, smiles) ->
"/api/smiles/#{width}/#{height}/#{foreground}/#{smiles}"
url = "/api/smiles/#{width}/#{height}/#{foreground}/#{smiles}"
if customLabel != '' then url += "?label=#{customLabel}"
return url
# Checks if a compound name can be converted to SMILES using the configured database.
#
@@ -151,6 +168,11 @@ $(document).ready ->
url = buildSmilesMoleculeOnlyUrl screenWidth, screenHeight, foregroundColor, currentCompoundSmiles
updatePreview previewElement, url, backgroundColor
# Refreshes the preview using the compound name or SMILES structure text box depending on mode.
#
modeAwareRefreshPreview = ->
if smilesMode then refreshPreviewSmiles() else refreshPreviewCompoundName()
# Let's initialize the color pickers.
$('.picker-fg').spectrum
@@ -169,11 +191,11 @@ $(document).ready ->
$('.picker-fg').on 'change', (e) ->
foregroundColor = $(e.target).val().substring(1)
if smilesMode then refreshPreviewSmiles() else refreshPreviewCompoundName()
modeAwareRefreshPreview()
$('.picker-bg').on 'change', (e) ->
backgroundColor = $(e.target).val().substring(1)
if smilesMode then refreshPreviewSmiles() else refreshPreviewCompoundName()
modeAwareRefreshPreview()
# Compound name update button should refresh the preview.
@@ -186,9 +208,16 @@ $(document).ready ->
errorRows.hide()
checkSmiles getCompoundSmiles(), refreshPreviewSmiles, failPreviewSmiles
# Label update button should also refresh preview.
$('.update-lbl-btn').on 'click', (e) ->
customLabel = getCustomLabel()
modeAwareRefreshPreview()
# Grab initial values from text boxes.
currentCompoundName = compoundTextBox.val()
currentCompoundSmiles = smilesTextBox.val()
customLabel = customLabelTextBox.val()
# Initial update.
if smilesMode then refreshPreviewSmiles() else refreshPreviewCompoundName()
modeAwareRefreshPreview()
+18
View File
@@ -88,6 +88,24 @@
</div>
</div>
</div>
<div class="tool-section mtop-10">
<div class="row">
<div class="col-xs-12">
<div class="section-lbl">Custom Label</div>
<hr>
</div>
</div>
<div class="row mtop-10">
<div class="col-xs-12">
<input type="text" class="cust-lbl-tbox dark-tbox">
</div>
</div>
<div class="row mtop-10">
<div class="col-xs-12 text-right">
<button class="update-lbl-btn">Update</button>
</div>
</div>
</div>
<div class="tool-section mtop-10">
<div class="row">
<div class="col-xs-12">
+16 -6
View File
@@ -23,6 +23,8 @@ $config = Spyc::YAMLLoad(__DIR__ . '/../config/config.yaml');
$smilesConverter = new SmilesConverter(new Database('names', __DIR__ . '/../db'));
$moleculeRenderer = new MoleculeRenderer($config['sourire_service']);
$moleculeRenderer->setRenderChiralLabels(false); // Disable chiral labels.
// Twig initialization.
$loader = new Twig_Loader_Filesystem(__DIR__.'/../templates');
$twig = new Twig_Environment($loader, array(
@@ -44,7 +46,10 @@ $app->get('/', function () use ($twig, $config) {
* Action for SMILES wallpaper route.
*/
$app->get('/api/smiles/{width}/{height}/{background}/{foreground}/{smiles}',
function ($width, $height, $background, $foreground, $smiles) use ($moleculeRenderer) {
function (Request $request, $width, $height, $background, $foreground, $smiles) use ($moleculeRenderer) {
// Add label.
$moleculeRenderer->setCustomLabel($request->get('label'));
// Render molecule with background.
$image = $moleculeRenderer->renderMoleculeWithBackground($smiles, $foreground, $background, $width, $height);
@@ -57,7 +62,10 @@ $app->get('/api/smiles/{width}/{height}/{background}/{foreground}/{smiles}',
* Action for molecule-only SMILES route.
*/
$app->get('/api/smiles/{width}/{height}/{color}/{smiles}',
function ($width, $height, $color, $smiles) use ($moleculeRenderer) {
function (Request $request, $width, $height, $color, $smiles) use ($moleculeRenderer) {
// Add label.
$moleculeRenderer->setCustomLabel($request->get('label'));
// Render molecule only.
$image = $moleculeRenderer->renderScaledMolecule($smiles, $color, $width, $height);
@@ -70,14 +78,15 @@ $app->get('/api/smiles/{width}/{height}/{color}/{smiles}',
* Action for compound name wallpaper route.
*/
$app->get('/api/name/{width}/{height}/{background}/{foreground}/{name}',
function ($width, $height, $background, $foreground, $name) use ($app, $smilesConverter) {
function (Request $request, $width, $height, $background, $foreground, $name) use ($app, $smilesConverter) {
// Convert chemical name to SMILES if we can.
$smiles = $smilesConverter->nameToSmiles($name);
// Forward to SMILES route.
if ($smiles !== null) {
$smilesRequest = Request::create("/api/smiles/$width/$height/$background/$foreground/$smiles", 'GET');
$smilesRequest = Request::create("/api/smiles/$width/$height/$background/$foreground/$smiles",
'GET', $request->query->all());
return $app->handle($smilesRequest, HttpKernelInterface::SUB_REQUEST);
}
@@ -89,14 +98,15 @@ $app->get('/api/name/{width}/{height}/{background}/{foreground}/{name}',
* Action for molecule-only compound name route.
*/
$app->get('/api/name/{width}/{height}/{color}/{name}',
function ($width, $height, $color, $name) use ($app, $smilesConverter) {
function (Request $request, $width, $height, $color, $name) use ($app, $smilesConverter) {
// Convert chemical name to SMILES if we can.
$smiles = $smilesConverter->nameToSmiles($name);
// Forward to SMILES route.
if ($smiles !== null) {
$smilesRequest = Request::create("/api/smiles/$width/$height/$color/$smiles", 'GET');
$smilesRequest = Request::create("/api/smiles/$width/$height/$color/$smiles",
'GET', $request->query->all());
return $app->handle($smilesRequest, HttpKernelInterface::SUB_REQUEST);
}