├── ex
├── fullVertical.PNG
├── halfVertical.PNG
├── fullHorizontal.PNG
└── halfHorizontal.PNG
├── assets
├── css
│ └── rink-style.css
└── js
│ └── rinkPlot.js
├── README.md
└── rinks.html
/ex/fullVertical.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/war-on-ice/icerink/HEAD/ex/fullVertical.PNG
--------------------------------------------------------------------------------
/ex/halfVertical.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/war-on-ice/icerink/HEAD/ex/halfVertical.PNG
--------------------------------------------------------------------------------
/ex/fullHorizontal.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/war-on-ice/icerink/HEAD/ex/fullHorizontal.PNG
--------------------------------------------------------------------------------
/ex/halfHorizontal.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/war-on-ice/icerink/HEAD/ex/halfHorizontal.PNG
--------------------------------------------------------------------------------
/assets/css/rink-style.css:
--------------------------------------------------------------------------------
1 | .blue-line{
2 | fill: blue;
3 | }
4 |
5 | .red-line{
6 | fill: red;
7 | }
8 |
9 | .red-faceoff{
10 | stroke: red;
11 | }
12 |
13 | .rink-face{
14 | stroke: gray;
15 | fill: white;
16 | }
17 |
18 | .goal-crease{
19 | fill: lightblue;
20 | stroke: red;
21 | }
22 |
23 | .center-line{
24 | fill: red;
25 | }
26 |
27 | .neutral-faceoff{
28 | stroke: blue;
29 | }
30 |
31 | .danger-line{
32 | stroke: gray;
33 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # icerink
2 | Ice rink generated via d3.js
3 |
4 | This is intended to be used for any hockey visualizations. The rink is modeled after the current NHL regulation rink markings.
5 |
6 | It's configurable to allow for full or half rinks, vertical or horizontal stylings. You can also configure the sizing. Example usage is located in rinks.html.
7 |
8 | ## Full Rink, Vertical
9 | 
10 |
11 | ## Full Rink, Horizontal
12 | 
13 |
14 | ## Half Rink, Vertical
15 | 
16 |
17 | ## Half Rink, Horizontal
18 | 
--------------------------------------------------------------------------------
/rinks.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Rink Plots
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | Rink Plots
13 | Full Rink, Horizontal
14 |
15 | Full Rink, Vertical
16 |
17 | Half Rink, Horizontal
18 |
19 | Half Rink, Vertial
20 |
21 |
22 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/assets/js/rinkPlot.js:
--------------------------------------------------------------------------------
1 | var RINK_MAP = function RinkMap(config){
2 |
3 | // all distances are in FT
4 | var RINK_CONFIG =
5 | {
6 | RINK_LENGTH: 200,
7 | RINK_WIDTH: 85,
8 | BLUE_LINE_WIDTH: 1,
9 | BOARDS_RADIUS: 28,
10 | RED_TO_BOARDS: 11,
11 | RED_TO_FACEOFF: 20,
12 | FACEOFF_RADIUS: 15,
13 | FACEOFF_DOT_RADIUS: 1,
14 | ZONE_LINE_WIDTH: (2/12),
15 | CREASE_RADIUS: 6,
16 | ZONE_LENGTH: 75,
17 | ZONE_TO_NEUTRAL_DOT: 5,
18 | CENTER_TO_NEUTRAL_DOT: 22,
19 | REF_CREASE_RADIUS: 10,
20 | CREASE_HEIGHT: 4,
21 | FACEOFF_HOR_LENGTH: 3,
22 | FACEOFF_VER_LENGTH: 4,
23 | FACEOFF_HOR_DIST_CEN: 2,
24 | FACEOFF_VER_DIST_CEN: (9/12),
25 | FACEOFF_OUT_MARK_LENGTH: 2,
26 | FACEOFF_OUT_MARK_DIST_BW: 5 + (7/12),
27 | TRAPEZOID_TOP: 22,
28 | TRAPEZOID_BOTTOM: 28
29 | };
30 |
31 | var RINK_COLOR =
32 | {
33 | BLUE_LINE: "blue",
34 | RINK_FILL: "white",
35 | GOAL_FILL: "lightblue"
36 | }
37 |
38 | var DANGER_ZONES = [{x1: -9.11, y1: 89.1},
39 | {x1: -22.1, y1: 68.9}, {x1: -22.1, y1: 53.9},
40 | {x1: -9.11, y1: 53.9}, {x1: -9.11, y1: 43.9},
41 | {x1: 9.11, y1: 43.9}, {x1: 9.11, y1: 53.9},
42 | {x1: 22.1, y1: 53.9}, {x1: 22.1, y1: 68.9},
43 | {x1: 9.11, y1: 89.1}, {x1: -9.11, y1: 89.1},
44 | {x1: -9.11, y1: 68.9}, {x1: 9.11, y1: 68.9},
45 | {x1: 9.11, y1: 89.1}, {x1: -9.11, y1: 89.1}];
46 |
47 | var p =
48 | {
49 | chartsize: {width: 500, height: 500},
50 | margins: {top: 30, bottom: 5, left: 10, right: 10},
51 | showDanger: false,
52 | horizontal: true,
53 | fullRink: true,
54 | watermark: ""
55 | }
56 |
57 | if (config !== "undefined"){
58 | for (var property in config){
59 | p[property] = config[property];
60 | }
61 | }
62 |
63 | // Get rink scale, scale all rink config distances
64 | var rinkScale = p.desiredWidth / RINK_CONFIG.RINK_WIDTH;
65 | for (var param in RINK_CONFIG){
66 | RINK_CONFIG[param] = rinkScale * RINK_CONFIG[param];
67 | }
68 |
69 | // CREATE CHART
70 | function chart() {
71 |
72 | function rinkLine(x, group, type){
73 | var lineWidth = RINK_CONFIG.BLUE_LINE_WIDTH;
74 | if (type === "center-line"){
75 | var lineWidth = RINK_CONFIG.BLUE_LINE_WIDTH/2;
76 | }
77 | group
78 | .append("rect")
79 | .attr("x", x - lineWidth)
80 | .attr("y", 0)
81 | .attr("width", lineWidth)
82 | .attr("height", RINK_CONFIG.RINK_WIDTH)
83 | .attr("class", type);
84 | }
85 |
86 | function rinkOutLine(group){
87 |
88 | group.append("path")
89 | .attr("d", rounded_rect(0,0, RINK_CONFIG.RINK_LENGTH *0.5, RINK_CONFIG.RINK_WIDTH, RINK_CONFIG.BOARDS_RADIUS, true, false, true, false))
90 | .attr("class", "rink-face")
91 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
92 |
93 | }
94 |
95 | // From stackOverflow http://stackoverflow.com/questions/12115691/svg-d3-js-rounded-corner-on-one-corner-of-a-rectangle
96 | // r -> radius, tl/tr/bl/br - top left/bottom right TRUE/FALSE for posessing rounded corner
97 | function rounded_rect(x, y, w, h, r, tl, tr, bl, br) {
98 | var retval;
99 | retval = "M" + (x + r) + "," + y;
100 | retval += "h" + (w - 2*r);
101 | if (tr) { retval += "a" + r + "," + r + " 0 0 1 " + r + "," + r; }
102 | else { retval += "h" + r; retval += "v" + r; }
103 | retval += "v" + (h - 2*r);
104 | if (br) { retval += "a" + r + "," + r + " 0 0 1 " + -r + "," + r; }
105 | else { retval += "v" + r; retval += "h" + -r; }
106 | retval += "h" + (2*r - w);
107 | if (bl) { retval += "a" + r + "," + r + " 0 0 1 " + -r + "," + -r; }
108 | else { retval += "h" + -r; retval += "v" + -r; }
109 | retval += "v" + (2*r - h);
110 | if (tl) { retval += "a" + r + "," + r + " 0 0 1 " + r + "," + -r; }
111 | else { retval += "v" + -r; retval += "h" + r; }
112 | retval += "z";
113 | return retval;
114 | }
115 |
116 | // Create goal crease with center at point (x,y) and width d
117 | function goalCrease(xPos, group){
118 |
119 | var creaseData = [ {"x": xPos, "y": (RINK_CONFIG.RINK_WIDTH/2 ) - RINK_CONFIG.CREASE_HEIGHT , "type": "M"},
120 | {"x": xPos + RINK_CONFIG.CREASE_HEIGHT, "y":(RINK_CONFIG.RINK_WIDTH/2 ) - RINK_CONFIG.CREASE_HEIGHT, "type": "L"},
121 | {"x": xPos + RINK_CONFIG.CREASE_HEIGHT, "y": (RINK_CONFIG.RINK_WIDTH/2 ) + RINK_CONFIG.CREASE_HEIGHT, "type": "A", "radius": RINK_CONFIG.CREASE_RADIUS},
122 | {"x": xPos, "y": (RINK_CONFIG.RINK_WIDTH/2 ) + RINK_CONFIG.CREASE_HEIGHT, "type": "L"}];
123 |
124 | var creaseFunction = function(input){
125 | var dStr = "";
126 | for (var i=0; i < input.length; i++){
127 | if (input[i]["type"] === "M" || input[i]["type"] === "L"){
128 | dStr += input[i]["type"] + input[i]["x"] + "," + input[i]["y"];
129 | }
130 | else if (input[i]["type"] === "A"){
131 | dStr += input[i]["type"] + input[i]["radius"] + "," + input[i]["radius"] + ",0,0,1," + input[i]["x"] + "," + input[i]["y"];
132 | }
133 | }
134 | return dStr;
135 | }
136 |
137 | group
138 | .append("path")
139 | .attr("d", creaseFunction(creaseData))
140 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
141 | .attr("class", "goal-crease");
142 | }
143 |
144 | // Create red-line at xPos to scale
145 | function redLine(x, group){
146 | var yDistance = RINK_CONFIG.BOARDS_RADIUS - Math.sqrt((2 * RINK_CONFIG.RED_TO_BOARDS * RINK_CONFIG.BOARDS_RADIUS) - (RINK_CONFIG.RED_TO_BOARDS * RINK_CONFIG.RED_TO_BOARDS));
147 | group
148 | .append("rect")
149 | .attr("x", x)
150 | .attr("y", yDistance)
151 | .attr("width", RINK_CONFIG.ZONE_LINE_WIDTH)
152 | .attr("height", RINK_CONFIG.RINK_WIDTH - 2 * yDistance)
153 | .attr("class", "red-line");
154 | }
155 |
156 | function faceOffDot(x,y, group){
157 | group
158 | .append("circle")
159 | .attr("cx", x)
160 | .attr("cy", y)
161 | .attr("r", RINK_CONFIG.FACEOFF_DOT_RADIUS)
162 | .attr("class", "red-line");
163 | }
164 |
165 | // Create face-off circule with radius r at point (x,y)
166 | function faceOffCircle(x, y, group){
167 | var faceOff = group.append("g")
168 | .attr("class", "faceoff");
169 |
170 |
171 | // outer face-off circle
172 | faceOff.append("circle")
173 | .attr("cx", x)
174 | .attr("cy", y)
175 | .attr("r", RINK_CONFIG.FACEOFF_RADIUS)
176 | .style("fill", RINK_COLOR.RINK_FILL)
177 | .attr("class", "red-faceoff")
178 | .style("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH);
179 |
180 | // face-off dot
181 | faceOff
182 | .append("circle")
183 | .attr("cx", x)
184 | .attr("cy", y)
185 | .attr("r", RINK_CONFIG.FACEOFF_DOT_RADIUS)
186 | .attr("class", "red-line");
187 |
188 | // Function/data to create four face-off markers
189 | var faceOffLineFunction = d3.svg.line()
190 | .x(function(d) {return RINK_CONFIG.FACEOFF_HOR_DIST_CEN + d.x; })
191 | .y(function(d) {return RINK_CONFIG.FACEOFF_VER_DIST_CEN + d.y; })
192 | .interpolate("linear");
193 | var faceOffLineData = [ {"x": RINK_CONFIG.FACEOFF_VER_LENGTH, "y": 0} ,{"x": 0, "y": 0},{"x": 0, "y": RINK_CONFIG.FACEOFF_HOR_LENGTH}];
194 |
195 | // Create four markers, each translated appropriately off-of (x,y)
196 | faceOff
197 | .append("path")
198 | .attr("d", faceOffLineFunction(faceOffLineData))
199 | .attr("class", "red-faceoff")
200 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
201 | .attr("fill", "none")
202 | .attr("transform", "translate(" + x + " , " + y + ")scale(-1, -1)");
203 | faceOff
204 | .append("path")
205 | .attr("d", faceOffLineFunction(faceOffLineData))
206 | .attr("class", "red-faceoff")
207 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
208 | .attr("fill", "none")
209 | .attr("transform", "translate(" + x + " , " + y + ")scale(1,-1)");
210 | faceOff
211 | .append("path")
212 | .attr("d", faceOffLineFunction(faceOffLineData))
213 | .attr("class", "red-faceoff")
214 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
215 | .attr("fill", "none")
216 | .attr("transform", "translate(" + x + " , " + y + ")");
217 | faceOff
218 | .append("path")
219 | .attr("d", faceOffLineFunction(faceOffLineData))
220 | .attr("class", "red-faceoff")
221 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
222 | .attr("fill", "none")
223 | .attr("transform", "translate(" + x + " , " + y + ")scale(-1, 1)");
224 |
225 | // Create two hash on outside of circle (each side)
226 | // Function/data to create outside line markers
227 | var outsideLineFunction = d3.svg.line()
228 | .x(function(d) {return d.x; })
229 | .y(function(d) {return d.y; })
230 | .interpolate("linear");
231 | var xStartOutsideLine = 0.5 * RINK_CONFIG.FACEOFF_OUT_MARK_DIST_BW * Math.tan(Math.acos(0.5 * RINK_CONFIG.FACEOFF_OUT_MARK_DIST_BW/RINK_CONFIG.FACEOFF_RADIUS));
232 | var outsideLineData = [ {"x": 0, "y": xStartOutsideLine} ,{"x": 0, "y": xStartOutsideLine + RINK_CONFIG.FACEOFF_OUT_MARK_LENGTH}];
233 | faceOff
234 | .append("path")
235 | .attr("d", outsideLineFunction(outsideLineData))
236 | .attr("class", "red-faceoff")
237 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
238 | .attr("fill", "none")
239 | .attr("transform", "translate(" + (x - 0.5 * RINK_CONFIG.FACEOFF_OUT_MARK_DIST_BW) + " , " + y + ")");
240 | faceOff
241 | .append("path")
242 | .attr("d", outsideLineFunction(outsideLineData))
243 | .attr("class", "red-faceoff")
244 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
245 | .attr("fill", "none")
246 | .attr("transform", "translate(" + (x + 0.5 * RINK_CONFIG.FACEOFF_OUT_MARK_DIST_BW) + " , " + y + ")");
247 | faceOff
248 | .append("path")
249 | .attr("d", outsideLineFunction(outsideLineData))
250 | .attr("class", "red-faceoff")
251 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
252 | .attr("fill", "none")
253 | .attr("transform", "translate(" + (x + 0.5 * RINK_CONFIG.FACEOFF_OUT_MARK_DIST_BW) + " , " + y + "), scale(1,-1)");
254 | faceOff
255 | .append("path")
256 | .attr("d", outsideLineFunction(outsideLineData))
257 | .attr("class", "red-faceoff")
258 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
259 | .attr("fill", "none")
260 | .attr("transform", "translate(" + (x - 0.5 * RINK_CONFIG.FACEOFF_OUT_MARK_DIST_BW) + " , " + y + "), scale(1,-1)");
261 |
262 | }
263 |
264 | function trapezoid(xPos, group){
265 |
266 | var trapezoidFunction = d3.svg.line()
267 | .x(function(d) {return RINK_CONFIG.RED_TO_BOARDS + d.x; })
268 | .y(function(d) {return (0.5 * (RINK_CONFIG.RINK_WIDTH - RINK_CONFIG.CENTER_TO_NEUTRAL_DOT)) + d.y; })
269 | .interpolate("linear");
270 |
271 | var trapezoidData = [ {"x": -1 * RINK_CONFIG.RED_TO_BOARDS, "y": -0.5 * (RINK_CONFIG.TRAPEZOID_BOTTOM - RINK_CONFIG.TRAPEZOID_TOP)} ,{"x":0 , "y": 0}];
272 |
273 | group
274 | .append("path")
275 | .attr("d", trapezoidFunction(trapezoidData))
276 | .attr("class", "red-faceoff")
277 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
278 | .attr("fill", "none")
279 | .attr("transform", "translate(" + xPos + " ,0)");
280 | group
281 | .append("path")
282 | .attr("d", trapezoidFunction(trapezoidData))
283 | .attr("class", "red-faceoff")
284 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
285 | .attr("fill", "none")
286 | .attr("transform", "scale(1,-1),translate(" + xPos + "," + (-1 * RINK_CONFIG.RINK_WIDTH) + ")");
287 | }
288 |
289 | function neutralCircle(x, y, group){
290 |
291 | var circleData = [ {"x": x, "y": y - RINK_CONFIG.FACEOFF_RADIUS, "type": "M"},
292 | {"x": x, "y": y + RINK_CONFIG.FACEOFF_RADIUS, "type": "A", "radius": RINK_CONFIG.FACEOFF_RADIUS, "dir": 0}];
293 |
294 | group
295 | .append("path")
296 | .attr("d", dStringCreator(circleData))
297 | .attr("class", "neutral-faceoff")
298 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
299 | .attr("fill", "none");
300 | }
301 |
302 | var dStringCreator = function(input){
303 | var dStr = "";
304 | for (var i=0; i < input.length; i++){
305 | if (input[i]["type"] === "M" || input[i]["type"] === "L"){
306 | dStr += input[i]["type"] + input[i]["x"] + " " + input[i]["y"];
307 | }
308 | else if (input[i]["type"] === "A"){
309 | dStr += input[i]["type"] + input[i]["radius"] + "," + input[i]["radius"] + ",0,0," + input[i]["dir"] + "," + input[i]["x"] + "," + input[i]["y"];
310 | }
311 | else{
312 | "neither";
313 | }
314 | }
315 | return dStr;
316 | }
317 |
318 | function refereeCrease(xPos, group){
319 | var creaseData = [ {"x": xPos - RINK_CONFIG.REF_CREASE_RADIUS, "y": RINK_CONFIG.RINK_WIDTH, "type": "M"},
320 | {"x": xPos, "y": RINK_CONFIG.RINK_WIDTH - RINK_CONFIG.REF_CREASE_RADIUS, "type": "A", "radius": RINK_CONFIG.REF_CREASE_RADIUS, "dir": 1}];
321 |
322 | group
323 | .append("path")
324 | .attr("d", dStringCreator(creaseData))
325 | .attr("class", "red-faceoff")
326 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
327 | .attr("fill", "none");
328 | }
329 |
330 | function dangerZones(zoneCoords, group){
331 | var dangerZoneGroup = group.append("g").attr("class","danger-zone");
332 | var dangerData = [];
333 |
334 | dangerData[0] = {"type": "M", "x": (0.5 * RINK_CONFIG.RINK_LENGTH - zoneCoords[0]["y1"] * rinkScale), "y": (0.5 * RINK_CONFIG.RINK_WIDTH +zoneCoords[0]["x1"] * rinkScale)};
335 |
336 | var i = 1;
337 | for (coord in zoneCoords){
338 | dangerData[i] = {};
339 | dangerData[i]["x"] = 0.5 * RINK_CONFIG.RINK_LENGTH - zoneCoords[coord]["y1"] * rinkScale;
340 | dangerData[i]["y"] = 0.5 * RINK_CONFIG.RINK_WIDTH + zoneCoords[coord]["x1"] * rinkScale;
341 | dangerData[i]["type"] = "L";
342 | i++;
343 | }
344 |
345 | dangerZoneGroup
346 | .append("path")
347 | .attr("d", dStringCreator(dangerData))
348 | .attr("class", "danger-line")
349 | .attr("stroke-width", RINK_CONFIG.ZONE_LINE_WIDTH)
350 | .style("stroke-dasharray", "10,10")
351 | .attr("fill", "none");
352 | }
353 |
354 | function waterMark(xPos, yPos, waterMarkText, group){
355 | group
356 | .append("text")
357 | .style("fill", "lightgray")
358 | .style("font-size", "18px")
359 | .style("text-anchor", "middle")
360 | .style("alignment-baseline", "middle")
361 | .attr("transform", "translate(" + xPos +"," + yPos + ") rotate(90)")
362 | .text(waterMarkText);
363 | }
364 |
365 | var zones = p.parent.append("g").attr("class", "zones");
366 |
367 | // RINK CONFIGURATON -- BOTH ZONES
368 | var zone1 = zones.append("g")
369 | .attr("class", "zone1");
370 | var zone1Elements = zone1.append("g").attr("class", "rinkElements");
371 | generateRinkElements(zone1Elements);
372 |
373 | function generateRinkElements(zoneGroup){
374 | // RINK OUT LINE, CENTER LINE
375 | rinkOutLine(zoneGroup);
376 | rinkLine(0.5 * RINK_CONFIG.RINK_LENGTH, zoneGroup, "center-line");
377 |
378 | // NEUTRAL ZONE
379 | refereeCrease(0.5 * RINK_CONFIG.RINK_LENGTH, zoneGroup);
380 | neutralCircle(0.5 * RINK_CONFIG.RINK_LENGTH, 0.5 * RINK_CONFIG.RINK_WIDTH, zoneGroup);
381 |
382 | faceOffDot(RINK_CONFIG.ZONE_LENGTH + RINK_CONFIG.ZONE_TO_NEUTRAL_DOT, (RINK_CONFIG.RINK_WIDTH/2 - RINK_CONFIG.CENTER_TO_NEUTRAL_DOT), zoneGroup);
383 | faceOffDot(RINK_CONFIG.ZONE_LENGTH + RINK_CONFIG.ZONE_TO_NEUTRAL_DOT, (RINK_CONFIG.RINK_WIDTH/2 + RINK_CONFIG.CENTER_TO_NEUTRAL_DOT), zoneGroup);
384 |
385 | // O-ZONE
386 | rinkLine(RINK_CONFIG.ZONE_LENGTH, zoneGroup, "blue-line");
387 | faceOffCircle(RINK_CONFIG.RED_TO_BOARDS + RINK_CONFIG.RED_TO_FACEOFF, RINK_CONFIG.RINK_WIDTH/2 - RINK_CONFIG.CENTER_TO_NEUTRAL_DOT, zoneGroup);
388 | faceOffCircle(RINK_CONFIG.RED_TO_BOARDS + RINK_CONFIG.RED_TO_FACEOFF, RINK_CONFIG.RINK_WIDTH/2 + RINK_CONFIG.CENTER_TO_NEUTRAL_DOT, zoneGroup);
389 |
390 | //GOAL LINES
391 | redLine(RINK_CONFIG.RED_TO_BOARDS, zoneGroup);
392 | trapezoid(0, zoneGroup);
393 | goalCrease(RINK_CONFIG.RED_TO_BOARDS, zoneGroup);
394 |
395 | // Show danger if flagged
396 | if (p.showDanger){
397 | dangerZones(DANGER_ZONES, zoneGroup);
398 | }
399 |
400 | waterMark(RINK_CONFIG.RED_TO_BOARDS /2, RINK_CONFIG.RINK_WIDTH/2, p.watermark, zoneGroup);
401 |
402 | }
403 |
404 | // FULL RINK. Generate second zone.
405 | if (p.fullRink){
406 | zoneName = "zone2";
407 | var zone2 = zones.append("g")
408 | .attr("class", zoneName);
409 |
410 | var zone2Elements = zone2.append("g").attr("class", "rinkElements");
411 |
412 | generateRinkElements(zone2Elements);
413 | // FULL RINK, HORIZONTAL. Rotate second zone.
414 | if (p.horizontal){
415 | p.parent.selectAll(".zone2")
416 | .attr("transform", "scale(-1, 1)translate(" + (-1 * (RINK_CONFIG.RINK_LENGTH)) + ",0)");
417 |
418 | }
419 | // FULL RINK, VERTICAL. rotate/move both zones.
420 | else{
421 | p.parent.selectAll(".zone1")
422 | .attr("transform", "rotate(-90)translate(" + (-1 * (RINK_CONFIG.RINK_LENGTH)) +",0)");
423 | p.parent.selectAll(".zone2")
424 | .attr("transform", "scale(-1,1)rotate(90)");
425 | }
426 | }
427 | else{
428 | // HALF RINK, VERTICAL.
429 | if (!p.horizontal){
430 | p.parent.selectAll(".zone1")
431 | .attr("transform", "rotate(-90)translate(" + (-1*(RINK_CONFIG.RINK_LENGTH/2)) +",0)");
432 |
433 | }
434 | }
435 | // move for margins
436 | p.parent.selectAll(".zones").attr("transform", "translate(" + p.margins.left + "," + p.margins.top + ")");
437 |
438 | }
439 | return chart;
440 | };
441 |
442 |
--------------------------------------------------------------------------------