Geometry Spice converted to Goodie: Broken hover and missing calculation feature (#3181)

* Geometry Broken Hover and missing calc

* Linked hover effect for dot and SVG

* updated css

* started test file

* consolidated objectInfo YML and finished testing

* removed dumeprs

* fixed triggering and added more triggering test cases
master
Brian Singer 2017-04-24 15:41:31 -04:00 committed by Zaahir Moolla
parent 67f6e084f2
commit c5816891e4
13 changed files with 370 additions and 0 deletions

View File

@ -0,0 +1,66 @@
package DDG::Goodie::Geometry;
# ABSTRACT: Write an abstract here
# Start at http://docs.duckduckhack.com/walkthroughs/calculation.html if
# you are new to instant answer development
use DDG::Goodie;
use strict;
use YAML::XS 'LoadFile';
use Data::Dumper;
zci answer_type => 'geometry';
# Caching - http://docs.duckduckhack.com/backend-reference/api-reference.html#caching`
zci is_cached => 1;
my @keyWords = ('geometry', 'formula', 'volume', 'area', 'surface area', 'perimeter', 'circumference', 'diagonal');
my @finalWords;
foreach my $word (@keyWords) {
push(@finalWords, $word);
push(@finalWords, $word.' of');
push(@finalWords, $word.' of a');
}
triggers any => @finalWords;
my ($shapes, $formulas) = LoadFile(share('objectInfo.yml'));
handle remainder => sub {
return unless $_;
my $remainder = lc($_);
return unless my $shape = $shapes->{$remainder};
my %dataFormula;
# Fill dataFormula with values for handlebar to parse
foreach my $key (keys $shape) {
$dataFormula{$key} = {
'nameCaps' => ucfirst($key),
'color' => $formulas->{$key}{'color'},
'symbol' => $formulas->{$key}{'symbol'},
'html' => $shape->{$key}
};
}
return "plain text response", structured_answer => {
data => {
title => ucfirst($remainder),
formulas => \%dataFormula,
svg => LoadFile(share("svg/$remainder.svg")),
},
templates => {
group => "text",
options => {
subtitle_content => 'DDH.geometry.subtitle'
}
}
};
};
1;

View File

@ -0,0 +1,93 @@
.geometry-svg {
fill: transparent;
margin-left: 40px;
max-width: 50%;
height: 175px;
}
.geometry-svg .stroke {
stroke: black;
stroke-width: 2;
stroke-linejoin: round;
}
.geometry-svg .stroke.backface {
stroke-width: 1.5;
}
.geometry-svg .stroke.special {
stroke-dasharray: 5,5;
}
.geometry-svg .stroke.special.hover {
stroke-dasharray: none;
}
.geometry-formulas {
float: left;
font-size: 1.5em;
margin-right: 10px;
}
.geometry-formulas .formula {
margin-bottom: 5px;
overflow: hidden;
clear: left;
}
.geometry-formulas .formula div {
float: left;
}
.geometry-formulas .dot{
width: 14px;
height: 14px;
border-radius: 7px;
opacity: 0.5;
margin: 20px 10px;
}
.geometry-formulas .hover .dot {
opacity: 1;
}
.geometry-formulas h4 {
color: #999;
font-size: 12px;
padding-bottom: 0;
margin-bottom: -3px;
}
.geometry-formulas sup {
font-size: 0.6em;
}
.geometry-formulas small {
color: #808080;
font-size: 0.8em;
}
#geometry--goodie .volume.hover {
fill: #DE5833;
opacity: 1;
}
#geometry--goodie .area.hover {
fill: #F1A031;
opacity: 1;
}
#geometry--goodie .surface.hover {
fill: #F1A031;
opacity: 1;
}
#geometry--goodie .perimeter.hover {
stroke: #5B9E4D;
opacity: 1;
}
#geometry--goodie .circumference.hover {
stroke: #5B9E4D;
opacity: 1;
}
#geometry--goodie .diagonal.hover {
stroke: #4495D4;
opacity: 1;
}

View File

@ -0,0 +1,36 @@
DDH.geometry_goodie = DDH.geometry_goodie || {};
(function(DDH) {
"use strict";
DDH.geometry_goodie.build = function(ops) {
return {
onShow: function() {
var formulaSelector = '.geometry-formulas .formula .dot';
var svgSelector = '.geometry-svg *';
$(svgSelector + ',' + formulaSelector).hover(
function() {
// Get Current geoemetry type
var datatype = $( this ).data('type');
// Add Hover to Dot
$('#geometry--goodie .'+ datatype).addClass( "hover" );
// Add Hover to SVG
// JQuery 1.1 cant select SVGs by normal selectors
var svg = document.querySelector(".geometry-svg ." + datatype);
svg.classList.add("hover");
}, function() {
// Remove hovers when not hovering
var datatype = $( this ).data('type');
$('#geometry--goodie .' + datatype).removeClass( "hover" );
var svg = document.querySelector(".geometry-svg ." + datatype);
svg.classList.remove("hover");
}
);
}
};
};
})(DDH);

View File

@ -0,0 +1,45 @@
---
square:
area: a<sup>2</sup>
perimeter: 4a
diagonal: a√2
rectangle:
area: ab
perimeter: 2(a+b)
diagonal: "√(a<sup>2</sup>+b<sup>2</sup>)"
equilateral triangle:
area: (a<sup>2</sup>*√3)/4
perimeter: 3a
circle:
area: "πr<sup>2</sup>"
circumference: 2πr
sphere:
volume: 4/3πr<sup>3</sup>
surface: 4πr<sup>2</sup>
cube:
volume: a<sup>3</sup>
surface: 6a<sup>2</sup>
diagonal: a√3
cuboid:
volume: abc
surface: 2(ab + ac + bc)
diagonal: "√(a<sup>2</sup> + b<sup>2</sup> + c<sup>2</sup>)"
---
volume:
symbol: "V"
color: "#DE5833"
area:
symbol: "A"
color: "#F1A031"
surface:
symbol: "S"
color: "#F1A031"
perimeter:
symbol: "u"
color: "#5B9E4D"
circumference:
symbol: "u"
color: "#5B9E4D"
diagonal:
symbol: "e"
color: "#4495D4"

View File

@ -0,0 +1,29 @@
<div id="geometry--goodie">
<div class="geometry-formulas text--primary">
{{#each formulas}}
<div class="formula">
<div class="dot {{@key}}" data-type="{{@key}}" style="background-color: {{color}}"></div>
<div>
<h4>{{nameCaps}}</h4>
{{symbol}} = {{{html}}}
{{#if result}}
= {{result}}
{{/if}}
</div>
</div>
{{/each}}
{{#if parameter}}
<small>
Assuming
{{#each parameter}}
{{symbol}} = {{value}}
{{/each}}
</small>
{{/if}}
</div>
{{#if svg}}
<svg class="geometry-svg" viewBox="-5 -5 170 130">
{{{svg}}}
</svg>
{{/if}}
</div>

View File

@ -0,0 +1,2 @@
<path d="M 0,60 a 25 25 0 0 0 120,0 a 25 25 0 0 0 -120,0" class="stroke area" data-type="area"></path>
<path d="M 0,60 a 25 25 0 0 0 120,0 a 25 25 0 0 0 -120,0" class="stroke circumference" data-type="circumference"></path>

View File

@ -0,0 +1,5 @@
<path d="M 0,120 v -80 l 40,-40 h 80 v 80 l -40 40 z" class="fill surface" data-type="surface"></path>
<path d="M 0,120 l 40,-40 v -80 v 80 h 80" class="stroke backface"></path>
<path d="M 0,40 l 120,40" class="stroke special diagonal" data-type="diagonal"></path>
<path d="M 0,120 v -80 l 40,-40 h 80 v 80 l -40 40 z" class="fill volume" data-type="volume"></path>
<path d="M 0,40 h 80 v 80 h -80 v -80 l 40,-40 h 80 v 80 l -40,40 v -80 l 40,-40" class="stroke"></path>

View File

@ -0,0 +1,5 @@
<path d="M 0,120 v -80 l 40,-40 h 120 v 80 l -40 40 z" class="fill surface" data-type="surface"></path>
<path d="M 0,120 l 40,-40 v -80 v 80 h 120" class="stroke backface"></path>
<path d="M 0,40 l 160,40" class="stroke special diagonal" data-type="diagonal"></path>
<path d="M 0,120 v -80 l 40,-40 h 120 v 80 l -40 40 z" class="fill volume" data-type="volume"></path>
<path d="M 0,40 h 120 v 80 h -120 v -80 l 40,-40 h 120 v 80 l -40,40 v -80 l 40,-40" class="stroke"></path>

View File

@ -0,0 +1,2 @@
<path d="M 70,0 l 70,120 h -140 z" class="fill area" data-type="area"></path>
<path d="M 70,0 l 70,120 m -140,0 l 70,-120 m 70,120 h -140" class="stroke perimeter" data-type="perimeter"></path>

View File

@ -0,0 +1,3 @@
<path d="M 0,0 h 160 v 120 h -160 z" class="stroke area" data-type="area"></path>
<path d="M 0,0 h 160 m 0,120 h -160 m 160,0 v -120 m -160,0 v 120" class="stroke perimeter" data-type="perimeter"></path>
<path d="M 0,0 l 160,120" class="stroke special diagonal" data-type="diagonal"></path>

View File

@ -0,0 +1,4 @@
<path d="M 0,60 a 25 25 0 0 0 120,0 a 25 25 0 0 0 -120,0" class="fill surface" data-type="surface"></path>
<path d="M 0,60 a 30 10 0 0 1 120,0" class="stroke backface"></path>
<path d="M 0,60 a 30 10 0 0 1 120,0" class="stroke backface" data-type="volume"></path>
<path d="M 0,60 a 30 10 0 1 0 120,0 a 25 25 0 0 0 -120,0 a 25 25 0 0 0 120,0" class="stroke volume" data-type="volume"></path>

View File

@ -0,0 +1,3 @@
<path d="M 0,0 h 120 v 120 h -120 z" class="stroke area" data-type="area"></path>
<path d="M 0,0 h 120 m 0,120 h -120 m 120,0 v -120 m -120,0 v 120" class="stroke perimeter" data-type="perimeter"></path>
<path d="M 0,0 l 120,120" class="stroke special diagonal" data-type="diagonal"></path>

77
t/Geometry.t Normal file
View File

@ -0,0 +1,77 @@
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
use Test::Deep;
use DDG::Test::Goodie;
use utf8;
zci answer_type => "geometry";
zci is_cached => 1;
# Build a structured answer that should match the response from the Perl file
sub build_structured_answer {
my ( $title, $formulas, $svg ) = @_;
return "plain text response", structured_answer => {
data => {
title => ucfirst($title),
formulas => $formulas,
svg => $svg,
},
templates => {
group => "text",
options => {
subtitle_content => 'DDH.geometry.subtitle'
}
}
};
}
# Use this to build expected results for your tests.
sub build_test { test_zci( build_structured_answer(@_) ) }
ddg_goodie_test(
[qw( DDG::Goodie::Geometry )],
# First Param = Name of object
# Second Param = Array of formula objects for expected object
# Third Param = SVG of expected object
'calc square' => build_test(
'square',
{
area => { color => "#F1A031", html => "a<sup>2</sup>", nameCaps => "Area", symbol => "A" },
diagonal => { color => "#4495D4", html => "a√2", nameCaps => "Diagonal", symbol => "e" },
perimeter => { color => "#5B9E4D", html => "4a", nameCaps => "Perimeter", symbol => "u" }
},
'<path d="M 0,0 h 120 v 120 h -120 z" class="stroke area" data-type="area"></path> <path d="M 0,0 h 120 m 0,120 h -120 m 120,0 v -120 m -120,0 v 120" class="stroke perimeter" data-type="perimeter"></path> <path d="M 0,0 l 120,120" class="stroke special diagonal" data-type="diagonal"></path>',
),
'area of a square' => build_test(
'square',
{
area => { color => "#F1A031", html => "a<sup>2</sup>", nameCaps => "Area", symbol => "A" },
diagonal => { color => "#4495D4", html => "a√2", nameCaps => "Diagonal", symbol => "e" },
perimeter => { color => "#5B9E4D", html => "4a", nameCaps => "Perimeter", symbol => "u" }
},
'<path d="M 0,0 h 120 v 120 h -120 z" class="stroke area" data-type="area"></path> <path d="M 0,0 h 120 m 0,120 h -120 m 120,0 v -120 m -120,0 v 120" class="stroke perimeter" data-type="perimeter"></path> <path d="M 0,0 l 120,120" class="stroke special diagonal" data-type="diagonal"></path>',
),
'volume of sphere' => build_test(
'sphere',
{
volume => { color => "#DE5833", html => "4/3πr<sup>3</sup>", nameCaps => "Volume", symbol => "V" },
surface => { color => "#F1A031", html => "4πr<sup>2</sup>", nameCaps => "Surface", symbol => "S" },
},
'<path d="M 0,60 a 25 25 0 0 0 120,0 a 25 25 0 0 0 -120,0" class="fill surface" data-type="surface"></path> <path d="M 0,60 a 30 10 0 0 1 120,0" class="stroke backface"></path> <path d="M 0,60 a 30 10 0 0 1 120,0" class="stroke backface" data-type="volume"></path> <path d="M 0,60 a 30 10 0 1 0 120,0 a 25 25 0 0 0 -120,0 a 25 25 0 0 0 120,0" class="stroke volume" data-type="volume"></path>',
),
# Does Not match to
'calc banana' => undef,
'formula of shirt' => undef,
'' => undef,
' ' => undef,
);
done_testing;