@ -31,7 +31,8 @@
////////////////////////////////////////////////////
// DEFAULT INTERFACE BUILDING
var myHouse = PROJECTS . items [ myNumber ] ;
var myHouseXname = PROJECTS . items [ myNumber ] . xname ;
cl ( myHouseXname ) ;
document . getElementById ( "h1_title" ) . innerHTML = h1 _title ;
document . getElementById ( "subtitle" ) . innerHTML = subtitle ;
@ -262,7 +263,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var family = document . getElementById ( "PDFamSensor" ) . value ;
var type = document . getElementById ( "PDParameter" ) . value ;
// Building API query
var apiUrl = "parallel/daily?family=" + family + "&type=" + type + "&day=" + day ;
var apiUrl = "parallel/daily?hus=" + myHouseXname + "& family=" + family + "&type=" + type + "&day=" + day ;
makeApiRequest ( formId , apiUrl , myid , myTitle , family , type , day ) ;
break ;
@ -276,7 +277,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var myTitle = document . getElementById ( "PWTitle" ) . value ;
var type = document . getElementById ( "PWParameter" ) . value ;
// BUILDING API query
var apiUrl = "parallel/weekly?family=" + family + "&type=" + type + "&year=" + year + "&week=" + week ;
var apiUrl = "parallel/weekly?hus=" + myHouseXname + "& family=" + family + "&type=" + type + "&year=" + year + "&week=" + week ;
makeApiRequest ( formId , apiUrl , myid , myTitle , family , type , year , week ) ;
break ;
@ -290,7 +291,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var myTitle = document . getElementById ( "PMTitle" ) . value ;
var type = document . getElementById ( "PMParameter" ) . value ;
// BUILDING API query
var apiUrl = "parallel/monthly?family=" + family + "&type=" + type + "&year=" + year + "&month=" + month ;
var apiUrl = "parallel/monthly?hus=" + myHouseXname + "& family=" + family + "&type=" + type + "&year=" + year + "&month=" + month ;
makeApiRequest ( formId , apiUrl , myid , myTitle , family , type , year , month )
break ;
@ -301,7 +302,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var myTitle = document . getElementById ( "PYTitle" ) . value ;
var type = document . getElementById ( "PYParameter" ) . value ;
// BUILDING API query
var apiUrl = "parallel/yearly?family=" + family + "&type=" + type + "&year=" + year ;
var apiUrl = "parallel/yearly?hus=" + myHouseXname + "& family=" + family + "&type=" + type + "&year=" + year ;
makeApiRequest ( formId , apiUrl , myid , myTitle , family , type , year )
break ;
}
@ -321,7 +322,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var sensor = document . getElementById ( "GWSensor" ) . value ;
var type = document . getElementById ( "GWParameter" ) . value ;
// BUILDING API query
var apiUrl = "grid/weekly?sensor=" + sensor + "&type=" + type + "&year=" + year + "&week=" + week ;
var apiUrl = "grid/weekly?hus=" + myHouseXname + "& sensor=" + sensor + "&type=" + type + "&year=" + year + "&week=" + week ;
makeApiRequest ( formId , apiUrl , myid , myTitle , sensor , type , inDate ) ;
break ;
@ -334,7 +335,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var sensor = document . getElementById ( "GMSensor" ) . value ;
var type = document . getElementById ( "GMParameter" ) . value ;
// BUILDING API query
var apiUrl = "grid/monthly?sensor=" + sensor + "&type=" + type + "&year=" + year + "&month=" + month ;
var apiUrl = "grid/monthly?hus=" + myHouseXname + "& sensor=" + sensor + "&type=" + type + "&year=" + year + "&month=" + month ;
makeApiRequest ( formId , apiUrl , myid , myTitle , sensor , type , year , month ) ;
break ;
@ -344,7 +345,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var year = document . getElementById ( "GYYear" ) . value ;
var sensor = document . getElementById ( "GYSensor" ) . value ;
var type = document . getElementById ( "GYParameter" ) . value ;
var apiUrl = "grid/monthly? sensor=" + sensor + "&type=" + type + "&year=" + year ;
var apiUrl = "grid/yearly?hus=" + myHouseXname + "& sensor=" + sensor + "&type=" + type + "&year=" + year ;
makeApiRequest ( formId , apiUrl , myid , myTitle , sensor , type , year ) ;
break ;
@ -369,7 +370,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var family = document . getElementById ( "HWFamSensor" ) . value ;
var type = document . getElementById ( "HYParameter" ) . value ;
// BUILDING API query
var apiUrl = "horizon/monthly? family=" + family + "&type=" + type + "&day=" + day ;
var apiUrl = "horizon/daily?hus=" + myHouseXname + "& family=" + family + "&type=" + type + "&day=" + day ;
makeApiRequest ( formId , apiUrl , myid , myTitle , family , type , year ) ;
break ;
@ -385,7 +386,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var family = document . getElementById ( "HWFamSensor" ) . value ;
var type = document . getElementById ( "HWParameter" ) . value ;
// BUILDING API query
var apiUrl = "horizon/monthly? family=" + family + "&type=" + type + "&year=" + year + "&week=" + week ;
var apiUrl = "horizon/weekly?hus=" + myHouseXname + "& family=" + family + "&type=" + type + "&year=" + year + "&week=" + week ;
makeApiRequest ( formId , apiUrl , myid , myTitle , family , type , year , week ) ;
break ;
@ -398,7 +399,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var family = document . getElementById ( "HMFamSensor" ) . value ;
var type = document . getElementById ( "HMParameter" ) . value ;
// BUILDING API query
var apiUrl = "horizon/monthly?family=" + family + "&type=" + type + "&year=" + year + "&month=" + month ;
var apiUrl = "horizon/monthly?hus=" + myHouseXname + "& family=" + family + "&type=" + type + "&year=" + year + "&month=" + month ;
makeApiRequest ( formId , apiUrl , myid , myTitle , family , type , year , month ) ;
@ -410,7 +411,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
var family = document . getElementById ( "HYFamSensor" ) . value ;
var type = document . getElementById ( "HYParameter" ) . value ;
// BUILDING API query
var apiUrl = "horizon/monthly? family=" + family + "&type=" + type + "&year=" + year ;
var apiUrl = "horizon/yearly?hus=" + myHouseXname + "& family=" + family + "&type=" + type + "&year=" + year ;
makeApiRequest ( formId , apiUrl , myid , myTitle , family , type , year ) ;
@ -440,6 +441,7 @@ document.getElementById("HDParameter").innerHTML = listParametersOptions;
// Parallel
function do _parallel ( myid , myxs , mycolumns , inMyTitle ) {
cl ( myxs ) ;
c3 . generate ( {
bindto : myid ,
data : {
@ -609,6 +611,13 @@ function do_grid_weekly(myid, startingDate, data) {
// GRID MONTHLY d3 diagram
function getMonth ( monthNumber ) {
const date = d3 . timeParse ( "%m" ) ( monthNumber ) ;
const monthName = d3 . timeFormat ( "%B" ) ( date ) ;
return monthName ;
}
function do _grid _monthly ( myid , month , year , data , apiUrl ) {
const margin = { top : 60 , right : 20 , bottom : 20 , left : 20 } ;
const cellSize = 35 ;
@ -643,8 +652,8 @@ function do_grid_monthly(myid, month, year, data, apiUrl) {
. enter ( ) . append ( "rect" )
. attr ( "width" , cellSize )
. attr ( "height" , cellSize )
. attr ( "x" , ( d , i ) => ( i % 7 ) * cellSize )
. attr ( "y" , ( d , i ) => Math . floor ( i / 7 ) * cellSize )
. attr ( "x" , ( d , i ) => ( ( i + getDayOffset ( month , year ) ) % 7 ) * cellSize )
. attr ( "y" , ( d , i ) => Math . floor ( ( i + getDayOffset ( month , year ) ) / 7 ) * cellSize )
. attr ( "fill" , d => colorScale ( d ) ) // Apply the color scale to data values
. on ( "mouseover" , function ( d ) {
// Show the tooltip on hover
@ -666,13 +675,13 @@ function do_grid_monthly(myid, month, year, data, apiUrl) {
. data ( numericData )
. enter ( ) . append ( "text" )
. attr ( "class" , "day-number" )
. attr ( "x" , ( d , i ) => ( i % 7 ) * cellSize + cellSize / 2 )
. attr ( "y" , ( d , i ) => Math . floor ( i / 7 ) * cellSize + cellSize / 2 )
. attr ( "x" , ( d , i ) => ( ( i + getDayOffset ( month , year ) ) % 7 ) * cellSize + cellSize / 2 )
. attr ( "y" , ( d , i ) => Math . floor ( ( i + getDayOffset ( month , year ) ) / 7 ) * cellSize + cellSize / 2 )
. attr ( "text-anchor" , "middle" )
. attr ( "alignment-baseline" , "middle" )
. text ( ( d , i ) => i + 1 ) ;
const weekDays = [ "Sun" , " Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" ] ;
const weekDays = [ "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" , "Sun " ] ;
svg . selectAll ( ".weekday" )
. data ( weekDays )
. enter ( ) . append ( "text" )
@ -682,22 +691,142 @@ function do_grid_monthly(myid, month, year, data, apiUrl) {
. attr ( "text-anchor" , "middle" )
. text ( ( d ) => d ) ;
const firstDayOfMonth = new Date ( year , month - 1 , 1 ) ;
const dayOffset = ( firstDayOfMonth . getDay ( ) + 6 ) % 7 ; // Calculate the day offset for the first day of the month
const monthName = getMonth ( month ) ;
svg . append ( "text" )
. attr ( "class" , "year-label" )
. attr ( "x" , width )
. attr ( "y" , - 30 )
. attr ( "text-anchor" , "end" )
. text ( "December " + year ) ;
}
. text ( monthName + ", " + year ) ;
function getDayOffset ( month , year ) {
const firstDayOfMonth = new Date ( year , month - 1 , 1 ) ;
const dayOffset = ( firstDayOfMonth . getDay ( ) + 6 ) % 7 ; // Calculate the day offset for the first day of the month
return dayOffset ;
}
function getMonth ( month ) {
const months = [
"January" , "February" , "March" , "April" , "May" , "June" ,
"July" , "August" , "September" , "October" , "November" , "December"
] ;
return months [ month - 1 ] ;
}
}
function do _grid _monthly _one ( myid , month , year , data , apiUrl ) {
const margin = { top : 60 , right : 20 , bottom : 20 , left : 20 } ;
const cellSize = 35 ;
const width = cellSize * 7 ; // Number of columns (days)
const height = cellSize * 7 ; // Number of rows (days)
// Create a tooltip element
const tooltip = d3 . select ( "body" )
. append ( "div" )
. attr ( "class" , "tooltip" )
. style ( "opacity" , 0 )
. style ( "position" , "absolute" ) ; // Set tooltip position to absolute
const svg = d3 . select ( ` # ${ myid } ` )
. append ( "svg" )
. attr ( "class" , "heatmap" )
. attr ( "width" , width + margin . left + margin . right )
. attr ( "height" , height + margin . top + margin . bottom )
. append ( "g" )
. attr ( "transform" , ` translate( ${ margin . left } , ${ margin . top } ) ` ) ;
// Convert data values to numbers
const numericData = data . map ( value => parseFloat ( value ) ) ;
// Create a color scale based on numeric data
const colorScale = d3 . scaleLinear ( )
. domain ( [ d3 . min ( numericData ) , d3 . max ( numericData ) ] )
. range ( [ "#0571b0" , "#ca0020" ] ) ; // Replace with your desired color range
const rect = svg . selectAll ( "rect" )
. data ( numericData )
. enter ( ) . append ( "rect" )
. attr ( "width" , cellSize )
. attr ( "height" , cellSize )
. attr ( "x" , ( d , i ) => ( ( i + getDayOffset ( month , year ) ) % 7 ) * cellSize )
. attr ( "y" , ( d , i ) => Math . floor ( ( i + getDayOffset ( month , year ) ) / 7 ) * cellSize )
. attr ( "fill" , d => colorScale ( d ) ) // Apply the color scale to data values
. on ( "mouseover" , function ( d ) {
// Show the tooltip on hover
const [ x , y ] = d3 . mouse ( this ) ;
const pageX = x + window . scrollX ; // Adjust for horizontal scroll
const pageY = y + window . scrollY ; // Adjust for vertical scroll
tooltip
. style ( "left" , ( d3 . event . pageX + 10 ) + "px" )
. style ( "top" , ( d3 . event . pageY - 10 ) + "px" )
. style ( "background-color" , "#c3c3c3" )
. style ( "opacity" , 1 )
. html ( "Value: " + d . toFixed ( 2 ) ) ;
} )
. on ( "mouseout" , ( ) => {
tooltip . style ( "opacity" , 0 ) ;
} ) ;
svg . selectAll ( ".day-number" )
. data ( numericData )
. enter ( ) . append ( "text" )
. attr ( "class" , "day-number" )
. attr ( "x" , ( d , i ) => ( ( i + getDayOffset ( month , year ) ) % 7 ) * cellSize + cellSize / 2 )
. attr ( "y" , ( d , i ) => Math . floor ( ( i + getDayOffset ( month , year ) ) / 7 ) * cellSize + cellSize / 2 )
. attr ( "text-anchor" , "middle" )
. attr ( "alignment-baseline" , "middle" )
. text ( ( d , i ) => i + 1 ) ;
const weekDays = [ "Mon" , "Tue" , "Wed" , "Thu" , "Fri" , "Sat" , "Sun" ] ;
svg . selectAll ( ".weekday" )
. data ( weekDays )
. enter ( ) . append ( "text" )
. attr ( "class" , "weekday" )
. attr ( "x" , ( d , i ) => i * cellSize + cellSize / 2 )
. attr ( "y" , - 10 )
. attr ( "text-anchor" , "middle" )
. text ( ( d ) => d ) ;
const firstDayOfMonth = new Date ( year , month - 1 , 1 ) ;
const dayOffset = ( firstDayOfMonth . getDay ( ) + 6 ) % 7 ; // Calculate the day offset for the first day of the month
const monthName = getMonth ( month ) ;
svg . append ( "text" )
. attr ( "class" , "year-label" )
. attr ( "x" , width )
. attr ( "y" , - 30 )
. attr ( "text-anchor" , "end" )
. text ( monthName + ", " + year ) ;
function getDayOffset ( month , year ) {
const firstDayOfMonth = new Date ( year , month - 1 , 1 ) ;
const dayOffset = ( firstDayOfMonth . getDay ( ) + 6 ) % 7 ; // Calculate the day offset for the first day of the month
return dayOffset ;
}
function getMonth ( month ) {
const months = [
"January" , "February" , "March" , "April" , "May" , "June" ,
"July" , "August" , "September" , "October" , "November" , "December"
] ;
return months [ month - 1 ] ;
}
}
//--------------------------------
// GRID YEARLY d3 diagram
function do _grid _yearly ( myid , year , myData ) {
// Remove the existing SVG if it exists
d3 . select ( ` # ${ myid } svg ` ) . remove ( ) ;
@ -800,7 +929,196 @@ function do_grid_yearly(myid, year, myData) {
// Calendar Days
for ( let day = 1 ; day <= month . days ; day ++ ) {
// Get the value for the current day
const value = myData [ day - 1 ] ; // Subtract 1 because array index starts from 0
const value = myData [ month . days * i + day - 1 ] ; // Calculate index based on month and day
// Calculate the color based on the value
const color = d3 . interpolateViridis ( colorScale ( value ) ) ;
// Calculate the position of the current day
const dayRow = Math . floor ( ( day - 1 ) / 7 ) ;
const dayCol = ( day - 1 ) % 7 ;
function getDayOffset ( month , year ) {
const firstDayOfMonth = new Date ( year , month - 1 , 1 ) ;
const dayOffset = ( firstDayOfMonth . getDay ( ) + 6 ) % 7 ; // Calculate the day offset for the first day of the month
return dayOffset ;
}
}
// Weekday labels
const weekdays = [ 'Mon' , 'Tue' , 'Wed' , 'Thu' , 'Fri' , 'Sat' , 'Sun' ] ;
// Loop through each month and create the calendar heatmap
for ( let i = 0 ; i < months . length ; i ++ ) {
const month = months [ i ] ;
// Calculate row and column positions
const row = Math . floor ( i / columns ) ;
const col = i % columns ;
// Starting positions for months
const x = col * cellWidth + borderWidth ;
const y = row * cellHeight + borderWidth ;
// Weekday labels
for ( let w = 0 ; w < weekdays . length ; w ++ ) {
const weekdayLabel = svg . append ( "text" )
. attr ( "x" , x + ( w * ( cellWidth / 7 ) ) + cellWidth / 14 )
. attr ( "y" , y + 55 ) // Increased vertical position
. attr ( "font-size" , "12" )
. attr ( "text-anchor" , "middle" )
. text ( weekdays [ w ] ) ;
}
// Calendar Days
for ( let day = 1 ; day <= month . days ; day ++ ) {
// Get the value for the current day
const value = myData [ month . days * i + day - 1 ] ; // Calculate index based on month and day
// Calculate the color based on the value
const color = d3 . interpolateViridis ( colorScale ( value ) ) ;
// Calculate the position of the current day
const dayRow = Math . floor ( ( day - 1 ) / 7 ) ;
const dayCol = ( day - 1 ) % 7 ;
// Create a rectangle for each day
svg . append ( "rect" )
. attr ( "x" , x + ( dayCol * ( cellWidth / 7 ) ) )
. attr ( "y" , y + 60 + ( dayRow * ( cellHeight / 6 ) ) ) // Increased vertical position
. attr ( "width" , cellWidth / 7 )
. attr ( "height" , cellHeight / 6 )
. attr ( "fill" , color )
. attr ( "stroke" , "#ffffff" ) // white border
. attr ( "class" , "day" )
. on ( "mouseover" , ( ) => {
const dayValue = myData [ month . days * i + day - 1 ] ; // Calculate index based on month and day
// Call the handleMouseover function with the correct value
handleMouseover ( day , dayValue ) ;
} )
. on ( "mouseout" , ( ) => {
tooltip . style ( "opacity" , 0 ) ;
} )
. append ( "text" ) // Add text to display the day number
. attr ( "x" , x + ( dayCol * ( cellWidth / 7 ) ) + cellWidth / 14 )
. attr ( "y" , y + 85 + ( dayRow * ( cellHeight / 6 ) ) ) // Increased vertical position
. attr ( "font-size" , "12" )
. attr ( "text-anchor" , "middle" )
. text ( day ) ;
}
}
}
}
function do _grid _yearlyXX ( myid , year , myData ) {
// Remove the existing SVG if it exists
d3 . select ( ` # ${ myid } svg ` ) . remove ( ) ;
// For demonstration purposes, let's create a simple SVG rectangle
const svg = d3 . select ( ` # ${ myid } ` ) . append ( "svg" )
. attr ( "width" , 800 )
. attr ( "height" , 650 ) ; // Increased height for a taller diagram
// Append the 'months' group inside the SVG
const monthsGroup = svg . append ( "g" )
. attr ( "id" , "months" ) ;
const months = [
{ name : 'January' , days : 31 } ,
{ name : 'February' , days : 28 } ,
{ name : 'March' , days : 31 } ,
{ name : 'April' , days : 30 } ,
{ name : 'May' , days : 31 } ,
{ name : 'June' , days : 30 } ,
{ name : 'July' , days : 31 } ,
{ name : 'August' , days : 31 } ,
{ name : 'September' , days : 30 } ,
{ name : 'October' , days : 31 } ,
{ name : 'November' , days : 30 } ,
{ name : 'December' , days : 31 } ,
] ;
// Number of columns and rows
const columns = 4 ;
const rows = 5 ; // Increased rows for more vertical space
// Calculate cell width and height
const cellWidth = 660 / columns ;
const cellHeight = ( 800 / rows ) ; // Increased cell height to 40px per month
// Border width
const borderWidth = 1 ;
// Calculate min and max values for the color scale
const minValue = Math . min ( ... myData ) ;
const maxValue = Math . max ( ... myData ) ;
const valueRange = maxValue - minValue ;
// Create a color scale based on the min, max, and range of values
const colorScale = d3 . scaleLinear ( )
. domain ( [ minValue , maxValue ] )
. range ( [ 0 , 1 ] ) ;
// Create a group for month labels
const monthLabelsGroup = svg . append ( "g" )
. attr ( "id" , "month-labels" ) ;
// Function to handle mouseover event and display tooltip
function handleMouseover ( day , value ) {
// Show the tooltip on hover
tooltip
. style ( "left" , ( d3 . event . pageX + 10 ) + "px" )
. style ( "top" , ( d3 . event . pageY - 10 ) + "px" )
. style ( "background-color" , "#c3c3c3" )
. style ( "opacity" , 1 )
. html ( ` Value: ${ value } ` ) ;
}
// Create a tooltip element
const tooltip = d3 . select ( "body" )
. append ( "div" )
. attr ( "class" , "tooltip" )
. style ( "opacity" , 0 ) ;
// Loop through each month and create the calendar heatmap
for ( let i = 0 ; i < months . length ; i ++ ) {
const month = months [ i ] ;
// Calculate row and column positions
const row = Math . floor ( i / columns ) ;
const col = i % columns ;
// Starting positions for months
const x = col * cellWidth + borderWidth ;
const y = row * cellHeight + borderWidth ;
// Month Label
const monthLabel = monthLabelsGroup . append ( "text" )
. attr ( "x" , x + cellWidth / 2 )
. attr ( "y" , y + 20 ) // Increased vertical position
. attr ( "font-size" , "18" )
. attr ( "text-anchor" , "middle" )
. text ( ` ${ month . name } ${ year } ` ) ;
// Create a border around the month
const border = svg . append ( "rect" )
. attr ( "x" , x )
. attr ( "y" , y + 30 ) // Increased vertical position
. attr ( "width" , cellWidth - 2 * borderWidth )
. attr ( "height" , cellHeight - 2 * borderWidth - 30 ) // Adjusted height to avoid overlap
. attr ( "fill" , "none" )
. attr ( "stroke" , "#ffffff" ) // Border
. attr ( "stroke-width" , borderWidth ) ;
// Calendar Days
for ( let day = 1 ; day <= month . days ; day ++ ) {
// Get the value for the current day
const value = myData [ month . days * i + day - 1 ] ; // Calculate index based on month and day
// Calculate the color based on the value
const color = d3 . interpolateViridis ( colorScale ( value ) ) ;
@ -819,7 +1137,7 @@ function do_grid_yearly(myid, year, myData) {
. attr ( "stroke" , "#ffffff" ) // white border
. attr ( "class" , "day" )
. on ( "mouseover" , ( ) => {
const dayValue = myData [ day - 1 ] ; // Subtract 1 because array index starts from 0
const dayValue = myData [ month . days * i + day - 1 ] ; // Calculate index based on month and day
// Call the handleMouseover function with the correct value
handleMouseover ( day , dayValue ) ;
} )
@ -827,12 +1145,100 @@ function do_grid_yearly(myid, year, myData) {
tooltip . style ( "opacity" , 0 ) ;
} ) ;
}
// Weekday labels
const weekdays = [ 'Mon' , 'Tue' , 'Wed' , 'Thu' , 'Fri' , 'Sat' , 'Sun' ] ;
// Loop through each month and create the calendar heatmap
for ( let i = 0 ; i < months . length ; i ++ ) {
const month = months [ i ] ;
// Calculate row and column positions
const row = Math . floor ( i / columns ) ;
const col = i % columns ;
// Starting positions for months
const x = col * cellWidth + borderWidth ;
const y = row * cellHeight + borderWidth ;
// Month Label
const monthLabel = monthLabelsGroup . append ( "text" )
. attr ( "x" , x + cellWidth / 2 )
. attr ( "y" , y + 20 ) // Increased vertical position
. attr ( "font-size" , "18" )
. attr ( "text-anchor" , "middle" )
. text ( ` ${ month . name } ${ year } ` ) ;
// Weekday labels
for ( let w = 0 ; w < weekdays . length ; w ++ ) {
const weekdayLabel = svg . append ( "text" )
. attr ( "x" , x + ( w * ( cellWidth / 7 ) ) + cellWidth / 14 )
. attr ( "y" , y + 55 ) // Increased vertical position
. attr ( "font-size" , "12" )
. attr ( "text-anchor" , "middle" )
. text ( weekdays [ w ] ) ;
}
// Create a border around the month
const border = svg . append ( "rect" )
. attr ( "x" , x )
. attr ( "y" , y + 30 ) // Increased vertical position
. attr ( "width" , cellWidth - 2 * borderWidth )
. attr ( "height" , cellHeight - 2 * borderWidth - 30 ) // Adjusted height to avoid overlap
. attr ( "fill" , "none" )
. attr ( "stroke" , "#ffffff" ) // Border
. attr ( "stroke-width" , borderWidth ) ;
// Calendar Days
for ( let day = 1 ; day <= month . days ; day ++ ) {
// Get the value for the current day
const value = myData [ month . days * i + day - 1 ] ; // Calculate index based on month and day
// Calculate the color based on the value
const color = d3 . interpolateViridis ( colorScale ( value ) ) ;
// Calculate the position of the current day
const dayRow = Math . floor ( ( day - 1 ) / 7 ) ;
const dayCol = ( day - 1 ) % 7 ;
// Create a rectangle for each day
svg . append ( "rect" )
. attr ( "x" , x + ( dayCol * ( cellWidth / 7 ) ) )
. attr ( "y" , y + 60 + ( dayRow * ( cellHeight / 6 ) ) ) // Increased vertical position
. attr ( "width" , cellWidth / 7 )
. attr ( "height" , cellHeight / 6 )
. attr ( "fill" , color )
. attr ( "stroke" , "#ffffff" ) // white border
. attr ( "class" , "day" )
. on ( "mouseover" , ( ) => {
const dayValue = myData [ month . days * i + day - 1 ] ; // Calculate index based on month and day
// Call the handleMouseover function with the correct value
handleMouseover ( day , dayValue ) ;
} )
. on ( "mouseout" , ( ) => {
tooltip . style ( "opacity" , 0 ) ;
} )
. append ( "text" ) // Add text to display the day number
. attr ( "x" , x + ( dayCol * ( cellWidth / 7 ) ) + cellWidth / 14 )
. attr ( "y" , y + 85 + ( dayRow * ( cellHeight / 6 ) ) ) // Increased vertical position
. attr ( "font-size" , "12" )
. attr ( "text-anchor" , "middle" )
. text ( day ) ;
}
}
}
}
//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ -841,8 +1247,6 @@ function do_grid_yearly(myid, year, myData) {
//--------------------------------
// HORIZON d3 diagram
function do _horizon _row ( data , myid , title , myDates ) {
var horizonChart = d3 . horizonChart ( )
. height ( 50 )
@ -923,7 +1327,7 @@ function getApiUrls() {
document . querySelectorAll ( '#col-left div' ) . forEach ( function ( element , index ) {
var apiUrl = element . getAttribute ( 'apiurl' ) ;
var id = element . id ;
var order = apiUrlsCenter . length ;
var order = apiUrlsLeft . length ;
if ( apiUrl === 'txt' ) {
var clone = element . cloneNode ( true ) ;
clone . querySelectorAll ( 'span' ) . forEach ( function ( span ) {
@ -962,7 +1366,7 @@ function getApiUrls() {
var apiUrl = element . getAttribute ( 'apiurl' ) ;
var id = element . id ;
var text = element . innerHTML . trim ( ) ; // Assuming the text is the innerHTML of the element
var order = apiUrlsCenter . length ;
var order = apiUrlsRight . length ;
if ( apiUrl === 'txt' ) {
var clone = element . cloneNode ( true ) ;
clone . querySelectorAll ( 'span' ) . forEach ( function ( span ) {
@ -980,7 +1384,10 @@ function getApiUrls() {
// Similar modifications for #col-center and #col-right
var result = {
"name" : myHouse . xname ,
// FIXME : boardName will be entered in the save board form
"boardName" : "my Form name test" ,
"name" : boardName ,
"hus" : myParam ,
"description" : myHouse . subtitle ,
"col-left" : apiUrlsLeft ,
"col-center" : apiUrlsCenter ,
@ -1407,9 +1814,42 @@ var firstOpen = true;
// > makeApiRequiest
// > submit nuttons listener
//function to prepare the tha API request upon a board JSON
function loadBoards ( myJSON ) {
myJSON = '' ;
function getFormId ( api _url ) { return api _url [ 0 ] . toUpperCase ( ) + api _url . split ( "/" ) [ 1 ] [ 0 ] . toUpperCase ( ) ; } ;
function loadBoards ( ) {
//JAUME
// Test JSON Board:
myJSON = { "name" : "Charlie" , "hus" : "Charlie" , "description" : "Lorem <a href=\"#\">Ipsum is</a> simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen." , "col-left" : [ { "order" : 0 , "id" : "P-txt-728265" , "text" : "Here a text" , "api_url" : null } , { "order" : 1 , "id" : "parallel-8001586" , "text" : "" , "api_url" : "parallel/monthly?hus=Charlie&family=MP1_1&type=celsius&year=2020&month=1" } ] , "col-center" : [ { "order" : 0 , "id" : "G-txt-956767" , "text" : "Here a text" , "api_url" : null } , { "order" : 1 , "id" : "grid-190619" , "text" : "" , "api_url" : "grid/monthly?hus=Charlie&sensor=Temp_MP1_1_Pos1&type=celsius&year=2023&month=01" } ] , "col-right" : [ { "order" : 0 , "id" : "H-txt-518613" , "text" : "Here a text" , "api_url" : null } , { "order" : 1 , "id" : "horizon-986338" , "text" : "" , "api_url" : "horizon/daily?hus=Charlie&family=MP1_1&type=celsius&day=2023-04-12" } ] } ;
var cols = [ "col-left" , "col-center" , "col-right" ] ;
cols . forEach ( col => {
if ( col . length > 0 ) {
myJSON [ col ] . forEach ( element => {
// Get necessary variables:
var myColumn = col ;
var myid = element . id ;
var myTitle = element . text ;
// Create DIV
createMyDiv ( myid , myColumn , myTitle ) ;
// Check if is TXT or Diagram:
if ( element . text == "" ) {
cl ( element [ "api_url" ] ) ;
var apiUrl = element [ "api_url" ] ;
var formId = getFormId ( apiUrl ) ;
//createParallel(myid, formId, formData);
makeApiRequest ( formId , apiUrl , myid ) ;
} else {
var formId = "TXT" ;
createTXT ( myid , element . text ) ;
}
} ) ;
}
} ) ;
//Prepara the variables:
// formId, apiUrl, myid, myTitle, ...args
@ -1530,7 +1970,7 @@ function makeApiRequest(formId, apiUrl, myid, myTitle, ...args) {
do _grid _weekly ( myid , inDate , data [ 2 ] ) ;
break ;
case "GM" :
do _grid _monthly ( myid , week , month , data [ 2 ] , apiUrl ) ;
do _grid _monthly ( myid , month , year , data [ 2 ] , apiUrl ) ;
break ;
case "GY" :
do _grid _yearly ( myid , year , data [ 2 ] ) ;
@ -1541,25 +1981,13 @@ function makeApiRequest(formId, apiUrl, myid, myTitle, ...args) {
case "HY" :
data . sensor _names . forEach ( element => {
var dataRow = data [ element ]
var element1 = [ 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.70 , 31.70 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.80 , 31.70 , 31.70 , 31.70 , 31.70 , 31.70 , 31.70 ] ;
do _horizon _row ( dataRow , "#" + myid , element , data . days ) ;
} ) ;
break ;
}
} )
. catch ( ( error ) => {
console . error ( "Fetch error:" , error ) ;
} ) ;
}
async function createHiddenVauesDiv ( myid , dataName , data ) {
// final childs for each data var
var mainDiv = document . getElementById ( myid ) ;
const childDiv = document . createElement ( "div" ) ;
const lastValueElement = document . createElement ( "div" ) ;
lastValueElement . id = dataName ;
var data2 = JSON . stringify ( data ) ;
lastValueElement . innerHTML = data2 ;
}