This guy fixed the missing graphs, in firefox, with this fork
Then lately something else happened ( In Ha / Firefox ) who knows, or maybe it was just my setup, that got f…up
Any ways i replaced the .js with this, with some modifications
console.info(
`%c WEATHER-CHART-CARD \n%c Version 0.2`,
'color: orange; font-weight: bold; background: black',
'color: white; font-weight: bold; background: dimgray',
);
const locale = {
da: {
tempHi: "Temperatur",
tempLo: "Temperatur nat",
precip: "Nedbør",
uPress: "hPa",
uSpeed: "m/s",
uPrecip: "mm",
uVisib: "km",
cardinalDirections: [
'N', 'N-NØ', 'NØ', 'Ø-NØ', 'Ø', 'Ø-SØ', 'SØ', 'S-SØ',
'S', 'S-SV', 'SV', 'V-SV', 'V', 'V-NV', 'NV', 'N-NV', 'N'
]
},
en: {
tempHi: "Temperature",
tempLo: "Temperature night",
precip: "Precipitations",
uPress: "hPa",
uSpeed: "km/h",
uPrecip: "mm",
uVisib: "mi",
cardinalDirections: [
'N', 'N-NE', 'NE', 'E-NE', 'E', 'E-SE', 'SE', 'S-SE',
'S', 'S-SW', 'SW', 'W-SW', 'W', 'W-NW', 'NW', 'N-NW', 'N'
]
},
fr: {
tempHi: "Température",
tempLo: "Température nuit",
precip: "Précipitations",
uPress: "hPa",
uSpeed: "m/s",
uPrecip: "mm",
uVisib: "km",
cardinalDirections: [
'N', 'N-NE', 'NE', 'E-NE', 'E', 'E-SE', 'SE', 'S-SE',
'S', 'S-SO', 'SO', 'O-SO', 'O', 'O-NO', 'NO', 'N-NO', 'N'
]
},
nl: {
tempHi: "Max temperatuur",
tempLo: "Min temperatuur",
precip: "Neerslag",
uPress: "hPa",
uSpeed: "km/u",
uPrecip: "mm",
uVisib: "km",
cardinalDirections: [
'N', 'N-NO', 'NO', 'O-NO', 'O', 'O-ZO', 'ZO', 'Z-ZO',
'Z', 'Z-ZW', 'ZW', 'W-ZW', 'W', 'W-NW', 'NW', 'N-NW', 'N'
]
},
ru: {
tempHi: "Температура",
tempLo: "Температура ночью",
precip: "Осадки",
uPress: "гПа",
uSpeed: "м/с",
uPrecip: "мм",
uVisib: "км",
cardinalDirections: [
'С', 'С-СВ', 'СВ', 'В-СВ', 'В', 'В-ЮВ', 'ЮВ', 'Ю-ЮВ',
'Ю', 'Ю-ЮЗ', 'ЮЗ', 'З-ЮЗ', 'З', 'З-СЗ', 'СЗ', 'С-СЗ', 'С'
]
}
};
class WeatherChart extends Polymer.Element {
static get template() {
return Polymer.html`
<style>
ha-icon {
color: var(--paper-item-icon-color);
}
.card {
padding: 16px;
}
</style>
<ha-card header="[[title]]">
<div class="card">
<ha-chart-base data="[[ChartData]]" options="[[ChartOptions]]" ></ha-chart-base>
</div>
</ha-card>
`;
}
static get properties() {
return {
config: Object,
mode: String,
weatherObj: {
type: Object,
observer: 'dataChanged',
},
};
}
setConfig(config) {
this.config = config;
this.title = config.title;
this.weatherObj = config.weather;
this.mode = config.mode;
if (!config.weather) {
throw new Error('Please define "weather" entity in the card config');
}
}
set hass(hass) {
this._hass = hass;
this.lang = this.config.locale in hass.states ? hass.states[this.config.locale] : this._hass.language;
this.weatherObj = this.config.weather in hass.states ? hass.states[this.config.weather] : null;
this.forecast = this.weatherObj.attributes.forecast.slice(0,9);
}
dataChanged() {
this.drawChart();
}
ll(str) {
if (locale[this.lang] === undefined)
return locale.en[str];
return locale[this.lang][str];
}
drawChart() {
var data = this.weatherObj.attributes.forecast.slice(0,9);
var tempUnit = this._hass.config.unit_system.temperature;
var lengthUnit = this._hass.config.unit_system.length;
var precipUnit = lengthUnit === 'km' ? this.ll('uPrecip') : 'in';
var mode = this.mode;
var i;
if (!this.weatherObj.attributes.forecast) {
return [];
}
var dateTime = [];
var tempHigh = [];
var tempLow = [];
var precip = [];
for (i = 0; i < data.length; i++) {
var d = data[i];
dateTime.push(new Date(d.datetime));
tempHigh.push(d.temperature);
tempLow.push(d.templow);
precip.push(d.precipitation);
}
var style = getComputedStyle(document.body);
var textColor = style.getPropertyValue('--primary-text-color');
var dividerColor = style.getPropertyValue('--divider-color');
const chartData = {
labels: dateTime,
datasets: [
{
label: this.ll('tempHi'),
type: 'line',
data: tempHigh,
yAxisID: 'yTempAxis',
borderColor: 'red',
backgroundColor: 'orange',
borderWidth: 2.0,
lineTension: 0.4,
pointRadius: 1.0,
pointHitRadius: 5.0,
fill: false,
tooltip: {
callbacks: {
label: function(context) {
var label = context.dataset.label || '';
return label += ': ' + context.parsed.y + tempUnit;
}
}
}
},
{
label: this.ll('tempLo'),
type: 'line',
data: tempLow,
yAxisID: 'yTempAxis',
borderColor: 'green',
backgroundColor: 'purple',
borderWidth: 2.0,
lineTension: 0.4,
pointRadius: 0.0,
pointHitRadius: 5.0,
fill: false,
tooltip: {
callbacks: {
label: function(context) {
var label = context.dataset.label || '';
return label += ': ' + context.parsed.y + tempUnit;
}
}
}
},
{
label: this.ll('precip'),
type: 'bar',
data: precip,
yAxisID: 'yPrecipAxis',
borderColor: 'skyblue',
backgroundColor: 'steelblue',
maxBarThickness: 15,
barThickness: 8,
tooltip: {
callbacks: {
label: function(context) {
var label = context.dataset.label || '';
return label += ': ' + context.parsed.y + precipUnit;
}
}
}
},
]
}
const chartOptions = {
animation: {
duration: 300,
easing: 'linear',
onComplete: function (animation) {
var chartInstance = animation.chart,
ctx = chartInstance.ctx;
ctx.fillStyle = textColor;
var fontSize = 10;
var fontStyle = 'normal';
var fontFamily = 'Roboto';
ctx.font = fontStyle + ' ' + fontSize + 'px ' + fontFamily;
ctx.textAlign = 'center';
ctx.textBaseline = 'bottom';
var meta = chartInstance.getDatasetMeta(2);
meta.data.forEach(function (bar, index) {
var data = (Math.round((chartInstance.data.datasets[2].data[index]) * 10) / 10).toFixed(1);
if (data > 0)
ctx.fillText(data, bar.x, bar.y - 5);
});
},
},
legend: {
display: false,
},
scales: {
xAxes: {
type: 'time',
adapters: {
date: {
locale: this._hass.locale,
},
},
// display: true,
ticks: {
display: false,
},
grid: {
display: false,
},
},
xDateAxis: {
type: 'time',
position: 'top',
adapters: {
date: {
locale: this._hass.locale,
},
},
grid: {
display: true,
drawBorder: false,
color: dividerColor,
},
ticks: {
display: true,
source: 'labels',
autoSkip: true,
color: textColor,
maxRotation: 0,
callback: function(value, index, values) {
var date = new Date(0);
date.setUTCMilliseconds(values[index].value);
if (mode == 'hourly') {
return date.toLocaleTimeString(locale, { hour: 'numeric' });
}
return date.toLocaleDateString(locale, { weekday: 'short' });;
},
},
},
yTempAxis: {
position: 'left',
adapters: {
date: {
locale: this._hass.locale,
},
},
grid: {
display: true,
drawBorder: false,
color: dividerColor,
borderDash: [1,3],
},
ticks: {
display: true,
color: textColor,
callback: function(value, index, values) {
return value + 'º';
},
},
afterFit: function(scaleInstance) {
scaleInstance.width = 37;
},
},
yPrecipAxis: {
display: false,
position: 'right',
suggestedMax: 20,
adapters: {
date: {
locale: this._hass.locale,
},
},
grid: {
display: false,
drawBorder: false,
color: dividerColor,
},
ticks: {
display: false,
min: 0,
color: textColor,
},
afterFit: function(scaleInstance) {
scaleInstance.width = 15;
},
},
},
plugins: {
tooltip: {
callbacks: {
title: function(context) {
return new Date(context[0].label).toLocaleDateString(locale, {
month: 'long',
day: 'numeric',
weekday: 'long',
// hour: 'numeric',
// minute: 'numeric',
});
}
}
}
},
}
this.ChartData = chartData;
this.ChartOptions = chartOptions;
/* this.ChartType = chartType;*/
}
_fire(type, detail, options) {
const node = this.shadowRoot;
options = options || {};
detail = (detail === null || detail === undefined) ? {} : detail;
const e = new Event(type, {
bubbles: options.bubbles === undefined ? true : options.bubbles,
cancelable: Boolean(options.cancelable),
composed: options.composed === undefined ? true : options.composed
});
e.detail = detail;
node.dispatchEvent(e);
return e;
}
}
customElements.define('weather-chart-card', WeatherChart);
Not sure which fork this came from, but i just change the name ( added -CARD ) as he had renamed it ( Weather-Chart ) only
PS: Might have been copied from one of Marius , modded-forks
PS_2: i was actually sitting today and “fiddling” with this .js, trying to remove the “bubbles”, to get a nice smooth graph … didn’t turned out well :(, but i might give it a try another day
PS_3 i added above fork through HACS, and then replaced the .js ( just for the record )