Skip to content

Commit

Permalink
Merge pull request #14 from andrewpucci/13-shot-correlation
Browse files Browse the repository at this point in the history
13 shot correlation
  • Loading branch information
andrewpucci authored Jan 31, 2019
2 parents 6c9c650 + b276167 commit 4883a1e
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 84 deletions.
12 changes: 6 additions & 6 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.5.2)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
autoprefixer-rails (6.3.7)
execjs
colorator (1.1.0)
concurrent-ruby (1.1.3)
concurrent-ruby (1.1.4)
em-websocket (0.5.1)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0.6.0)
eventmachine (1.2.7)
execjs (2.7.0)
ffi (1.9.25)
ffi (1.10.0)
forwardable-extended (2.6.0)
http_parser.rb (0.6.0)
i18n (0.9.5)
Expand Down Expand Up @@ -50,12 +50,12 @@ GEM
forwardable-extended (~> 2.6)
public_suffix (3.0.3)
rb-fsevent (0.10.3)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
rb-inotify (0.10.0)
ffi (~> 1.0)
rouge (3.3.0)
ruby_dep (1.5.0)
safe_yaml (1.0.4)
sass (3.7.2)
sass (3.7.3)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
Expand Down
154 changes: 107 additions & 47 deletions _assets/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(() => {
document.addEventListener("DOMContentLoaded", (event) => {
const rink = document.getElementById("rink");
const unitSelector = document.getElementById("unit-selector");
const pt = rink.createSVGPoint();
Expand All @@ -9,41 +9,81 @@
let tableData = [];
let shotCounter = 0;

function cursorPoint(evt) {
pt.x = evt.clientX;
pt.y = evt.clientY;
function cursorPoint(event) {
pt.x = event.clientX;
pt.y = event.clientY;
return pt.matrixTransform(rink.getScreenCTM().inverse());
}

function emphasizeShot(shot) {
shot.setAttribute("r", 45);
shot.parentElement.querySelectorAll(".shot").forEach((item) => {
item.classList.add("faded");
});
shot.classList.remove("faded");
}

function deemphasizeShot(shot) {
shot.setAttribute("r", 25);
shot.parentElement.querySelectorAll(".shot").forEach((item) => {
item.classList.remove("faded");
});
}

function emphasizeRow(row) {
row.classList.add("emphasized-row");
}

function deemphasizeRow(row) {
row.classList.remove("emphasized-row");
}

function drawCircle(elem, id, shotLocation) {
const ns = "http://www.w3.org/2000/svg";
const circle = document.createElementNS(ns, "circle");
circle.setAttributeNS(null, "id", id);
circle.setAttributeNS(null, "cx", shotLocation.x);
circle.setAttributeNS(null, "cy", shotLocation.y);
circle.setAttributeNS(null, "r", 25);
circle.setAttributeNS(null, "fill", shotColor);
circle.setAttribute("id", `shot-${id}`);
circle.classList.add("shot");
circle.setAttribute("cx", shotLocation.x);
circle.setAttribute("cy", shotLocation.y);
circle.setAttribute("r", 45);
circle.setAttribute("fill", shotColor);
circle.addEventListener("mouseover", (event) => {
emphasizeShot(event.currentTarget);
try {
emphasizeRow(document.getElementById(`row-${id}`));
}
catch(error) {
console.error("Row cannot be highlighted because shot is not listed in current table view.");
}
});
circle.addEventListener("mouseout", (event) => {
deemphasizeShot(event.currentTarget);
try {
deemphasizeRow(document.getElementById(`row-${id}`));
}
catch(error) {
console.error("Row cannot be highlighted because shot is not listed in current table view.");
}
});
elem.appendChild(circle);
}

function generateX(num, unitType) {
if (unitType === "cm") {
return Math.round((num - xOffset.NA) * 2.54, 1);
} else if (unitType === "in") {
return Math.round(num - xOffset.NA, 1);
} else if (unitType === "ft") {
return Math.round((num - xOffset.NA) / 12, 1);
}
const formulas = {
"cm": Math.round((num - xOffset.NA) * 2.54, 1),
"in": Math.round(num - xOffset.NA, 1),
"ft": Math.round((num - xOffset.NA) / 12, 1)
};
return formulas[unitType];
}

function generateY(num, unitType) {
if (unitType === "cm") {
return Math.round(-(num - yOffset.NA) * 2.54, 1);
} else if (unitType === "in") {
return Math.round(-(num - yOffset.NA), 1);
} else if (unitType === "ft") {
return Math.round(-(num - yOffset.NA) / 12, 1);
const formulas = {
"cm": Math.round(-(num - yOffset.NA) * 2.54, 1),
"in": Math.round(-(num - yOffset.NA), 1),
"ft": Math.round(-(num - yOffset.NA) / 12, 1)
}
return formulas[unitType];
}

function convertUnits(coordinates) {
Expand All @@ -63,6 +103,7 @@

const table = $("#coord-table");
table.removeClass("d-none");
document.getElementById("unit-selector").classList.add("mb-3");
table.DataTable({
dom: "rt<'mb-3' i><'row'<'col-6' B><'col-6' p>>",
destroy: true,
Expand All @@ -74,6 +115,17 @@
{ title: "X", data: "x" },
{ title: "Y", data: "y" },
],
rowId: (convertedData) => { return `row-${convertedData.id}`},
createdRow: function(row, data, dataIndex) {
row.addEventListener("mouseover", (event) => {
emphasizeShot(document.getElementById(`shot-${data.id}`));
emphasizeRow(row);
});
row.addEventListener("mouseout", (event) => {
deemphasizeShot(document.getElementById(`shot-${data.id}`));
deemphasizeRow(row);
});
},
buttons: [
{
extend: "csvHtml5",
Expand All @@ -84,30 +136,38 @@
});
}

unitSelector.addEventListener("change", () => {
buildTable();
unitSelector.addEventListener("change", buildTable);

// Hide svg title so browser tooltip is not shown on hover
rink.addEventListener("mouseover", (event) => {
const svg = event.currentTarget;
svg.setAttribute("data-title", svg.getElementsByTagName("title")[0].innerHTML);
svg.getElementsByTagName("title")[0].innerHTML = "";
});

// Replace svg title
rink.addEventListener("mouseout", (event) => {
const svg = event.currentTarget;
svg.getElementsByTagName("title")[0].innerHTML = svg.getAttribute("data-title");
svg.removeAttribute("data-title");
});

rink.addEventListener(
"mousedown",
evt => {
const shotID = ++shotCounter;
const shotLocation = cursorPoint(evt);
let coordinates = {
x: shotLocation.x,
y: shotLocation.y,
id: shotID
};

// add coordinates to table
tableData.unshift(coordinates);

// build table
buildTable();

// draw a circle on the rink at shot location
drawCircle(rink, shotID, shotLocation);
},
false
);
})();
rink.addEventListener("mousedown", (event) => {
const shotID = ++shotCounter;
const shotLocation = cursorPoint(event);
let coordinates = {
x: shotLocation.x,
y: shotLocation.y,
id: shotID
};

// add coordinates to table
tableData.unshift(coordinates);

// build table
buildTable();

// draw a circle on the rink at shot location
drawCircle(rink, shotID, shotLocation);
}, false);
});
1 change: 1 addition & 0 deletions _assets/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
@import "type";
@import "nav";
@import "cards";
@import "svg";
// @import "bootstrap/scss/alert";
// @import "bootstrap/scss/badge";
// @import "bootstrap/scss/breadcrumb";
Expand Down
7 changes: 7 additions & 0 deletions _sass/_svg.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.shot {
transition: opacity 0.2s ease-in;
}

.faded {
opacity: 0.5;
}
5 changes: 5 additions & 0 deletions _sass/_tables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,8 @@ table.dataTable {
#coord-table_wrapper {
padding: 0;
}

.emphasized-row {
background-color: lighten(#D59E0D, 40%);
transition: background-color 0.2s ease-in;
}
62 changes: 31 additions & 31 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ ajv@^5.2.3, ajv@^5.3.0:
json-schema-traverse "^0.3.0"

ansi-escapes@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
integrity sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==
version "3.2.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b"
integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==

ansi-regex@^2.0.0:
version "2.1.1"
Expand Down Expand Up @@ -83,9 +83,9 @@ balanced-match@^1.0.0:
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=

bootstrap@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.1.3.tgz#0eb371af2c8448e8c210411d0cb824a6409a12be"
integrity sha512-rDFIzgXcof0jDyjNosjv4Sno77X4KuPeFxG2XZZv1/Kc8DRVGVADdoQyyOVDwPqL36DDmtCQbrpMCqvpPLJQ0w==
version "4.2.1"
resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.2.1.tgz#8f8bdca024dbf0e8644da32e918c8a03a90a5757"
integrity sha512-tt/7vIv3Gm2mnd/WeDx36nfGGHleil0Wg8IeB7eMrVkY0fZ5iTaBisSh8oNANc2IBsCc6vCgCNTIM/IEN0+50Q==

brace-expansion@^1.1.7:
version "1.1.11"
Expand Down Expand Up @@ -124,9 +124,9 @@ chalk@^1.1.3:
supports-color "^2.0.0"

chalk@^2.0.0, chalk@^2.1.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e"
integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
Expand Down Expand Up @@ -409,7 +409,7 @@ functional-red-black-tree@^1.0.1:
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=

glob@^7.0.5, glob@^7.1.2:
glob@^7.1.2, glob@^7.1.3:
version "7.1.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1"
integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
Expand All @@ -422,9 +422,9 @@ glob@^7.0.5, glob@^7.1.2:
path-is-absolute "^1.0.0"

globals@^11.0.1:
version "11.9.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.9.0.tgz#bde236808e987f290768a93d065060d78e6ab249"
integrity sha512-5cJVtyXWH8PiJPVLZzzoIizXx944O4OmRro5MWKx5fT4MgcN7OfaMutPeaTdJCCURwbWdhhcCWcKIffPnmTzBg==
version "11.10.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-11.10.0.tgz#1e09776dffda5e01816b3bb4077c8b59c24eaa50"
integrity sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==

graceful-fs@^4.1.2:
version "4.1.15"
Expand Down Expand Up @@ -529,9 +529,9 @@ js-tokens@^3.0.2:
integrity sha1-mGbfOVECEw449/mWvOtlRDIJwls=

js-yaml@^3.9.1:
version "3.12.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1"
integrity sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==
version "3.12.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600"
integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
Expand Down Expand Up @@ -560,12 +560,12 @@ lodash@^4.17.4, lodash@^4.3.0:
integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==

lru-cache@^4.0.1:
version "4.1.4"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.4.tgz#51cc46e8e6d9530771c857e24ccc720ecdbcc031"
integrity sha512-EPstzZ23znHUVLKj+lcXO1KvZkrlw+ZirdwvOmnAnA/1PB4ggyXJ77LRkCqkff+ShQ+cqoxCxLQOh4cKITO5iA==
version "4.1.5"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd"
integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==
dependencies:
pseudomap "^1.0.2"
yallist "^3.0.2"
yallist "^2.1.2"

mimic-fn@^1.0.0:
version "1.2.0"
Expand Down Expand Up @@ -673,9 +673,9 @@ process-nextick-args@~2.0.0:
integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==

progress@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.1.tgz#c9242169342b1c29d275889c95734621b1952e31"
integrity sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==
version "2.0.3"
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==

pseudomap@^1.0.2:
version "1.0.2"
Expand Down Expand Up @@ -722,11 +722,11 @@ restore-cursor@^2.0.0:
signal-exit "^3.0.2"

rimraf@~2.6.2:
version "2.6.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36"
integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==
version "2.6.3"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab"
integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==
dependencies:
glob "^7.0.5"
glob "^7.1.3"

run-async@^2.2.0:
version "2.3.0"
Expand Down Expand Up @@ -907,7 +907,7 @@ write@^0.2.1:
dependencies:
mkdirp "^0.5.1"

yallist@^3.0.2:
version "3.0.3"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9"
integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==
yallist@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"
integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=

0 comments on commit 4883a1e

Please sign in to comment.