mirror of
https://github.com/beestat/app.git
synced 2025-06-02 21:26:38 -04:00
Tweaks and improvements to visualizer
This commit is contained in:
parent
b2a2e3d723
commit
c19bf4145c
@ -88,40 +88,6 @@ body {
|
|||||||
src:url("../font/montserrat/montserrat_900.eot?") format("embedded-opentype"),url("../font/montserrat/montserrat_900.woff") format("woff"),url("../font/montserrat/montserrat_900.ttf") format("truetype"),url("../font/montserrat/montserrat_900.svg#Montserrat") format("svg")
|
src:url("../font/montserrat/montserrat_900.eot?") format("embedded-opentype"),url("../font/montserrat/montserrat_900.woff") format("woff"),url("../font/montserrat/montserrat_900.ttf") format("truetype"),url("../font/montserrat/montserrat_900.svg#Montserrat") format("svg")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Beestat logo */
|
|
||||||
.beestat {
|
|
||||||
font-weight: 200;
|
|
||||||
font-size: 40px;
|
|
||||||
font-family: Montserrat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.beestat > .bee {
|
|
||||||
color: #f7b731;
|
|
||||||
}
|
|
||||||
|
|
||||||
.beestat > .stat {
|
|
||||||
color: #20bf6b;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Link styles */
|
/* Link styles */
|
||||||
a {
|
a {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -311,6 +277,43 @@ input[type=radio] {
|
|||||||
opacity: 0.25;
|
opacity: 0.25;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Range input */
|
||||||
|
input[type=range]{
|
||||||
|
-webkit-appearance: none;
|
||||||
|
background:transparent;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-runnable-track {
|
||||||
|
background: #37474f;
|
||||||
|
height: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-track {
|
||||||
|
background: #37474f;
|
||||||
|
height: 5px;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-webkit-slider-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: none;
|
||||||
|
background-color: #ffffff;
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=range]::-moz-range-thumb {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
height: 14px;
|
||||||
|
width: 14px;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: none;
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a stripped down version of https://flexgridlite.elliotdahl.com/
|
* This is a stripped down version of https://flexgridlite.elliotdahl.com/
|
||||||
@ -482,6 +485,7 @@ input[type=radio] {
|
|||||||
.icon.menu_down:before { content: "\F035D"; }
|
.icon.menu_down:before { content: "\F035D"; }
|
||||||
.icon.menu_up:before { content: "\F0360"; }
|
.icon.menu_up:before { content: "\F0360"; }
|
||||||
.icon.message:before { content: "\F0361"; }
|
.icon.message:before { content: "\F0361"; }
|
||||||
|
.icon.moon_waning_crescent:before { content: "\F0F65"; }
|
||||||
.icon.network_strength_4:before { content: "\F08FA"; }
|
.icon.network_strength_4:before { content: "\F08FA"; }
|
||||||
.icon.network_strength_off:before { content: "\F08FC"; }
|
.icon.network_strength_off:before { content: "\F08FC"; }
|
||||||
.icon.numeric_0:before { content: "\F0B39"; }
|
.icon.numeric_0:before { content: "\F0B39"; }
|
||||||
@ -516,6 +520,8 @@ input[type=radio] {
|
|||||||
.icon.redo:before { content: "\F044E"; }
|
.icon.redo:before { content: "\F044E"; }
|
||||||
.icon.refresh:before { content: "\F0450"; }
|
.icon.refresh:before { content: "\F0450"; }
|
||||||
.icon.resistor:before { content: "\F0B44"; }
|
.icon.resistor:before { content: "\F0B44"; }
|
||||||
|
.icon.restart:before { content: "\F0709"; }
|
||||||
|
.icon.restart_off:before { content: "\F0D95"; }
|
||||||
.icon.snowflake:before { content: "\F0717"; }
|
.icon.snowflake:before { content: "\F0717"; }
|
||||||
.icon.swap_horizontal:before { content: "\F04E1"; }
|
.icon.swap_horizontal:before { content: "\F04E1"; }
|
||||||
.icon.thermometer:before { content: "\F050F"; }
|
.icon.thermometer:before { content: "\F050F"; }
|
||||||
@ -542,6 +548,7 @@ input[type=radio] {
|
|||||||
.icon.weather_sunny:before { content: "\F0599"; }
|
.icon.weather_sunny:before { content: "\F0599"; }
|
||||||
.icon.weather_tornado:before { content: "\F0F38"; }
|
.icon.weather_tornado:before { content: "\F0F38"; }
|
||||||
.icon.weather_windy:before { content: "\F059D"; }
|
.icon.weather_windy:before { content: "\F059D"; }
|
||||||
|
.icon.white_balance_sunny:before { content: "\F05A8"; }
|
||||||
.icon.wifi_strength_1_alert:before { content: "\F0920"; }
|
.icon.wifi_strength_1_alert:before { content: "\F0920"; }
|
||||||
.icon.wifi_strength_4:before { content: "\F0928"; }
|
.icon.wifi_strength_4:before { content: "\F0928"; }
|
||||||
.icon.zigbee:before { content: "\F0D41"; }
|
.icon.zigbee:before { content: "\F0D41"; }
|
||||||
|
@ -394,6 +394,13 @@ beestat.style.hex_to_rgb = function(hex) {
|
|||||||
} : null;
|
} : null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert RGB components to a hex string.
|
||||||
|
*
|
||||||
|
* @param {object} RGB
|
||||||
|
*
|
||||||
|
* @return {string} hex
|
||||||
|
*/
|
||||||
beestat.style.rgb_to_hex = function(rgb) {
|
beestat.style.rgb_to_hex = function(rgb) {
|
||||||
return "#" + ((1 << 24) + (rgb.r << 16) + (rgb.g << 8) + rgb.b).toString(16).slice(1);
|
return "#" + ((1 << 24) + (rgb.r << 16) + (rgb.g << 8) + rgb.b).toString(16).slice(1);
|
||||||
}
|
};
|
||||||
|
@ -14,7 +14,10 @@ beestat.component.card.three_d = function() {
|
|||||||
'setting.visualize.heat_map_absolute.temperature.max',
|
'setting.visualize.heat_map_absolute.temperature.max',
|
||||||
'setting.visualize.heat_map_absolute.occupancy.min',
|
'setting.visualize.heat_map_absolute.occupancy.min',
|
||||||
'setting.visualize.heat_map_absolute.occupancy.max'
|
'setting.visualize.heat_map_absolute.occupancy.max'
|
||||||
], self.update_scene_.bind(this));
|
], function() {
|
||||||
|
self.update_scene_();
|
||||||
|
self.update_hud_();
|
||||||
|
});
|
||||||
|
|
||||||
beestat.dispatcher.addEventListener('cache.floor_plan', function() {
|
beestat.dispatcher.addEventListener('cache.floor_plan', function() {
|
||||||
self.scene_.rerender();
|
self.scene_.rerender();
|
||||||
@ -88,22 +91,66 @@ beestat.component.card.three_d.prototype.decorate_contents_ = function(parent) {
|
|||||||
parent.appendChild(drawing_pane_container);
|
parent.appendChild(drawing_pane_container);
|
||||||
this.decorate_drawing_pane_(drawing_pane_container);
|
this.decorate_drawing_pane_(drawing_pane_container);
|
||||||
|
|
||||||
// Decorate everything.
|
// Watermark
|
||||||
|
const watermark_container = document.createElement('div');
|
||||||
|
Object.assign(watermark_container.style, {
|
||||||
|
'position': 'absolute',
|
||||||
|
'height': '20px',
|
||||||
|
'bottom': `${beestat.style.size.gutter}px`,
|
||||||
|
'right': `${beestat.style.size.gutter}px`
|
||||||
|
});
|
||||||
|
parent.appendChild(watermark_container);
|
||||||
|
this.decorate_watermark_(watermark_container);
|
||||||
|
|
||||||
|
// Toolbar
|
||||||
|
const toolbar_container = document.createElement('div');
|
||||||
|
Object.assign(toolbar_container.style, {
|
||||||
|
'position': 'absolute',
|
||||||
|
'width': '1px',
|
||||||
|
'top': `${beestat.style.size.gutter}px`,
|
||||||
|
'left': `${beestat.style.size.gutter}px`
|
||||||
|
});
|
||||||
|
parent.appendChild(toolbar_container);
|
||||||
|
this.decorate_toolbar_(toolbar_container);
|
||||||
|
|
||||||
|
const top_container = document.createElement('div');
|
||||||
|
Object.assign(top_container.style, {
|
||||||
|
'display': 'flex',
|
||||||
|
'position': 'absolute',
|
||||||
|
'width': '100%',
|
||||||
|
'top': `${beestat.style.size.gutter}px`,
|
||||||
|
'padding-left': '55px',
|
||||||
|
'padding-right': `${beestat.style.size.gutter}px`
|
||||||
|
});
|
||||||
|
parent.appendChild(top_container);
|
||||||
|
|
||||||
|
// Floors
|
||||||
|
const floors_container = document.createElement('div');
|
||||||
|
Object.assign(floors_container.style, {
|
||||||
|
'flex-shrink': '0'
|
||||||
|
});
|
||||||
|
top_container.appendChild(floors_container);
|
||||||
|
this.decorate_floors_(floors_container);
|
||||||
|
|
||||||
|
// Controls
|
||||||
const controls_container = document.createElement('div');
|
const controls_container = document.createElement('div');
|
||||||
Object.assign(controls_container.style, {
|
Object.assign(controls_container.style, {
|
||||||
'position': 'absolute',
|
'flex-grow': '1'
|
||||||
'top': `${beestat.style.size.gutter}px`,
|
|
||||||
'left': '50%',
|
|
||||||
'width': '300px',
|
|
||||||
'margin-left': '-150px',
|
|
||||||
'background': beestat.style.color.bluegray.base,
|
|
||||||
'padding': `${beestat.style.size.gutter / 2}px`,
|
|
||||||
'border-radius': `${beestat.style.size.border_radius}px`
|
|
||||||
});
|
});
|
||||||
parent.appendChild(controls_container);
|
top_container.appendChild(controls_container);
|
||||||
this.decorate_controls_(controls_container);
|
this.decorate_controls_(controls_container);
|
||||||
|
|
||||||
// var thermostat = beestat.cache.thermostat[this.thermostat_id_];
|
// Legend
|
||||||
|
const legend_container = document.createElement('div');
|
||||||
|
Object.assign(legend_container.style, {
|
||||||
|
'position': 'absolute',
|
||||||
|
'top': '50%',
|
||||||
|
'margin-top': '-90px',
|
||||||
|
'right': `${beestat.style.size.gutter}px`,
|
||||||
|
'height': '180px'
|
||||||
|
});
|
||||||
|
parent.appendChild(legend_container);
|
||||||
|
this.decorate_legend_(legend_container);
|
||||||
|
|
||||||
let required_begin;
|
let required_begin;
|
||||||
let required_end;
|
let required_end;
|
||||||
@ -311,7 +358,7 @@ beestat.component.card.three_d.prototype.decorate_controls_ = function(parent) {
|
|||||||
|
|
||||||
// Hoisting
|
// Hoisting
|
||||||
const range = new beestat.component.input.range();
|
const range = new beestat.component.input.range();
|
||||||
const right_container = document.createElement('div');
|
const time_container = document.createElement('div');
|
||||||
|
|
||||||
const container = document.createElement('div');
|
const container = document.createElement('div');
|
||||||
Object.assign(container.style, {
|
Object.assign(container.style, {
|
||||||
@ -326,13 +373,11 @@ beestat.component.card.three_d.prototype.decorate_controls_ = function(parent) {
|
|||||||
const play_tile = new beestat.component.tile()
|
const play_tile = new beestat.component.tile()
|
||||||
.set_icon('play')
|
.set_icon('play')
|
||||||
.set_shadow(false)
|
.set_shadow(false)
|
||||||
.set_text_hover_color(beestat.style.color.green.base)
|
.set_text_hover_color(beestat.style.color.gray.base)
|
||||||
.render($(left_container));
|
.render($(left_container));
|
||||||
play_tile.addEventListener('click', function() {
|
play_tile.addEventListener('click', function() {
|
||||||
if (self.interval_ === undefined) {
|
if (self.interval_ === undefined) {
|
||||||
play_tile
|
play_tile.set_icon('pause');
|
||||||
.set_icon('pause')
|
|
||||||
.set_text_hover_color(beestat.style.color.red.base);
|
|
||||||
|
|
||||||
self.interval_ = window.setInterval(function() {
|
self.interval_ = window.setInterval(function() {
|
||||||
self.date_m_.add(5, 'minutes');
|
self.date_m_.add(5, 'minutes');
|
||||||
@ -340,51 +385,260 @@ beestat.component.card.three_d.prototype.decorate_controls_ = function(parent) {
|
|||||||
range.set_value(
|
range.set_value(
|
||||||
((self.date_m_.hours() * 60) + self.date_m_.minutes()) / 1440 * 288
|
((self.date_m_.hours() * 60) + self.date_m_.minutes()) / 1440 * 288
|
||||||
);
|
);
|
||||||
right_container.innerText = self.date_m_.format('h:mm a');
|
time_container.innerText = self.date_m_.format('h:mm a');
|
||||||
}, 100);
|
}, 100);
|
||||||
} else {
|
} else {
|
||||||
play_tile
|
play_tile
|
||||||
.set_icon('play')
|
.set_icon('play');
|
||||||
.set_text_hover_color(beestat.style.color.green.base);
|
|
||||||
window.clearInterval(self.interval_);
|
window.clearInterval(self.interval_);
|
||||||
delete self.interval_;
|
delete self.interval_;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const center_container = document.createElement('div');
|
const range_container = document.createElement('div');
|
||||||
Object.assign(center_container.style, {
|
Object.assign(range_container.style, {
|
||||||
|
'position': 'relative',
|
||||||
'flex-grow': '1'
|
'flex-grow': '1'
|
||||||
});
|
});
|
||||||
container.appendChild(center_container);
|
container.appendChild(range_container);
|
||||||
|
|
||||||
|
// Sunrise/Sunset
|
||||||
|
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||||
|
if (floor_plan.address_id !== undefined) {
|
||||||
|
const address = beestat.cache.address[floor_plan.address_id];
|
||||||
|
|
||||||
|
const times = SunCalc.getTimes(
|
||||||
|
self.date_m_.toDate(),
|
||||||
|
address.normalized.metadata.latitude,
|
||||||
|
address.normalized.metadata.longitude
|
||||||
|
);
|
||||||
|
|
||||||
|
const sunrise_m = moment(times.sunrise);
|
||||||
|
const sunrise_percentage = ((sunrise_m.hours() * 60) + sunrise_m.minutes()) / 1440 * 100;
|
||||||
|
|
||||||
|
const sunset_m = moment(times.sunset);
|
||||||
|
const sunset_percentage = ((sunset_m.hours() * 60) + sunset_m.minutes()) / 1440 * 100;
|
||||||
|
|
||||||
|
const sunrise_container = document.createElement('div');
|
||||||
|
Object.assign(sunrise_container.style, {
|
||||||
|
'position': 'absolute',
|
||||||
|
'top': '-10px',
|
||||||
|
'left': `${sunrise_percentage}%`
|
||||||
|
});
|
||||||
|
new beestat.component.icon('white_balance_sunny', 'Sunrise @ ' + sunrise_m.format('h:mm'))
|
||||||
|
.set_size(16)
|
||||||
|
.set_color(beestat.style.color.yellow.base)
|
||||||
|
.render($(sunrise_container));
|
||||||
|
range_container.appendChild(sunrise_container);
|
||||||
|
|
||||||
|
const sunset_container = document.createElement('div');
|
||||||
|
Object.assign(sunset_container.style, {
|
||||||
|
'position': 'absolute',
|
||||||
|
'top': '-10px',
|
||||||
|
'left': `${sunset_percentage}%`
|
||||||
|
});
|
||||||
|
new beestat.component.icon('moon_waning_crescent', 'Sunset @ ' + sunset_m.format('h:mm'))
|
||||||
|
.set_size(16)
|
||||||
|
.set_color(beestat.style.color.purple.base)
|
||||||
|
.render($(sunset_container));
|
||||||
|
range_container.appendChild(sunset_container);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range input
|
||||||
range
|
range
|
||||||
.set_min(0)
|
.set_min(0)
|
||||||
.set_max(287)
|
.set_max(287)
|
||||||
.set_value(0)
|
.set_value(0)
|
||||||
.render($(center_container));
|
.render($(range_container));
|
||||||
|
|
||||||
right_container.innerText = '12:00 am';
|
time_container.innerText = '12:00 am';
|
||||||
Object.assign(right_container.style, {
|
Object.assign(time_container.style, {
|
||||||
'width': '70px',
|
'margin-top': '-8px',
|
||||||
'text-align': 'right'
|
'text-align': 'right'
|
||||||
});
|
});
|
||||||
container.appendChild(right_container);
|
parent.appendChild(time_container);
|
||||||
|
|
||||||
range.addEventListener('input', function() {
|
range.addEventListener('input', function() {
|
||||||
play_tile
|
play_tile.set_icon('play');
|
||||||
.set_icon('play')
|
|
||||||
.set_text_hover_color(beestat.style.color.green.base);
|
|
||||||
window.clearInterval(self.interval_);
|
window.clearInterval(self.interval_);
|
||||||
delete self.interval_;
|
delete self.interval_;
|
||||||
|
|
||||||
const minute_of_day = range.get_value() * 5;
|
const minute_of_day = range.get_value() * 5;
|
||||||
self.date_m_.hours(Math.floor(minute_of_day / 60));
|
self.date_m_.hours(Math.floor(minute_of_day / 60));
|
||||||
self.date_m_.minutes(Math.floor(minute_of_day % 60));
|
self.date_m_.minutes(Math.floor(minute_of_day % 60));
|
||||||
right_container.innerText = self.date_m_.format('h:mm a');
|
time_container.innerText = self.date_m_.format('h:mm a');
|
||||||
self.scene_.set_date(self.date_m_);
|
self.scene_.set_date(self.date_m_);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Watermark.
|
||||||
|
*
|
||||||
|
* @param {HTMLDivElement} parent
|
||||||
|
*/
|
||||||
|
beestat.component.card.three_d.prototype.decorate_watermark_ = function(parent) {
|
||||||
|
const img = document.createElement('img');
|
||||||
|
img.setAttribute('src', 'img/logo.png');
|
||||||
|
Object.assign(img.style, {
|
||||||
|
'height': '100%',
|
||||||
|
'opacity': '0.7'
|
||||||
|
});
|
||||||
|
parent.appendChild(img);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Toolbar.
|
||||||
|
*
|
||||||
|
* @param {HTMLDivElement} parent
|
||||||
|
*/
|
||||||
|
beestat.component.card.three_d.prototype.decorate_toolbar_ = function(parent) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const tile_group = new beestat.component.tile_group();
|
||||||
|
|
||||||
|
// Add floor
|
||||||
|
tile_group.add_tile(new beestat.component.tile()
|
||||||
|
.set_icon('layers')
|
||||||
|
.set_shadow(false)
|
||||||
|
.set_text_color(beestat.style.color.lightblue.base)
|
||||||
|
);
|
||||||
|
|
||||||
|
let auto_rotate = false;
|
||||||
|
|
||||||
|
// Add room
|
||||||
|
tile_group.add_tile(new beestat.component.tile()
|
||||||
|
.set_icon('restart_off')
|
||||||
|
.set_title('Auto-Rotate')
|
||||||
|
.set_text_color(beestat.style.color.gray.light)
|
||||||
|
.set_background_color(beestat.style.color.bluegray.base)
|
||||||
|
.set_background_hover_color(beestat.style.color.bluegray.light)
|
||||||
|
.addEventListener('click', function() {
|
||||||
|
auto_rotate = !auto_rotate;
|
||||||
|
this.set_icon(
|
||||||
|
'restart' + (auto_rotate === false ? '_off' : '')
|
||||||
|
);
|
||||||
|
self.scene_.set_auto_rotate(auto_rotate);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
tile_group.render($(parent));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Floors.
|
||||||
|
*
|
||||||
|
* @param {HTMLDivElement} parent
|
||||||
|
*/
|
||||||
|
beestat.component.card.three_d.prototype.decorate_floors_ = function(parent) {
|
||||||
|
const self = this;
|
||||||
|
|
||||||
|
const tile_group = new beestat.component.tile_group();
|
||||||
|
|
||||||
|
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||||
|
|
||||||
|
const sorted_groups = Object.values(floor_plan.data.groups)
|
||||||
|
.sort(function(a, b) {
|
||||||
|
return a.elevation > b.elevation;
|
||||||
|
});
|
||||||
|
|
||||||
|
let icon_number = 1;
|
||||||
|
sorted_groups.forEach(function(group, i) {
|
||||||
|
const button = new beestat.component.tile()
|
||||||
|
.set_title(group.name)
|
||||||
|
.set_shadow(false)
|
||||||
|
.set_text_hover_color(beestat.style.color.lightblue.light)
|
||||||
|
.set_text_color(beestat.style.color.lightblue.base);
|
||||||
|
|
||||||
|
let icon;
|
||||||
|
if (group.elevation < 0) {
|
||||||
|
icon = 'alpha_b';
|
||||||
|
} else {
|
||||||
|
icon = 'numeric_' + icon_number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
let layer_visible = true;
|
||||||
|
button
|
||||||
|
.set_icon(icon + '_box')
|
||||||
|
.addEventListener('click', function() {
|
||||||
|
if (layer_visible === true) {
|
||||||
|
self.scene_.set_layer_visible('group_' + i, false);
|
||||||
|
button.set_icon(icon);
|
||||||
|
} else {
|
||||||
|
self.scene_.set_layer_visible('group_' + i, true);
|
||||||
|
button.set_icon(icon + '_box');
|
||||||
|
}
|
||||||
|
layer_visible = !layer_visible;
|
||||||
|
});
|
||||||
|
|
||||||
|
tile_group.add_tile(button);
|
||||||
|
});
|
||||||
|
|
||||||
|
tile_group.render($(parent));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Legend.
|
||||||
|
*
|
||||||
|
* @param {HTMLDivElement} parent
|
||||||
|
*/
|
||||||
|
beestat.component.card.three_d.prototype.decorate_legend_ = function(parent) {
|
||||||
|
if (parent !== undefined) {
|
||||||
|
this.legend_container_ = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.legend_container_.innerHTML = '';
|
||||||
|
|
||||||
|
const gradient = this.get_gradient_();
|
||||||
|
const gradient_parts = [
|
||||||
|
beestat.style.rgb_to_hex(gradient[0]) + ' 0%',
|
||||||
|
beestat.style.rgb_to_hex(gradient[Math.round(gradient.length / 2)]) + ' 50%',
|
||||||
|
beestat.style.rgb_to_hex(gradient[gradient.length - 1]) + ' 100%'
|
||||||
|
];
|
||||||
|
|
||||||
|
const gradient_container = document.createElement('div');
|
||||||
|
Object.assign(gradient_container.style, {
|
||||||
|
'background': 'linear-gradient(0deg, ' + gradient_parts.join(', ') + ')',
|
||||||
|
'height': '100%',
|
||||||
|
'width': '6px',
|
||||||
|
'border-radius': '6px',
|
||||||
|
'position': 'relative'
|
||||||
|
});
|
||||||
|
this.legend_container_.appendChild(gradient_container);
|
||||||
|
|
||||||
|
let units;
|
||||||
|
let min = this.get_heat_map_min_();
|
||||||
|
let max = this.get_heat_map_max_();
|
||||||
|
if (beestat.setting('visualize.data_type') === 'temperature') {
|
||||||
|
min = beestat.temperature(min);
|
||||||
|
max = beestat.temperature(max);
|
||||||
|
units = beestat.setting('temperature_unit');
|
||||||
|
} else {
|
||||||
|
min *= 100;
|
||||||
|
max *= 100;
|
||||||
|
units = '%';
|
||||||
|
}
|
||||||
|
|
||||||
|
const min_container = document.createElement('div');
|
||||||
|
Object.assign(min_container.style, {
|
||||||
|
'position': 'absolute',
|
||||||
|
'bottom': '0',
|
||||||
|
'right': '10px',
|
||||||
|
'font-size': beestat.style.font_size.small
|
||||||
|
});
|
||||||
|
min_container.innerText = min + units;
|
||||||
|
gradient_container.appendChild(min_container);
|
||||||
|
|
||||||
|
const max_container = document.createElement('div');
|
||||||
|
Object.assign(max_container.style, {
|
||||||
|
'position': 'absolute',
|
||||||
|
'top': '0',
|
||||||
|
'right': '10px',
|
||||||
|
'font-size': beestat.style.font_size.small
|
||||||
|
});
|
||||||
|
max_container.innerText = max + units;
|
||||||
|
gradient_container.appendChild(max_container);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get data. This doesn't directly or indirectly make any API calls, but it
|
* Get data. This doesn't directly or indirectly make any API calls, but it
|
||||||
* caches the data so it doesn't have to loop over everything more than once.
|
* caches the data so it doesn't have to loop over everything more than once.
|
||||||
@ -498,32 +752,13 @@ beestat.component.card.three_d.prototype.has_data_ = function() {
|
|||||||
beestat.component.card.three_d.prototype.update_scene_ = function() {
|
beestat.component.card.three_d.prototype.update_scene_ = function() {
|
||||||
this.scene_.set_data_type(beestat.setting('visualize.data_type'));
|
this.scene_.set_data_type(beestat.setting('visualize.data_type'));
|
||||||
|
|
||||||
switch (beestat.setting('visualize.heat_map_type')) {
|
this.scene_.set_gradient(this.get_gradient_());
|
||||||
case 'relative':
|
this.scene_.set_heat_map_min(this.get_heat_map_min_());
|
||||||
this.scene_.set_heat_map_min(
|
this.scene_.set_heat_map_max(this.get_heat_map_max_());
|
||||||
this.data_.metadata.series[beestat.setting('visualize.data_type')].min
|
};
|
||||||
);
|
|
||||||
this.scene_.set_heat_map_max(
|
beestat.component.card.three_d.prototype.update_hud_ = function() {
|
||||||
this.data_.metadata.series[beestat.setting('visualize.data_type')].max
|
this.decorate_legend_();
|
||||||
);
|
|
||||||
break;
|
|
||||||
case 'absolute':
|
|
||||||
this.scene_.set_heat_map_min(
|
|
||||||
beestat.setting(
|
|
||||||
'visualize.heat_map_absolute.' +
|
|
||||||
beestat.setting('visualize.data_type') +
|
|
||||||
'.min'
|
|
||||||
) / (beestat.setting('visualize.data_type') === 'occupancy' ? 100 : 1)
|
|
||||||
);
|
|
||||||
this.scene_.set_heat_map_max(
|
|
||||||
beestat.setting(
|
|
||||||
'visualize.heat_map_absolute.' +
|
|
||||||
beestat.setting('visualize.data_type') +
|
|
||||||
'.max'
|
|
||||||
) / (beestat.setting('visualize.data_type') === 'occupancy' ? 100 : 1)
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -542,3 +777,61 @@ beestat.component.card.three_d.prototype.set_floor_plan_id = function(floor_plan
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the effective minimum heat map value based on the settings.
|
||||||
|
*
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
beestat.component.card.three_d.prototype.get_heat_map_min_ = function() {
|
||||||
|
if (beestat.setting('visualize.heat_map_type') === 'relative') {
|
||||||
|
return this.data_.metadata.series[beestat.setting('visualize.data_type')].min;
|
||||||
|
}
|
||||||
|
return beestat.setting(
|
||||||
|
'visualize.heat_map_absolute.' +
|
||||||
|
beestat.setting('visualize.data_type') +
|
||||||
|
'.min'
|
||||||
|
) / (beestat.setting('visualize.data_type') === 'occupancy' ? 100 : 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the effective maximum heat map value based on the settings.
|
||||||
|
*
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
beestat.component.card.three_d.prototype.get_heat_map_max_ = function() {
|
||||||
|
if (beestat.setting('visualize.heat_map_type') === 'relative') {
|
||||||
|
return this.data_.metadata.series[beestat.setting('visualize.data_type')].max;
|
||||||
|
}
|
||||||
|
return beestat.setting(
|
||||||
|
'visualize.heat_map_absolute.' +
|
||||||
|
beestat.setting('visualize.data_type') +
|
||||||
|
'.max'
|
||||||
|
) / (beestat.setting('visualize.data_type') === 'occupancy' ? 100 : 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the gradient based on the settings.
|
||||||
|
*
|
||||||
|
* @return {object}
|
||||||
|
*/
|
||||||
|
beestat.component.card.three_d.prototype.get_gradient_ = function() {
|
||||||
|
if (beestat.setting('visualize.data_type') === 'temperature') {
|
||||||
|
return beestat.style.generate_gradient(
|
||||||
|
[
|
||||||
|
beestat.style.hex_to_rgb(beestat.style.color.blue.dark),
|
||||||
|
beestat.style.hex_to_rgb(beestat.style.color.gray.base),
|
||||||
|
beestat.style.hex_to_rgb(beestat.style.color.red.dark)
|
||||||
|
],
|
||||||
|
100
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return beestat.style.generate_gradient(
|
||||||
|
[
|
||||||
|
beestat.style.hex_to_rgb(beestat.style.color.gray.base),
|
||||||
|
beestat.style.hex_to_rgb(beestat.style.color.orange.dark)
|
||||||
|
],
|
||||||
|
200
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
@ -46,7 +46,7 @@ beestat.component.card.visualize_affiliate.prototype.decorate_top_right_ = funct
|
|||||||
.set_shadow(false)
|
.set_shadow(false)
|
||||||
.set_icon('close')
|
.set_icon('close')
|
||||||
.set_text_color('#fff')
|
.set_text_color('#fff')
|
||||||
.set_background_hover_color(beestat.style.color.green.light)
|
.set_background_hover_color('rgba(255, 255, 255, 0.1')
|
||||||
.addEventListener('click', function() {
|
.addEventListener('click', function() {
|
||||||
beestat.setting('visualize.hide_affiliate', true);
|
beestat.setting('visualize.hide_affiliate', true);
|
||||||
})
|
})
|
||||||
|
@ -78,7 +78,7 @@ beestat.component.floor_plan.prototype.render = function(parent) {
|
|||||||
this.floors_container_.style({
|
this.floors_container_.style({
|
||||||
'position': 'absolute',
|
'position': 'absolute',
|
||||||
'top': beestat.style.size.gutter,
|
'top': beestat.style.size.gutter,
|
||||||
'left': 40 + beestat.style.size.gutter + (beestat.style.size.gutter / 2)
|
'left': beestat.style.size.gutter * 4
|
||||||
});
|
});
|
||||||
parent.appendChild(this.floors_container_);
|
parent.appendChild(this.floors_container_);
|
||||||
|
|
||||||
|
@ -48,8 +48,8 @@ beestat.component.scene.ambient_light_intensity = 0.3;
|
|||||||
* having to manually save camera info etc.
|
* having to manually save camera info etc.
|
||||||
*/
|
*/
|
||||||
beestat.component.scene.prototype.rerender = function() {
|
beestat.component.scene.prototype.rerender = function() {
|
||||||
this.scene_.remove(this.group_);
|
this.scene_.remove(this.main_group_);
|
||||||
this.add_group_();
|
this.add_main_group_();
|
||||||
this.add_floor_plan_();
|
this.add_floor_plan_();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ beestat.component.scene.prototype.decorate_ = function(parent) {
|
|||||||
// this.add_ground_();
|
// this.add_ground_();
|
||||||
// this.add_ground_limited_();
|
// this.add_ground_limited_();
|
||||||
|
|
||||||
this.add_group_();
|
this.add_main_group_();
|
||||||
this.add_floor_plan_();
|
this.add_floor_plan_();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -410,27 +410,6 @@ beestat.component.scene.prototype.update_ = function() {
|
|||||||
|
|
||||||
const time = this.date_.format('HH:mm');
|
const time = this.date_.format('HH:mm');
|
||||||
|
|
||||||
// TODO Memoize this
|
|
||||||
let gradient;
|
|
||||||
if (self.data_type_ === 'temperature') {
|
|
||||||
gradient = beestat.style.generate_gradient(
|
|
||||||
[
|
|
||||||
beestat.style.hex_to_rgb(beestat.style.color.blue.dark),
|
|
||||||
beestat.style.hex_to_rgb(beestat.style.color.gray.base),
|
|
||||||
beestat.style.hex_to_rgb(beestat.style.color.red.dark)
|
|
||||||
],
|
|
||||||
100
|
|
||||||
);
|
|
||||||
} else if (self.data_type_ === 'occupancy') {
|
|
||||||
gradient = beestat.style.generate_gradient(
|
|
||||||
[
|
|
||||||
beestat.style.hex_to_rgb(beestat.style.color.gray.base),
|
|
||||||
beestat.style.hex_to_rgb(beestat.style.color.orange.dark)
|
|
||||||
],
|
|
||||||
200
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the color of each room
|
// Set the color of each room
|
||||||
floor_plan.data.groups.forEach(function(group) {
|
floor_plan.data.groups.forEach(function(group) {
|
||||||
group.rooms.forEach(function(room) {
|
group.rooms.forEach(function(room) {
|
||||||
@ -449,7 +428,9 @@ beestat.component.scene.prototype.update_ = function() {
|
|||||||
(value - self.heat_map_min_) / (self.heat_map_max_ - self.heat_map_min_)
|
(value - self.heat_map_min_) / (self.heat_map_max_ - self.heat_map_min_)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
color = beestat.style.rgb_to_hex(gradient[Math.floor((gradient.length - 1) * percentage)]);
|
color = beestat.style.rgb_to_hex(
|
||||||
|
self.gradient_[Math.floor((self.gradient_.length - 1) * percentage)]
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
color = beestat.style.color.gray.dark;
|
color = beestat.style.color.gray.dark;
|
||||||
}
|
}
|
||||||
@ -739,10 +720,11 @@ beestat.component.scene.prototype.add_background_ = function() {
|
|||||||
/**
|
/**
|
||||||
* Add a room. Room coordinates are absolute.
|
* Add a room. Room coordinates are absolute.
|
||||||
*
|
*
|
||||||
|
* @param {THREE.Group} layer The layer the room belongs to.
|
||||||
* @param {object} group The group the room belongs to.
|
* @param {object} group The group the room belongs to.
|
||||||
* @param {object} room The room to add.
|
* @param {object} room The room to add.
|
||||||
*/
|
*/
|
||||||
beestat.component.scene.prototype.add_room_ = function(group, room) {
|
beestat.component.scene.prototype.add_room_ = function(layer, group, room) {
|
||||||
const color = beestat.style.color.gray.dark;
|
const color = beestat.style.color.gray.dark;
|
||||||
|
|
||||||
var clipper_offset = new ClipperLib.ClipperOffset();
|
var clipper_offset = new ClipperLib.ClipperOffset();
|
||||||
@ -805,13 +787,15 @@ beestat.component.scene.prototype.add_room_ = function(group, room) {
|
|||||||
// mesh.receiveShadow = true;
|
// mesh.receiveShadow = true;
|
||||||
|
|
||||||
// Add the mesh to the group.
|
// Add the mesh to the group.
|
||||||
this.group_.add(mesh);
|
this.main_group_.add(mesh);
|
||||||
|
|
||||||
// Store a reference to the mesh representing each room.
|
// Store a reference to the mesh representing each room.
|
||||||
if (this.rooms_ === undefined) {
|
if (this.rooms_ === undefined) {
|
||||||
this.rooms_ = {};
|
this.rooms_ = {};
|
||||||
}
|
}
|
||||||
this.rooms_[room.room_id] = mesh;
|
this.rooms_[room.room_id] = mesh;
|
||||||
|
|
||||||
|
layer.add(mesh);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -849,9 +833,10 @@ beestat.component.scene.prototype.update_debug_ = function() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a group containing all of the extruded geometry.
|
* Add a group containing all of the extruded geometry that can be transformed
|
||||||
|
* all together.
|
||||||
*/
|
*/
|
||||||
beestat.component.scene.prototype.add_group_ = function() {
|
beestat.component.scene.prototype.add_main_group_ = function() {
|
||||||
const bounding_box = beestat.floor_plan.get_bounding_box(this.floor_plan_id_);
|
const bounding_box = beestat.floor_plan.get_bounding_box(this.floor_plan_id_);
|
||||||
// this.floor_plan_center_x_ = ;
|
// this.floor_plan_center_x_ = ;
|
||||||
// this.floor_plan_center_y_ = (bounding_box.bottom + bounding_box.top) / 2;
|
// this.floor_plan_center_y_ = (bounding_box.bottom + bounding_box.top) / 2;
|
||||||
@ -859,13 +844,13 @@ beestat.component.scene.prototype.add_group_ = function() {
|
|||||||
// this.view_box_.x = center_x - (this.view_box_.width / 2);
|
// this.view_box_.x = center_x - (this.view_box_.width / 2);
|
||||||
// this.view_box_.y = center_y - (this.view_box_.height / 2);
|
// this.view_box_.y = center_y - (this.view_box_.height / 2);
|
||||||
|
|
||||||
this.group_ = new THREE.Group();
|
this.main_group_ = new THREE.Group();
|
||||||
this.group_.translateX((bounding_box.right + bounding_box.left) / -2);
|
this.main_group_.translateX((bounding_box.right + bounding_box.left) / -2);
|
||||||
this.group_.translateZ((bounding_box.bottom + bounding_box.top) / -2);
|
this.main_group_.translateZ((bounding_box.bottom + bounding_box.top) / -2);
|
||||||
// this.group_.rotation.x = -Math.PI / 2;
|
// this.main_group_.rotation.x = -Math.PI / 2;
|
||||||
//
|
//
|
||||||
this.group_.rotation.x = Math.PI / 2;
|
this.main_group_.rotation.x = Math.PI / 2;
|
||||||
this.scene_.add(this.group_);
|
this.scene_.add(this.main_group_);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -875,9 +860,13 @@ beestat.component.scene.prototype.add_floor_plan_ = function() {
|
|||||||
const self = this;
|
const self = this;
|
||||||
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
const floor_plan = beestat.cache.floor_plan[this.floor_plan_id_];
|
||||||
|
|
||||||
floor_plan.data.groups.forEach(function(group) {
|
this.layers_ = {};
|
||||||
|
floor_plan.data.groups.forEach(function(group, i) {
|
||||||
|
const layer = new THREE.Group();
|
||||||
|
self.main_group_.add(layer);
|
||||||
|
self.layers_['group_' + i] = layer;
|
||||||
group.rooms.forEach(function(room) {
|
group.rooms.forEach(function(room) {
|
||||||
self.add_room_(group, room);
|
self.add_room_(layer, group, room);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@ -949,3 +938,43 @@ beestat.component.scene.prototype.set_heat_map_max = function(heat_map_max) {
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the visibility of a layer.
|
||||||
|
*
|
||||||
|
* @param {string} layer_name
|
||||||
|
* @param {boolean} visible
|
||||||
|
*
|
||||||
|
* @return {beestat.component.scene}
|
||||||
|
*/
|
||||||
|
beestat.component.scene.prototype.set_layer_visible = function(layer_name, visible) {
|
||||||
|
this.layers_[layer_name].visible = visible;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether or not auto-rotate is enabled.
|
||||||
|
*
|
||||||
|
* @param {boolean} auto_rotate
|
||||||
|
*
|
||||||
|
* @return {beestat.component.scene}
|
||||||
|
*/
|
||||||
|
beestat.component.scene.prototype.set_auto_rotate = function(auto_rotate) {
|
||||||
|
this.controls_.autoRotate = auto_rotate;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the gradient.
|
||||||
|
*
|
||||||
|
* @param {boolean} gradient
|
||||||
|
*
|
||||||
|
* @return {beestat.component.scene}
|
||||||
|
*/
|
||||||
|
beestat.component.scene.prototype.set_gradient = function(gradient) {
|
||||||
|
this.gradient_ = gradient;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user