Commit c0f2ef47 authored by Rushikesh Padsala's avatar Rushikesh Padsala
Browse files

added HFT viewer

parent f67ddac7
/*
* Copyright 2019 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { subclass, property } from "esri/core/accessorSupport/decorators";
import { tsx } from "esri/widgets/support/widget";
import AppState from "../../AppState";
import Widget from "esri/widgets/Widget";
@subclass("widgets/Popup")
class Popup extends Widget {
@property({aliasOf: "appState.popupInfo.active"})
active: boolean = false;
@property({aliasOf: "appState.popupInfo.image"})
image: string;
@property({aliasOf: "appState.popupInfo.credit"})
credit: string;
@property()
appState: AppState;
constructor(args: {appState: AppState, container: string}) {
super(args);
}
render() {
const activeClass = {
"active": this.active
};
const image = this.image ? (<img src={this.image}/>) : null;
const credit = this.credit ? (<div class="credit"><div>{this.credit}</div></div>) : null;
return (<div bind={this} key={this} class={this.classes("popup", activeClass)} onclick={this.onClick.bind(this)}>{image}{credit}</div>);
}
private onClick(event: Event) {
event.stopPropagation();
this.active = true;
}
}
export = Popup;
/*
* Copyright 2019 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { subclass, property } from "esri/core/accessorSupport/decorators";
import Accessor from "esri/core/Accessor";
@subclass("PopupInfo")
class PopupInfo extends Accessor {
@property()
image: string;
@property()
credit: string;
@property()
active: boolean = true;
}
export = PopupInfo;
@import "../../../../css/variables.scss";
@import "../../../../css/mixins.scss";
#appDiv #popup {
z-index: 100;
position: absolute;
width: 0%;
height: 0%;
overflow: hidden;
left: 50%;
top: 50%;
background: #fff;
opacity: 0;
box-shadow: 2px 2px 5px rgba(0,0,0,0.5);
// display: none;
@include transition(width 0.5s ease, height 0.5s ease, opacity 0.5s ease, left 0.5s ease, top 0.5s ease);
& > img {
width: 100%;
}
&.active {
// display: block;
width: 90%;
height: 90%;
left: 5%;
top: 5%;
opacity: 1;
cursor: pointer;
pointer-events: all;
}
.credit {
position: absolute;
width: 100%;
bottom: -2px;
background: rgba(0,0,0,0.5);
& > div {
margin: 10px 20px;
}
}
}
/*
* Copyright 2019 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { subclass, property } from "esri/core/accessorSupport/decorators";
import { tsx } from "esri/widgets/support/widget";
import Widget from "esri/widgets/Widget";
import Collection from "esri/core/Collection";
const daysName = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
interface TimetableCtorArgs {
dates: Collection<DayTimetable>;
}
interface DayTimetableCtorArgs {
opens: string;
closes: string;
}
@subclass("widgets/Timetable")
export class DayTimetable extends Widget {
@property()
opens: string;
@property()
closes: string;
@property()
index = 0;
@property({dependsOn: ["opens", "index"]})
private get openDate() {
if (!this.opens) {
return new Date();
}
const time = this.opens.split(":").map((aTime) => parseInt(aTime));
return new Date(2019, 2, 18 + this.index, time[0], time[1]);
}
@property({dependsOn: ["closes", "index"]})
private get closeDate() {
if (!this.closes) {
return new Date();
}
const time = this.closes.split(":").map((aTime) => parseInt(aTime));
return new Date(2019, 2, 18 + this.index, time[0], time[1]);
}
render() {
const today = new Date();
if (today.getDay() === this.openDate.getDay()) {
return (<div class="daytime today">
<h3>Today</h3>
<div class="schedule">{this.openDate.getHours()}:00 - {this.closeDate.getHours()}:00</div>
</div>);
}
else {
return (<div class="daytime">
<h3>{daysName[this.openDate.getDay()]}</h3>
<div class="schedule">{this.openDate.getHours()}:00 - {this.closeDate.getHours()}:00</div>
</div>);
}
}
constructor(args: DayTimetableCtorArgs) {
super(args as any);
}
}
@subclass("widgets/Timetable")
export class Timetable extends Widget {
@property()
today = new Date();
@property()
dates: Collection<DayTimetable>;
render() {
const dates = this.dates.map(d => d.render()).toArray();
return (<div bind={this} key={this} class="timetable">{dates}</div>);
}
constructor(args: TimetableCtorArgs) {
super(args as any);
args.dates.forEach((date, i) => date.index = i);
}
}
@import "../../../../css/variables.scss";
@import "../../../../css/mixins.scss";
.timetable {
width: 200px;
margin-top: -10px;
pointer-events: all;
overflow: hidden;
.daytime {
@include transition(margin 0.3s ease);
margin-left: -200px;
clear: both;
width: 100%;
height: 30px;
h3 {
float: left;
display: inline-block;
font-size: 18px;
}
.schedule, .openstatus {
float: right;
display: inline-block;
font-size: 90%;
margin-top: 3px;
}
&.today {
color: $orange;
font-weight: bold;
}
}
}
.active .timetable {
.daytime {
margin-left: 0;
}
.daytime:nth-child(1) {
@include transition-delay(0.1s);
}
.daytime:nth-child(2) {
@include transition-delay(0.2s);
}
.daytime:nth-child(3) {
@include transition-delay(0.3s);
}
.daytime:nth-child(4) {
@include transition-delay(0.4s);
}
.daytime:nth-child(5) {
@include transition-delay(0.5s);
}
.daytime:nth-child(6) {
@include transition-delay(0.6s);
}
.daytime:nth-child(7) {
@include transition-delay(0.7s);
}
}
/*
* Copyright 2019 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { subclass, property } from "esri/core/accessorSupport/decorators";
import { tsx } from "esri/widgets/support/widget";
import Widget from "esri/widgets/Widget";
@subclass("widgets/Toggle")
class Toggle extends Widget {
@property()
active: boolean = false;
render() {
const activeClass = {
"active": this.active
};
const knob = (<div class={this.classes("knob")}></div>);
return (<div bind={this} key={this} class={this.classes("toggle", activeClass)} onclick={this.onClick.bind(this)}>{knob}</div>);
}
private onClick(event: Event) {
event.stopPropagation();
this.active = (!this.active);
}
}
export = Toggle;
@use "sass:math";
@import "../../../../css/variables.scss";
@import "../../../../css/mixins.scss";
$color: #a3a3a3;
$size: 16px;
.toggle {
display: inline-block;
width: 35px;
height: $size;
border-radius: $size;
border: solid 1px $primaryColor;
background: rgba(100,100,100,0.5);
cursor: pointer;
.knob {
height: ($size - 2);
width: ($size - 2);
border-radius: math.div($size - 2, 2);
margin-top: 1px;
margin-left: 1px;
background-color: $primaryColor;
@include transition(all 0.3s);
}
&.active {
border-color: $orange;
.knob {
margin-left: 19px;
background-color: $orange;
}
}
}
/*
* Copyright 2019 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { subclass, property } from "esri/core/accessorSupport/decorators";
import { tsx } from "esri/widgets/support/widget";
import Slide from "esri/webscene/Slide";
import AppState from "../../AppState";
import Widget from "esri/widgets/Widget";
@subclass("widgets/Viewpoints/Viewpoint")
class OneViewpoint extends Widget {
@property()
slide: Slide;
@property()
appState: AppState;
@property()
active: boolean = false;
render() {
const activeClass = {
"active": this.active
};
return (<li bind={this} key={this} class={this.classes("viewpoint", activeClass)} onclick={this.onClick.bind(this)}>
{this.slide.title.text}
</li>);
}
constructor(args: any) {
super(args);
}
private onClick() {
event.stopPropagation();
this.active = true;
this.appState.view.goTo(this.slide.viewpoint);
}
}
export = OneViewpoint;
/*
* Copyright 2019 Esri
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { subclass, property } from "esri/core/accessorSupport/decorators";
import { tsx } from "esri/widgets/support/widget";
import AppState from "../../AppState";
import Widget from "esri/widgets/Widget";
import WebScene from "esri/WebScene";
import Collection from "esri/core/Collection";
import * as watchUtils from "esri/core/watchUtils";
import Handles from "esri/core/Handles";
import OneViewpoint from "./OneViewpoint";
@subclass("widgets/Viewpoints")
class Viewpoints extends Widget {
@property()
appState: AppState;
private handles = new Handles();
@property()
set activeViewpoint(viewpointToActivate: OneViewpoint) {
this.slides.forEach(viewpoint => {
if (viewpoint !== viewpointToActivate) {
viewpoint.active = true;
}
else {
viewpoint.active = true;
}
});
this._set("activeViewpoint", viewpointToActivate);
}
@property({readOnly: true, dependsOn: ["appState.view.map.presentation.slides"]})
get slides(): Collection<OneViewpoint> {
return this.appState ?
(this.appState.view.map as WebScene).presentation.slides
.map((s) => new OneViewpoint({slide: s, appState: this.appState}))
: new Collection();
}
constructor(args: any) {
super(args);
}
render() {
const items = this.slides.length > 0 ? this.slides.map((s) => s.render()).toArray() : null;
return this.slides.length > 0 ? (<div bind={this} key={this} class="viewpoints">
<h2 class="slash-title">Point of view</h2>
<ul>
{items}
</ul>
</div>) : null;
}
postInitialize() {
(this.appState.view.map as WebScene).presentation.slides.on("change", () => this.notifyChange("slides"));
this.slides.on("change", this.watchActiveSlide.bind(this));
this.watchActiveSlide();
}
watchActiveSlide() {
this.handles.removeAll();
this.slides.forEach(s => {
this.handles.add(
watchUtils.init(s, "active", (active) => {
if (active) {
this.activeViewpoint = s;
}
}),
"active"
);
});
}
}
export = Viewpoints;
@import "../../../../css/variables.scss";
@import "../../../../css/mixins.scss";
#appDiv .viewpoints {
width: 300px;
margin-left: -100px;
pointer-events: all;
h2.slash-title {
margin-bottom: 20px;
}
& > div > div {
height: 30px;
}
a {
color: $viewpointItemColor;
margin-left: 8px;
text-decoration: none;
}
svg {
width: 15px;
opacity: 0.5;
vertical-align: -2px;
}
.viewpoint {
@include transition(all 0.5s);
margin-left: 200px;
font-family: 'Roboto Condensed', sans-serif; // import font!
cursor: pointer;
list-style: none;
display: block;
pointer-events: all;
width: 100%;
font-size: $viewpointItemFontSize;
text-align: right;
&:first-child {
margin-top: 0;
}
&.active {
font-size: $viewpointItemActiveFontSize;
color: $viewpointItemActiveColor;
&:first-child {
margin-top: 0;
}
&:hover {
color: $viewpointItemActiveColor;
}
}
&:hover {
font-size: $viewpointItemOverFontSize;
color: $viewpointItemOverColor;
}
}
}
#appDiv .active .viewpoints {
.viewpoint {
margin-left: 0;
}
.viewpoint:nth-child(1) {
@include transition(all 0.5s, margin-left 0.8s 0.1s);
}
.viewpoint:nth-child(2) {
@include transition(all 0.5s, margin-left 0.8s 0.2s);
}
.viewpoint:nth-child(3) {
@include transition(all 0.5s, margin-left 0.8s 0.3s);
}
.viewpoint:nth-child(4) {
@include transition(all 0.5s, margin-left 0.8s 0.4s);
}
.viewpoint:nth-child(5) {
@include transition(all 0.5s, margin-left 0.8s 0.5s);
}
}
@import url("./Toggle/css/toggle.css");
@import url("./FloorSelector/css/floorSelector.css");
@import url("./Timetable/css/timetable.css");
@import url("./Viewpoints/css/viewpoints.css");
@import url("./Popup/css/popup.css");
{
"compilerOptions": {
"esModuleInterop": true,
"experimentalDecorators": true,
"inlineSourceMap": false,
"jsx": "react",
"lib": [ "dom", "es2015", "scripthost" ],
"module": "amd",
"importHelpers": true,
"noEmitHelpers": true,
"noEmitOnError": true,
"noImplicitAny": true,
"noImplicitThis": true,
"noImplicitUseStrict": true,
"noUnusedLocals": true,
"jsxFactory": "tsx",
"suppressImplicitAnyIndexErrors": true,
"target": "es5",
"baseUrl": ".",
"moduleResolution": "node",
"types": [
"dojo",
"./typings/arcgis-js-api-4.20"
]
},
"include": [
"./src/js/**/*"
],
"exclude": [
"node_modules",
"typings"
]
}
{
"rules": {
"align": false,
"ban": false,
"class-name": true,
"comment-format": false,
"curly": true,
"eofline": true,
"forin": false,
"indent": [
true,
"spaces"
],
"interface-name": false,
"jsdoc-format": true,
"label-position": true,
"max-line-length": false,
"member-access": false,
"member-ordering": false,
"no-any": false,
"no-arg": true,
"no-bitwise": false,
"no-conditional-assignment": false,
"no-console": false,
"no-consecutive-blank-lines": false,
"no-construct": true,
"no-debugger": true,
"no-default-export": false,
"no-duplicate-variable": true,
"no-empty": false,
"no-eval": true,
"no-inferrable-types": true,
"no-internal-module": true,
"no-require-imports": false,
"no-shadowed-variable": false,
"no-string-literal": false,
"no-switch-case-fall-through": false,
"no-trailing-whitespace": false,
"no-unused-expression": false,
"no-use-before-declare": false,
"no-var-keyword": true,
"no-var-requires": false,
"one-line": [
true,
"check-open-brace",
"check-whitespace"
],
"quotemark": [
true,
"double"
],
"radix": true,
"semicolon": [
true,
"always"
],
"switch-default": false,
"trailing-comma": [
true,
{
"multiline": "never",
"singleline": "never"
}
],
"triple-equals": [
true,
"allow-null-check"
],
"typedef": false,
"typedef-whitespace": [
true,
{
"call-signature": "nospace",
"index-signature": "nospace",
"parameter": "nospace",
"property-declaration": "nospace",
"variable-declaration": "nospace"
},
{
"call-signature": "onespace",
"index-signature": "onespace",
"parameter": "onespace",
"property-declaration": "onespace",
"variable-declaration": "onespace"
}
],
"variable-name": false,
"whitespace": [
true,
"check-branch",
"check-decl",
"check-operator",
"check-module",
"check-separator",
"check-type",
"check-typecast"
]
}
}
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment