You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							134 lines
						
					
					
						
							4.0 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							134 lines
						
					
					
						
							4.0 KiB
						
					
					
				
								<template>
							 | 
						|
								  <QuickNav />
							 | 
						|
								
							 | 
						|
								  <!-- CONTENT -->
							 | 
						|
								  <section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
							 | 
						|
								    <!-- Breadcrumb -->
							 | 
						|
								    <div class="mb-8">
							 | 
						|
								      <!-- Back -->
							 | 
						|
								      <div class="text-lg text-center font-light relative px-7">
							 | 
						|
								        <h1
							 | 
						|
								          class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
							 | 
						|
								          @click="$router.back()"
							 | 
						|
								        >
							 | 
						|
								          <fa icon="chevron-left" class="fa-fw"></fa>
							 | 
						|
								        </h1>
							 | 
						|
								      </div>
							 | 
						|
								
							 | 
						|
								      <!-- Heading -->
							 | 
						|
								      <h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
							 | 
						|
								        Achievements & Statistics
							 | 
						|
								      </h1>
							 | 
						|
								    </div>
							 | 
						|
								
							 | 
						|
								    <div>
							 | 
						|
								      Here is a view of the activity you can see.
							 | 
						|
								      <ul class="list-disc outside ml-4">
							 | 
						|
								        <li>Each identity and claim has a unique position.</li>
							 | 
						|
								        <!-- eslint-disable prettier/prettier --><!-- If we format prettier then there is extra space at the start of the line. -->
							 | 
						|
								        <li>Each will show at their time of appearance relative to all others.</li>
							 | 
						|
								        <li>Note that the ones on the left and right edges are randomized
							 | 
						|
								          because their data isn't all visible to you.
							 | 
						|
								        </li>
							 | 
						|
								        <!-- eslint-enable -->
							 | 
						|
								      </ul>
							 | 
						|
								    </div>
							 | 
						|
								
							 | 
						|
								    <div class="mt-3">
							 | 
						|
								      <div v-if="worldProperties.startTime">
							 | 
						|
								        <label>Time Range: </label>
							 | 
						|
								        {{ worldProperties.startTime }}
							 | 
						|
								        -
							 | 
						|
								        {{ worldProperties.endTime }}
							 | 
						|
								      </div>
							 | 
						|
								      <div v-if="worldProperties.animationDurationSeconds">
							 | 
						|
								        <label>Animation Time: </label>
							 | 
						|
								        {{ worldProperties.animationDurationSeconds }} seconds
							 | 
						|
								      </div>
							 | 
						|
								    </div>
							 | 
						|
								    <button class="float-right text-blue-600" @click="captureGraphics()">Screenshot</button>
							 | 
						|
								    <div id="scene-container" class="h-screen"></div>
							 | 
						|
								  </section>
							 | 
						|
								</template>
							 | 
						|
								<script lang="ts">
							 | 
						|
								import { SVGRenderer } from "three/examples/jsm/renderers/SVGRenderer.js";
							 | 
						|
								import { Component, Vue } from "vue-facing-decorator";
							 | 
						|
								import { World } from "@/components/World/World.js";
							 | 
						|
								import QuickNav from "@/components/QuickNav.vue";
							 | 
						|
								
							 | 
						|
								interface RendererSVGType {
							 | 
						|
								  domElement: Element;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								interface Dictionary<T> {
							 | 
						|
								  [key: string]: T;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								interface Notification {
							 | 
						|
								  group: string;
							 | 
						|
								  type: string;
							 | 
						|
								  title: string;
							 | 
						|
								  text: string;
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								@Component({ components: { World, QuickNav } })
							 | 
						|
								export default class StatisticsView extends Vue {
							 | 
						|
								  $notify!: (notification: Notification, timeout?: number) => void;
							 | 
						|
								
							 | 
						|
								  world: World;
							 | 
						|
								  worldProperties: Dictionary<number> = {};
							 | 
						|
								
							 | 
						|
								  mounted() {
							 | 
						|
								    try {
							 | 
						|
								      const container = document.querySelector("#scene-container");
							 | 
						|
								      const newWorld = new World(container, this);
							 | 
						|
								      newWorld.start();
							 | 
						|
								      this.world = newWorld;
							 | 
						|
								    } catch (err: unknown) {
							 | 
						|
								      const error = err as Error;
							 | 
						|
								      this.$notify(
							 | 
						|
								        {
							 | 
						|
								          group: "alert",
							 | 
						|
								          type: "danger",
							 | 
						|
								          title: "Mounting Error",
							 | 
						|
								          text: error.message,
							 | 
						|
								        },
							 | 
						|
								        -1,
							 | 
						|
								      );
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  public captureGraphics() {
							 | 
						|
								    /**
							 | 
						|
								     * This yields an SVG that only shows white and black highlights
							 | 
						|
								     // from https://stackoverflow.com/questions/27632621/exporting-from-three-js-scene-to-svg-or-other-vector-format
							 | 
						|
								     **/
							 | 
						|
								    const rendererSVG = new SVGRenderer();
							 | 
						|
								    rendererSVG.setSize(window.innerWidth, window.innerHeight);
							 | 
						|
								    rendererSVG.render(this.world.scene, this.world.camera);
							 | 
						|
								    ExportToSVG(rendererSVG, "test.svg");
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  public setWorldProperty(propertyName: string, propertyValue: number) {
							 | 
						|
								    this.worldProperties[propertyName] = propertyValue;
							 | 
						|
								  }
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								function ExportToSVG(rendererSVG: RendererSVGType, filename: string) {
							 | 
						|
								  const XMLS = new XMLSerializer();
							 | 
						|
								  const svgfile = XMLS.serializeToString(rendererSVG.domElement);
							 | 
						|
								  const svgData = svgfile;
							 | 
						|
								  const preface = '<?xml version="1.0" standalone="no"?>\r\n';
							 | 
						|
								  const svgBlob = new Blob([preface, svgData], {
							 | 
						|
								    type: "image/svg+xml;charset=utf-8",
							 | 
						|
								  });
							 | 
						|
								  const svgUrl = URL.createObjectURL(svgBlob);
							 | 
						|
								  const downloadLink = document.createElement("a");
							 | 
						|
								
							 | 
						|
								  downloadLink.href = svgUrl;
							 | 
						|
								  downloadLink.download = filename;
							 | 
						|
								  document.body.appendChild(downloadLink);
							 | 
						|
								  downloadLink.click();
							 | 
						|
								  document.body.removeChild(downloadLink);
							 | 
						|
								}
							 | 
						|
								</script>
							 | 
						|
								
							 |