mirror of
https://github.com/beestat/app.git
synced 2025-06-03 05:36:51 -04:00
Fixed #165 - Convert Temperature Profiles to chart2
Also fixed #173 - Runtime Summary - No title/subtitle or filename on export.
This commit is contained in:
parent
9992abc592
commit
43e547198b
@ -29,6 +29,9 @@ class thermostat_group extends cora\crud {
|
|||||||
public static $converged = [
|
public static $converged = [
|
||||||
'temperature_profile' => [
|
'temperature_profile' => [
|
||||||
'type' => 'json'
|
'type' => 'json'
|
||||||
|
],
|
||||||
|
'weather' => [
|
||||||
|
'type' => 'json'
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -314,7 +317,8 @@ class thermostat_group extends cora\crud {
|
|||||||
'property_age',
|
'property_age',
|
||||||
'property_square_feet',
|
'property_square_feet',
|
||||||
'property_stories',
|
'property_stories',
|
||||||
'property_structure_type'
|
'property_structure_type',
|
||||||
|
'weather'
|
||||||
];
|
];
|
||||||
|
|
||||||
$thermostats = $this->api(
|
$thermostats = $this->api(
|
||||||
@ -377,6 +381,11 @@ class thermostat_group extends cora\crud {
|
|||||||
$final_attributes[$attribute] = $system_type;
|
$final_attributes[$attribute] = $system_type;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
// Stuff that doesn't really matter (weather); just pick the last
|
||||||
|
// one.
|
||||||
|
$final_attributes[$attribute] = $thermostat[$attribute];
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,9 @@ beestat.setting = function(key, opt_value, opt_callback) {
|
|||||||
'runtime_thermostat_summary_gap_fill': true,
|
'runtime_thermostat_summary_gap_fill': true,
|
||||||
|
|
||||||
'comparison_region': 'global',
|
'comparison_region': 'global',
|
||||||
'comparison_property_type': 'similar'
|
'comparison_property_type': 'similar',
|
||||||
|
|
||||||
|
'temperature_unit': '°F'
|
||||||
};
|
};
|
||||||
|
|
||||||
if (user.json_settings === null) {
|
if (user.json_settings === null) {
|
||||||
|
@ -279,3 +279,22 @@ beestat.series.calendar_event_other = {
|
|||||||
'name': 'Other',
|
'name': 'Other',
|
||||||
'color': beestat.style.color.gray.base
|
'color': beestat.style.color.gray.base
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Temperature Profiles
|
||||||
|
beestat.series.indoor_heat_delta = {
|
||||||
|
'name': 'Indoor Heat Δ',
|
||||||
|
'color': beestat.series.compressor_heat_1.color
|
||||||
|
};
|
||||||
|
beestat.series.indoor_heat_delta_raw = beestat.series.indoor_heat_delta;
|
||||||
|
|
||||||
|
beestat.series.indoor_cool_delta = {
|
||||||
|
'name': 'Indoor Cool Δ',
|
||||||
|
'color': beestat.series.compressor_cool_1.color
|
||||||
|
};
|
||||||
|
beestat.series.indoor_cool_delta_raw = beestat.series.indoor_cool_delta;
|
||||||
|
|
||||||
|
beestat.series.indoor_resist_delta = {
|
||||||
|
'name': 'Indoor Δ',
|
||||||
|
'color': beestat.style.color.gray.dark
|
||||||
|
};
|
||||||
|
beestat.series.indoor_resist_delta_raw = beestat.series.indoor_resist_delta;
|
||||||
|
@ -50,10 +50,7 @@ beestat.extend(beestat.component.card.runtime_thermostat_summary, beestat.compon
|
|||||||
*/
|
*/
|
||||||
beestat.component.card.runtime_thermostat_summary.prototype.decorate_contents_ = function(parent) {
|
beestat.component.card.runtime_thermostat_summary.prototype.decorate_contents_ = function(parent) {
|
||||||
var data = this.get_data_();
|
var data = this.get_data_();
|
||||||
this.chart_ = new beestat.component.chart2.runtime_thermostat_summary(
|
this.chart_ = new beestat.component.chart2.runtime_thermostat_summary(data);
|
||||||
this.thermostat_id_,
|
|
||||||
data
|
|
||||||
);
|
|
||||||
this.chart_.render(parent);
|
this.chart_.render(parent);
|
||||||
|
|
||||||
var sync_progress = beestat.get_sync_progress(this.thermostat_id_);
|
var sync_progress = beestat.get_sync_progress(this.thermostat_id_);
|
||||||
@ -117,7 +114,11 @@ beestat.component.card.runtime_thermostat_summary.prototype.get_data_ = function
|
|||||||
'x': [],
|
'x': [],
|
||||||
'series': {},
|
'series': {},
|
||||||
'metadata': {
|
'metadata': {
|
||||||
'series': {}
|
'series': {},
|
||||||
|
'chart': {
|
||||||
|
'title': this.get_title_(),
|
||||||
|
'subtitle': this.get_subtitle_()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,7 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* Temperature profiles.
|
* Temperature profiles.
|
||||||
|
*
|
||||||
|
* @param {number} thermostat_group_id The thermostat_group_id this card is
|
||||||
|
* displaying data for.
|
||||||
*/
|
*/
|
||||||
beestat.component.card.temperature_profiles = function() {
|
beestat.component.card.temperature_profiles = function(thermostat_group_id) {
|
||||||
|
this.thermostat_group_id_ = thermostat_group_id;
|
||||||
|
|
||||||
beestat.component.card.apply(this, arguments);
|
beestat.component.card.apply(this, arguments);
|
||||||
};
|
};
|
||||||
beestat.extend(beestat.component.card.temperature_profiles, beestat.component.card);
|
beestat.extend(beestat.component.card.temperature_profiles, beestat.component.card);
|
||||||
@ -12,15 +17,36 @@ beestat.extend(beestat.component.card.temperature_profiles, beestat.component.ca
|
|||||||
* @param {rocket.Elements} parent
|
* @param {rocket.Elements} parent
|
||||||
*/
|
*/
|
||||||
beestat.component.card.temperature_profiles.prototype.decorate_contents_ = function(parent) {
|
beestat.component.card.temperature_profiles.prototype.decorate_contents_ = function(parent) {
|
||||||
var self = this;
|
var data = this.get_data_();
|
||||||
|
this.chart_ = new beestat.component.chart2.temperature_profiles(data);
|
||||||
|
this.chart_.render(parent);
|
||||||
|
};
|
||||||
|
|
||||||
var thermostat = beestat.cache.thermostat[beestat.setting('thermostat_id')];
|
/**
|
||||||
|
* Get all of the series data.
|
||||||
|
*
|
||||||
|
* @return {object} The series data.
|
||||||
|
*/
|
||||||
|
beestat.component.card.temperature_profiles.prototype.get_data_ = function() {
|
||||||
var thermostat_group = beestat.cache.thermostat_group[
|
var thermostat_group = beestat.cache.thermostat_group[
|
||||||
thermostat.thermostat_group_id
|
this.thermostat_group_id_
|
||||||
];
|
];
|
||||||
|
|
||||||
this.chart_ = new beestat.component.chart();
|
var data = {
|
||||||
this.chart_.options.chart.height = 300;
|
'x': [],
|
||||||
|
'series': {},
|
||||||
|
'metadata': {
|
||||||
|
'series': {},
|
||||||
|
'chart': {
|
||||||
|
'title': this.get_title_(),
|
||||||
|
'subtitle': this.get_subtitle_(),
|
||||||
|
'outdoor_temperature': beestat.temperature({
|
||||||
|
'temperature': (thermostat_group.weather.temperature / 10),
|
||||||
|
'round': 0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (
|
if (
|
||||||
thermostat_group.temperature_profile === null
|
thermostat_group.temperature_profile === null
|
||||||
@ -28,10 +54,6 @@ beestat.component.card.temperature_profiles.prototype.decorate_contents_ = funct
|
|||||||
this.chart_.render(parent);
|
this.chart_.render(parent);
|
||||||
this.show_loading_('Calculating');
|
this.show_loading_('Calculating');
|
||||||
} else {
|
} else {
|
||||||
// var x_categories = [];
|
|
||||||
var trendlines = {};
|
|
||||||
var raw = {};
|
|
||||||
|
|
||||||
// Global x range.
|
// Global x range.
|
||||||
var x_min = Infinity;
|
var x_min = Infinity;
|
||||||
var x_max = -Infinity;
|
var x_max = -Infinity;
|
||||||
@ -69,8 +91,8 @@ beestat.component.card.temperature_profiles.prototype.decorate_contents_ = funct
|
|||||||
x_min = Math.min(x_min, this_x_min);
|
x_min = Math.min(x_min, this_x_min);
|
||||||
x_max = Math.max(x_max, this_x_max);
|
x_max = Math.max(x_max, this_x_max);
|
||||||
|
|
||||||
trendlines[type] = [];
|
data.series['trendline_' + type] = [];
|
||||||
raw[type] = [];
|
data.series['raw_' + type] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data is stored internally as °F with 1 value per degree. That data
|
* Data is stored internally as °F with 1 value per degree. That data
|
||||||
@ -87,7 +109,7 @@ beestat.component.card.temperature_profiles.prototype.decorate_contents_ = funct
|
|||||||
*/
|
*/
|
||||||
var increment;
|
var increment;
|
||||||
var fixed;
|
var fixed;
|
||||||
if (thermostat.temperature_unit === '°F') {
|
if (beestat.setting('temperature_unit') === '°F') {
|
||||||
increment = 1;
|
increment = 1;
|
||||||
fixed = 0;
|
fixed = 0;
|
||||||
} else {
|
} else {
|
||||||
@ -99,240 +121,27 @@ beestat.component.card.temperature_profiles.prototype.decorate_contents_ = funct
|
|||||||
var y = (linear_trendline.slope * x_fixed) +
|
var y = (linear_trendline.slope * x_fixed) +
|
||||||
linear_trendline.intercept;
|
linear_trendline.intercept;
|
||||||
|
|
||||||
trendlines[type].push([
|
data.series['trendline_' + type].push([
|
||||||
parseFloat(x_fixed),
|
parseFloat(x_fixed),
|
||||||
y
|
y
|
||||||
]);
|
]);
|
||||||
if (profile.deltas[x_fixed] !== undefined) {
|
if (profile.deltas[x_fixed] !== undefined) {
|
||||||
raw[type].push([
|
data.series['raw_' + type].push([
|
||||||
parseFloat(x_fixed),
|
parseFloat(x_fixed),
|
||||||
profile.deltas[x_fixed]
|
profile.deltas[x_fixed]
|
||||||
]);
|
]);
|
||||||
y_min = Math.min(y_min, profile.deltas[x_fixed]);
|
y_min = Math.min(y_min, profile.deltas[x_fixed]);
|
||||||
y_max = Math.max(y_max, profile.deltas[x_fixed]);
|
y_max = Math.max(y_max, profile.deltas[x_fixed]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
data.metadata.chart.y_min = y_min;
|
||||||
|
data.metadata.chart.y_max = y_max;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Set y_min and y_max to be equal but opposite so the graph is always
|
|
||||||
* centered.
|
|
||||||
*/
|
|
||||||
var absolute_y_max = Math.max(Math.abs(y_min), Math.abs(y_max));
|
|
||||||
y_min = absolute_y_max * -1;
|
|
||||||
y_max = absolute_y_max;
|
|
||||||
|
|
||||||
// Chart
|
|
||||||
this.chart_.options.exporting.chartOptions.title.text = this.get_title_();
|
|
||||||
this.chart_.options.exporting.chartOptions.subtitle.text = this.get_subtitle_();
|
|
||||||
|
|
||||||
this.chart_.options.chart.backgroundColor = beestat.style.color.bluegray.base;
|
|
||||||
this.chart_.options.exporting.filename = 'Temperature Profiles';
|
|
||||||
this.chart_.options.chart.zoomType = null;
|
|
||||||
this.chart_.options.plotOptions.series.connectNulls = true;
|
|
||||||
this.chart_.options.legend = {'enabled': false};
|
|
||||||
|
|
||||||
this.chart_.options.xAxis = {
|
|
||||||
'lineWidth': 0,
|
|
||||||
'tickLength': 0,
|
|
||||||
'tickInterval': 5,
|
|
||||||
'gridLineWidth': 1,
|
|
||||||
'gridLineColor': beestat.style.color.bluegray.light,
|
|
||||||
'gridLineDashStyle': 'longdash',
|
|
||||||
'labels': {
|
|
||||||
'style': {'color': beestat.style.color.gray.base},
|
|
||||||
'formatter': function() {
|
|
||||||
return this.value + thermostat.temperature_unit;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'plotLines': [
|
|
||||||
{
|
|
||||||
'color': beestat.series.outdoor_temperature.color,
|
|
||||||
'dashStyle': 'ShortDash',
|
|
||||||
'width': 1,
|
|
||||||
'value': beestat.temperature(thermostat.weather.temperature),
|
|
||||||
'zIndex': 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
this.chart_.options.yAxis = [
|
|
||||||
{
|
|
||||||
'alignTicks': false,
|
|
||||||
'gridLineColor': beestat.style.color.bluegray.light,
|
|
||||||
'gridLineDashStyle': 'longdash',
|
|
||||||
'title': {'text': null},
|
|
||||||
'labels': {
|
|
||||||
'style': {'color': beestat.style.color.gray.base},
|
|
||||||
'formatter': function() {
|
|
||||||
return this.value + thermostat.temperature_unit;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'min': y_min,
|
|
||||||
'max': y_max,
|
|
||||||
'plotLines': [
|
|
||||||
{
|
|
||||||
'color': beestat.style.color.bluegray.light,
|
|
||||||
'dashStyle': 'solid',
|
|
||||||
'width': 3,
|
|
||||||
'value': 0,
|
|
||||||
'zIndex': 1
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
this.chart_.options.tooltip = {
|
|
||||||
'shared': true,
|
|
||||||
'useHTML': true,
|
|
||||||
'borderWidth': 0,
|
|
||||||
'shadow': false,
|
|
||||||
'backgroundColor': null,
|
|
||||||
'followPointer': true,
|
|
||||||
'crosshairs': {
|
|
||||||
'width': 1,
|
|
||||||
'zIndex': 100,
|
|
||||||
'color': beestat.style.color.gray.light,
|
|
||||||
'dashStyle': 'shortDot',
|
|
||||||
'snap': false
|
|
||||||
},
|
|
||||||
'positioner': function(tooltip_width, tooltip_height, point) {
|
|
||||||
return beestat.component.chart.tooltip_positioner(
|
|
||||||
self.chart_.get_chart(),
|
|
||||||
tooltip_width,
|
|
||||||
tooltip_height,
|
|
||||||
point
|
|
||||||
);
|
|
||||||
},
|
|
||||||
'formatter': function() {
|
|
||||||
var sections = [];
|
|
||||||
var section = [];
|
|
||||||
this.points.forEach(function(point) {
|
|
||||||
var series = point.series;
|
|
||||||
|
|
||||||
var value = beestat.temperature({
|
|
||||||
'temperature': point.y,
|
|
||||||
'units': true,
|
|
||||||
'convert': false,
|
|
||||||
'delta': true,
|
|
||||||
'type': 'string'
|
|
||||||
}) + ' / hour';
|
|
||||||
|
|
||||||
if (series.name.indexOf('Raw') === -1) {
|
|
||||||
section.push({
|
|
||||||
'label': series.name,
|
|
||||||
'value': value,
|
|
||||||
'color': series.color
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
sections.push(section);
|
|
||||||
|
|
||||||
return beestat.component.chart.tooltip_formatter(
|
|
||||||
'Outdoor Temp: ' +
|
|
||||||
beestat.temperature({
|
|
||||||
'temperature': this.x,
|
|
||||||
'round': 0,
|
|
||||||
'units': true,
|
|
||||||
'convert': false
|
|
||||||
}),
|
|
||||||
sections
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this.chart_.options.series = [];
|
|
||||||
|
|
||||||
// Trendline data
|
|
||||||
this.chart_.options.series.push({
|
|
||||||
'data': trendlines.heat,
|
|
||||||
'name': 'Indoor Heat Δ',
|
|
||||||
'color': beestat.series.compressor_heat_1.color,
|
|
||||||
'marker': {
|
|
||||||
'enabled': false,
|
|
||||||
'states': {'hover': {'enabled': false}}
|
|
||||||
},
|
|
||||||
'type': 'line',
|
|
||||||
'lineWidth': 2,
|
|
||||||
'states': {'hover': {'lineWidthPlus': 0}}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Trendline data
|
|
||||||
this.chart_.options.series.push({
|
|
||||||
'data': trendlines.cool,
|
|
||||||
'name': 'Indoor Cool Δ',
|
|
||||||
'color': beestat.series.compressor_cool_1.color,
|
|
||||||
'marker': {
|
|
||||||
'enabled': false,
|
|
||||||
'states': {'hover': {'enabled': false}}
|
|
||||||
},
|
|
||||||
'type': 'line',
|
|
||||||
'lineWidth': 2,
|
|
||||||
'states': {'hover': {'lineWidthPlus': 0}}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Trendline data
|
|
||||||
this.chart_.options.series.push({
|
|
||||||
'data': trendlines.resist,
|
|
||||||
'name': 'Indoor Δ',
|
|
||||||
'color': beestat.style.color.gray.dark,
|
|
||||||
'marker': {
|
|
||||||
'enabled': false,
|
|
||||||
'states': {'hover': {'enabled': false}}
|
|
||||||
},
|
|
||||||
'type': 'line',
|
|
||||||
'lineWidth': 2,
|
|
||||||
'states': {'hover': {'lineWidthPlus': 0}}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Raw data
|
|
||||||
this.chart_.options.series.push({
|
|
||||||
'data': raw.heat,
|
|
||||||
'name': 'Heat Raw',
|
|
||||||
'color': beestat.series.compressor_heat_1.color,
|
|
||||||
'dashStyle': 'ShortDot',
|
|
||||||
'marker': {
|
|
||||||
'enabled': false,
|
|
||||||
'states': {'hover': {'enabled': false}}
|
|
||||||
},
|
|
||||||
'type': 'spline',
|
|
||||||
'lineWidth': 1,
|
|
||||||
'states': {'hover': {'lineWidthPlus': 0}}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Raw data
|
|
||||||
this.chart_.options.series.push({
|
|
||||||
'data': raw.cool,
|
|
||||||
'name': 'Cool Raw',
|
|
||||||
'color': beestat.series.compressor_cool_1.color,
|
|
||||||
'dashStyle': 'ShortDot',
|
|
||||||
'marker': {
|
|
||||||
'enabled': false,
|
|
||||||
'states': {'hover': {'enabled': false}}
|
|
||||||
},
|
|
||||||
'type': 'spline',
|
|
||||||
'lineWidth': 1,
|
|
||||||
'states': {'hover': {'lineWidthPlus': 0}}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Raw data
|
|
||||||
this.chart_.options.series.push({
|
|
||||||
'data': raw.resist,
|
|
||||||
'name': 'Resist Raw',
|
|
||||||
'color': beestat.style.color.gray.dark,
|
|
||||||
'dashStyle': 'ShortDot',
|
|
||||||
'marker': {
|
|
||||||
'enabled': false,
|
|
||||||
'states': {'hover': {'enabled': false}}
|
|
||||||
},
|
|
||||||
'type': 'spline',
|
|
||||||
'lineWidth': 1,
|
|
||||||
'states': {'hover': {'lineWidthPlus': 0}}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.chart_.render(parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* Runtime thermostat summary chart.
|
* Runtime thermostat summary chart.
|
||||||
*
|
*
|
||||||
* @param {number} thermostat_id The thermostat_id this chart is showing data
|
|
||||||
* for.
|
|
||||||
* @param {object} data The chart data.
|
* @param {object} data The chart data.
|
||||||
*/
|
*/
|
||||||
beestat.component.chart2.runtime_thermostat_summary = function(thermostat_id, data) {
|
beestat.component.chart2.runtime_thermostat_summary = function(data) {
|
||||||
beestat.component.chart2.apply(this, arguments);
|
|
||||||
this.thermostat_id_ = thermostat_id;
|
|
||||||
this.data_ = data;
|
this.data_ = data;
|
||||||
|
|
||||||
|
beestat.component.chart2.apply(this, arguments);
|
||||||
};
|
};
|
||||||
beestat.extend(beestat.component.chart2.runtime_thermostat_summary, beestat.component.chart2);
|
beestat.extend(beestat.component.chart2.runtime_thermostat_summary, beestat.component.chart2);
|
||||||
|
|
||||||
@ -189,7 +187,7 @@ beestat.component.chart2.runtime_thermostat_summary.prototype.get_options_yAxis_
|
|||||||
'color': beestat.style.color.gray.base
|
'color': beestat.style.color.gray.base
|
||||||
},
|
},
|
||||||
'formatter': function() {
|
'formatter': function() {
|
||||||
return this.value + beestat.cache.thermostat[self.thermostat_id_].temperature_unit;
|
return this.value + beestat.setting('temperature_unit');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
287
js/component/chart/temperature_profiles.js
Normal file
287
js/component/chart/temperature_profiles.js
Normal file
@ -0,0 +1,287 @@
|
|||||||
|
/**
|
||||||
|
* Temperature profiles chart.
|
||||||
|
*
|
||||||
|
* @param {object} data The chart data.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles = function(data) {
|
||||||
|
this.data_ = data;
|
||||||
|
|
||||||
|
beestat.component.chart2.apply(this, arguments);
|
||||||
|
};
|
||||||
|
beestat.extend(beestat.component.chart2.temperature_profiles, beestat.component.chart2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_xAxis_labels_formatter_.
|
||||||
|
*
|
||||||
|
* @return {Function} xAxis labels formatter.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_xAxis_labels_formatter_ = function() {
|
||||||
|
return function() {
|
||||||
|
return this.value + beestat.setting('temperature_unit');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_series_.
|
||||||
|
*
|
||||||
|
* @return {Array} All of the series to display on the chart.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_series_ = function() {
|
||||||
|
var series = [];
|
||||||
|
|
||||||
|
// Trendline data
|
||||||
|
series.push({
|
||||||
|
'data': this.data_.series.trendline_heat,
|
||||||
|
'name': 'indoor_heat_delta',
|
||||||
|
'color': beestat.series.compressor_heat_1.color,
|
||||||
|
'marker': {
|
||||||
|
'enabled': false,
|
||||||
|
'states': {'hover': {'enabled': false}}
|
||||||
|
},
|
||||||
|
'type': 'line',
|
||||||
|
'lineWidth': 2,
|
||||||
|
'states': {'hover': {'lineWidthPlus': 0}}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Trendline data
|
||||||
|
series.push({
|
||||||
|
'data': this.data_.series.trendline_cool,
|
||||||
|
'name': 'indoor_cool_delta',
|
||||||
|
'color': beestat.series.compressor_cool_1.color,
|
||||||
|
'marker': {
|
||||||
|
'enabled': false,
|
||||||
|
'states': {'hover': {'enabled': false}}
|
||||||
|
},
|
||||||
|
'type': 'line',
|
||||||
|
'lineWidth': 2,
|
||||||
|
'states': {'hover': {'lineWidthPlus': 0}}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Trendline data
|
||||||
|
series.push({
|
||||||
|
'data': this.data_.series.trendline_resist,
|
||||||
|
'name': 'indoor_resist_delta',
|
||||||
|
'color': beestat.style.color.gray.dark,
|
||||||
|
'marker': {
|
||||||
|
'enabled': false,
|
||||||
|
'states': {'hover': {'enabled': false}}
|
||||||
|
},
|
||||||
|
'type': 'line',
|
||||||
|
'lineWidth': 2,
|
||||||
|
'states': {'hover': {'lineWidthPlus': 0}}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Raw data
|
||||||
|
series.push({
|
||||||
|
'data': this.data_.series.raw_heat,
|
||||||
|
'name': 'indoor_heat_delta_raw',
|
||||||
|
'color': beestat.series.compressor_heat_1.color,
|
||||||
|
'dashStyle': 'ShortDot',
|
||||||
|
'marker': {
|
||||||
|
'enabled': false,
|
||||||
|
'states': {'hover': {'enabled': false}}
|
||||||
|
},
|
||||||
|
'type': 'spline',
|
||||||
|
'lineWidth': 1,
|
||||||
|
'states': {'hover': {'lineWidthPlus': 0}}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Raw data
|
||||||
|
series.push({
|
||||||
|
'data': this.data_.series.raw_cool,
|
||||||
|
'name': 'indoor_cool_delta_raw',
|
||||||
|
'color': beestat.series.compressor_cool_1.color,
|
||||||
|
'dashStyle': 'ShortDot',
|
||||||
|
'marker': {
|
||||||
|
'enabled': false,
|
||||||
|
'states': {'hover': {'enabled': false}}
|
||||||
|
},
|
||||||
|
'type': 'spline',
|
||||||
|
'lineWidth': 1,
|
||||||
|
'states': {'hover': {'lineWidthPlus': 0}}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Raw data
|
||||||
|
series.push({
|
||||||
|
'data': this.data_.series.raw_resist,
|
||||||
|
'name': 'indoor_resist_delta_raw',
|
||||||
|
'color': beestat.style.color.gray.dark,
|
||||||
|
'dashStyle': 'ShortDot',
|
||||||
|
'marker': {
|
||||||
|
'enabled': false,
|
||||||
|
'states': {'hover': {'enabled': false}}
|
||||||
|
},
|
||||||
|
'type': 'spline',
|
||||||
|
'lineWidth': 1,
|
||||||
|
'states': {'hover': {'lineWidthPlus': 0}}
|
||||||
|
});
|
||||||
|
|
||||||
|
return series;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_yAxis_.
|
||||||
|
*
|
||||||
|
* @return {Array} The y-axis options.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_yAxis_ = function() {
|
||||||
|
var absolute_y_max = Math.max(
|
||||||
|
Math.abs(this.data_.metadata.chart.y_min),
|
||||||
|
Math.abs(this.data_.metadata.chart.y_max)
|
||||||
|
);
|
||||||
|
|
||||||
|
var y_min = absolute_y_max * -1;
|
||||||
|
var y_max = absolute_y_max;
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
'alignTicks': false,
|
||||||
|
'gridLineColor': beestat.style.color.bluegray.light,
|
||||||
|
'gridLineDashStyle': 'longdash',
|
||||||
|
'title': {'text': null},
|
||||||
|
'labels': {
|
||||||
|
'style': {'color': beestat.style.color.gray.base},
|
||||||
|
'formatter': function() {
|
||||||
|
return this.value + beestat.setting('temperature_unit');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'min': y_min,
|
||||||
|
'max': y_max,
|
||||||
|
'plotLines': [
|
||||||
|
{
|
||||||
|
'color': beestat.style.color.bluegray.light,
|
||||||
|
'dashStyle': 'solid',
|
||||||
|
'width': 3,
|
||||||
|
'value': 0,
|
||||||
|
'zIndex': 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_tooltip_formatter_.
|
||||||
|
*
|
||||||
|
* @return {Function} The tooltip formatter.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_tooltip_formatter_ = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
return function() {
|
||||||
|
var sections = [];
|
||||||
|
var section = [];
|
||||||
|
this.points.forEach(function(point) {
|
||||||
|
var series = point.series;
|
||||||
|
|
||||||
|
var value = beestat.temperature({
|
||||||
|
'temperature': point.y,
|
||||||
|
'units': true,
|
||||||
|
'convert': false,
|
||||||
|
'delta': true,
|
||||||
|
'type': 'string'
|
||||||
|
}) + ' / h';
|
||||||
|
|
||||||
|
if (series.name.indexOf('raw') === -1) {
|
||||||
|
section.push({
|
||||||
|
'label': beestat.series[series.name].name,
|
||||||
|
'value': value,
|
||||||
|
'color': series.color
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
sections.push(section);
|
||||||
|
|
||||||
|
return self.tooltip_formatter_helper_(
|
||||||
|
'Outdoor Temp: ' +
|
||||||
|
beestat.temperature({
|
||||||
|
'temperature': this.x,
|
||||||
|
'round': 0,
|
||||||
|
'units': true,
|
||||||
|
'convert': false
|
||||||
|
}),
|
||||||
|
sections
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_chart_zoomType_.
|
||||||
|
*
|
||||||
|
* @return {string} The zoom type.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_chart_zoomType_ = function() {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_legend_.
|
||||||
|
*
|
||||||
|
* @return {object} The legend options.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_legend_ = function() {
|
||||||
|
return {
|
||||||
|
'enabled': false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_xAxis_.
|
||||||
|
*
|
||||||
|
* @return {object} The xAxis options.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_xAxis_ = function() {
|
||||||
|
return {
|
||||||
|
'lineWidth': 0,
|
||||||
|
'tickLength': 0,
|
||||||
|
'tickInterval': 5,
|
||||||
|
'gridLineWidth': 1,
|
||||||
|
'gridLineColor': beestat.style.color.bluegray.light,
|
||||||
|
'gridLineDashStyle': 'longdash',
|
||||||
|
'labels': {
|
||||||
|
'style': {
|
||||||
|
'color': beestat.style.color.gray.base
|
||||||
|
},
|
||||||
|
'formatter': this.get_options_xAxis_labels_formatter_()
|
||||||
|
},
|
||||||
|
'plotLines': [
|
||||||
|
{
|
||||||
|
'color': beestat.series.outdoor_temperature.color,
|
||||||
|
'dashStyle': 'ShortDash',
|
||||||
|
'width': 1,
|
||||||
|
'label': {
|
||||||
|
'style': {
|
||||||
|
'color': beestat.series.outdoor_temperature.color
|
||||||
|
},
|
||||||
|
'useHTML': true,
|
||||||
|
'text': 'Now: ' + beestat.temperature({
|
||||||
|
'temperature': this.data_.metadata.chart.outdoor_temperature,
|
||||||
|
'convert': false,
|
||||||
|
'units': true,
|
||||||
|
'round': 0
|
||||||
|
})
|
||||||
|
},
|
||||||
|
'value': this.data_.metadata.chart.outdoor_temperature,
|
||||||
|
'zIndex': 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_chart_height_.
|
||||||
|
*
|
||||||
|
* @return {number} The height of the chart.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_chart_height_ = function() {
|
||||||
|
return 300;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override for get_options_plotOptions_series_connectNulls_.
|
||||||
|
*
|
||||||
|
* @return {boolean} Whether or not to connect nulls.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.temperature_profiles.prototype.get_options_plotOptions_series_connectNulls_ = function() {
|
||||||
|
return true;
|
||||||
|
};
|
@ -105,7 +105,8 @@ beestat.component.chart2.prototype.get_options_plotOptions_ = function() {
|
|||||||
'inactive': {
|
'inactive': {
|
||||||
'opacity': 1
|
'opacity': 1
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
'connectNulls': this.get_options_plotOptions_series_connectNulls_()
|
||||||
},
|
},
|
||||||
'column': {
|
'column': {
|
||||||
'pointPadding': 0,
|
'pointPadding': 0,
|
||||||
@ -118,6 +119,15 @@ beestat.component.chart2.prototype.get_options_plotOptions_ = function() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get whether or not to connect nulls.
|
||||||
|
*
|
||||||
|
* @return {boolean} Whether or not to connect nulls.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.prototype.get_options_plotOptions_series_connectNulls_ = function() {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the title options.
|
* Get the title options.
|
||||||
*
|
*
|
||||||
@ -156,7 +166,7 @@ beestat.component.chart2.prototype.get_options_chart_ = function() {
|
|||||||
0,
|
0,
|
||||||
0
|
0
|
||||||
],
|
],
|
||||||
'zoomType': 'x',
|
'zoomType': this.get_options_chart_zoomType_(),
|
||||||
'panning': true,
|
'panning': true,
|
||||||
'panKey': 'ctrl',
|
'panKey': 'ctrl',
|
||||||
'backgroundColor': beestat.style.color.bluegray.base,
|
'backgroundColor': beestat.style.color.bluegray.base,
|
||||||
@ -164,10 +174,29 @@ beestat.component.chart2.prototype.get_options_chart_ = function() {
|
|||||||
'theme': {
|
'theme': {
|
||||||
'display': 'none'
|
'display': 'none'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
'height': this.get_options_chart_height_()
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the height of the chart.
|
||||||
|
*
|
||||||
|
* @return {number} The height of the chart.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.prototype.get_options_chart_height_ = function() {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the zoomType option. Return null for no zoom.
|
||||||
|
*
|
||||||
|
* @return {string} The zoom type.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.prototype.get_options_chart_zoomType_ = function() {
|
||||||
|
return 'x';
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the export options.
|
* Get the export options.
|
||||||
*
|
*
|
||||||
@ -178,14 +207,14 @@ beestat.component.chart2.prototype.get_options_exporting_ = function() {
|
|||||||
'enabled': false,
|
'enabled': false,
|
||||||
'sourceWidth': 980,
|
'sourceWidth': 980,
|
||||||
'scale': 1,
|
'scale': 1,
|
||||||
'filename': 'beestat',
|
'filename': this.get_options_exporting_filename_(),
|
||||||
'chartOptions': {
|
'chartOptions': {
|
||||||
'credits': {
|
'credits': {
|
||||||
'text': 'beestat.io'
|
'text': 'beestat.io'
|
||||||
},
|
},
|
||||||
'title': {
|
'title': {
|
||||||
'align': 'left',
|
'align': 'left',
|
||||||
'text': null,
|
'text': this.get_options_exporting_chartOptions_title_text_(),
|
||||||
'margin': beestat.style.size.gutter,
|
'margin': beestat.style.size.gutter,
|
||||||
'style': {
|
'style': {
|
||||||
'color': '#fff',
|
'color': '#fff',
|
||||||
@ -195,7 +224,7 @@ beestat.component.chart2.prototype.get_options_exporting_ = function() {
|
|||||||
},
|
},
|
||||||
'subtitle': {
|
'subtitle': {
|
||||||
'align': 'left',
|
'align': 'left',
|
||||||
'text': null,
|
'text': this.get_options_exporting_chartOptions_subtitle_text_(),
|
||||||
'style': {
|
'style': {
|
||||||
'color': '#fff',
|
'color': '#fff',
|
||||||
'font-weight': beestat.style.font_weight.light,
|
'font-weight': beestat.style.font_weight.light,
|
||||||
@ -217,6 +246,50 @@ beestat.component.chart2.prototype.get_options_exporting_ = function() {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the exported chart title.
|
||||||
|
*
|
||||||
|
* @return {string} The exported chart title.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.prototype.get_options_exporting_chartOptions_title_text_ = function() {
|
||||||
|
return this.data_.metadata.chart.title;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the exported chart subtitle.
|
||||||
|
*
|
||||||
|
* @return {string} The exported chart subtitle.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.prototype.get_options_exporting_chartOptions_subtitle_text_ = function() {
|
||||||
|
return this.data_.metadata.chart.subtitle;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the exported chart filename.
|
||||||
|
*
|
||||||
|
* @return {string} The exported chart filename.
|
||||||
|
*/
|
||||||
|
beestat.component.chart2.prototype.get_options_exporting_filename_ = function() {
|
||||||
|
var title = this.get_options_exporting_chartOptions_title_text_();
|
||||||
|
var subtitle = this.get_options_exporting_chartOptions_subtitle_text_();
|
||||||
|
|
||||||
|
var filename = [];
|
||||||
|
if (title !== null) {
|
||||||
|
filename.push(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (subtitle !== null) {
|
||||||
|
filename.push('-');
|
||||||
|
filename.push(subtitle);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename.length === 0) {
|
||||||
|
filename.push('beestat');
|
||||||
|
}
|
||||||
|
|
||||||
|
return filename.join(' ');
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the credits options.
|
* Get the credits options.
|
||||||
*
|
*
|
||||||
|
@ -61,6 +61,7 @@ if($setting->get('environment') === 'dev' || $setting->get('environment') === 'd
|
|||||||
echo '<script src="/js/component/chart.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/chart.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/chart2.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/chart2.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/chart/runtime_thermostat_summary.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/chart/runtime_thermostat_summary.js"></script>' . PHP_EOL;
|
||||||
|
echo '<script src="/js/component/chart/temperature_profiles.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/header.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/header.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/icon.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/icon.js"></script>' . PHP_EOL;
|
||||||
echo '<script src="/js/component/layout.js"></script>' . PHP_EOL;
|
echo '<script src="/js/component/layout.js"></script>' . PHP_EOL;
|
||||||
|
@ -82,7 +82,7 @@ beestat.layer.home_comparisons.prototype.decorate_ = function(parent) {
|
|||||||
|
|
||||||
cards.push([
|
cards.push([
|
||||||
{
|
{
|
||||||
'card': new beestat.component.card.temperature_profiles(),
|
'card': new beestat.component.card.temperature_profiles(thermostat_group.thermostat_group_id),
|
||||||
'size': 12
|
'size': 12
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
@ -175,6 +175,9 @@ beestat.layer.load.prototype.decorate_ = function(parent) {
|
|||||||
thermostat.ecobee_thermostat_id
|
thermostat.ecobee_thermostat_id
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Set the active temperature unit.
|
||||||
|
beestat.setting('temperature_unit', thermostat.temperature_unit);
|
||||||
|
|
||||||
// Rename series if only one stage is available.
|
// Rename series if only one stage is available.
|
||||||
if (ecobee_thermostat.json_settings.coolStages === 1) {
|
if (ecobee_thermostat.json_settings.coolStages === 1) {
|
||||||
beestat.series.sum_compressor_cool_1.name = 'Cool';
|
beestat.series.sum_compressor_cool_1.name = 'Cool';
|
||||||
|
Loading…
x
Reference in New Issue
Block a user