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 casesmaster
parent
67f6e084f2
commit
c5816891e4
|
@ -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;
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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"
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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;
|
Loading…
Reference in New Issue