2022-03-27 15:24:38 +00:00
"use strict" ;
2022-04-03 01:41:58 +00:00
import Emel from 'emel' ;
2022-04-03 01:53:41 +00:00
import forkawesome _emel from './forkawesome_emel.mjs' ;
2022-05-25 01:47:06 +00:00
// import ChartStackedBarSet from './charts/ChartStackedBarSet.mjs';
import Plotly from 'plotly.js-dist' ;
2022-04-02 02:00:56 +00:00
2022-03-27 15:24:38 +00:00
import AbstractUIItem from './AbstractUIItem.mjs' ;
import find _in _obj from '../misc/find_in_obj.mjs' ;
class UIGauge extends AbstractUIItem {
2022-05-25 01:47:06 +00:00
# chart _data = [ ] ;
# chart = null ;
2022-04-02 02:00:56 +00:00
2022-03-27 15:24:38 +00:00
constructor ( el , def ) {
super ( el , def ) ;
2022-04-03 01:41:58 +00:00
this . emel = new Emel ( ) . emel ;
this . el . replaceChildren ( this . emel ( ` h3{?}+div[class="container-gauge"] ` , {
placeholders : [ this . def . name ]
} ) ) ;
2022-05-25 01:47:06 +00:00
this . el _gauge = this . el . querySelector ( ".container-gauge" ) ;
2022-04-02 02:00:56 +00:00
2022-03-27 15:24:38 +00:00
}
2022-05-25 01:47:06 +00:00
render ( ) {
// Refuse to render an empty chart
if ( this . # chart _data . length === 0 ) return ;
const data = {
x : [ ] , // Labels
y : [ ] , // Data numbers
2022-05-25 02:14:18 +00:00
type : "bar" ,
marker : {
color : "hsla(178, 61%, 59%, 0.75)" // --tech-d, taken from the CSS
}
2022-05-25 01:47:06 +00:00
} ;
for ( const itemdef of this . # chart _data ) {
let label _this = itemdef . label ;
for ( let i = 2 ; data . x . includes ( label _this ) ; i ++ )
label _this = ` ${ itemdef . label } ( ${ i } ) ` ;
data . x . push ( label _this ) ;
data . y . push ( itemdef . data _item ) ;
}
2022-05-25 02:14:18 +00:00
data . text = data . y . map ( value => this . def . gauge _unit ? ` ${ value } ${ this . def . gauge _unit } ` : value ) ;
2022-05-25 01:47:06 +00:00
console . log ( ` def ${ this . def . name } plotly definition ` , data ) ;
2022-05-25 02:14:18 +00:00
const layout = {
// title: this.def.name // We already have a title, but if we didn't we'd add one like this
paper _bgcolor : window . getComputedStyle ( this . el _gauge , null ) . backgroundColor ,
plot _bgcolor : "transparent" ,
modebar : { bgcolor : "transparent" } ,
font : {
color : "white"
} ,
margin : {
2022-05-25 02:18:27 +00:00
b : 80 , l : 40 , r : 40 , t : 40
2022-05-25 02:14:18 +00:00
}
}
2022-05-25 01:47:06 +00:00
if ( this . # chart === null ) {
console . log ( ` def ${ this . def . name } plotly NEW ` ) ;
2022-05-25 02:14:18 +00:00
this . # chart = Plotly . newPlot (
this . el _gauge ,
[ data ] , layout ,
{ responsive : true }
) ;
2022-05-25 01:47:06 +00:00
}
else {
console . log ( ` def ${ this . def . name } plotly REACT ` ) ;
2022-05-25 02:14:18 +00:00
this . # chart = Plotly . react (
this . el _gauge ,
[ data ] , layout ,
{ responsive : true }
) ;
2022-05-25 01:47:06 +00:00
}
2022-03-27 15:24:38 +00:00
}
2022-04-02 02:00:56 +00:00
# _ _insert _item ( label , data _item ) {
const comparer = new Intl . Collator ( navigator . language ) ;
2022-05-25 01:47:06 +00:00
for ( let i in this . # chart _data ) {
2022-04-02 02:00:56 +00:00
const comp _name = comparer . compare (
label . toLowerCase ( ) ,
2022-05-25 01:47:06 +00:00
this . # chart _data [ i ] . label . toLowerCase ( )
2022-04-02 02:00:56 +00:00
) ;
if ( comp _name < 0 ) { // Insert immediately before this index
2022-05-25 01:47:06 +00:00
this . # chart _data . splice ( i , 0 , {
label ,
data _item
} ) ;
2022-04-02 02:00:56 +00:00
return ;
}
}
2022-05-25 01:47:06 +00:00
// Didn't manage to find a good sopt, put it on the end
this . # chart _data . push ( { label , data _item } ) ;
2022-04-02 02:00:56 +00:00
}
2022-03-27 15:24:38 +00:00
clear ( ) {
super . clear ( ) ;
2022-05-25 01:47:06 +00:00
this . el _gauge . replaceChildren ( ) ;
this . chart = null ;
this . # chart _data = [ ] ;
2022-03-27 15:24:38 +00:00
}
append ( peer , table ) {
2022-04-02 02:00:56 +00:00
super . append ( peer , table ) ;
2022-03-27 15:24:38 +00:00
2022-05-25 02:18:27 +00:00
let label = peer . name ; //`${peer.name}\n${peer.id.slice(0, 7)}`; // Plotly doesn't support multiline labels :-/
2022-04-02 02:00:56 +00:00
let data _item = null ;
2022-04-03 01:36:26 +00:00
switch ( typeof this . def . content ) {
2022-04-02 02:00:56 +00:00
case "function" :
2022-04-03 01:36:26 +00:00
data _item = this . def . content ( table ) ;
2022-04-02 02:00:56 +00:00
break ;
case "string" :
2022-04-03 01:36:26 +00:00
data _item = find _in _obj ( table , this . def . content ) ;
2022-04-02 02:00:56 +00:00
break ;
default :
2022-04-03 01:36:26 +00:00
console . warn ( ` Warning: Unknown UIGauge content type ' ${ typeof this . def . content } ' for def with name ' ${ this . def . name } '. ` ) ;
2022-04-03 01:53:41 +00:00
this . el . querySelector ( ".container-gauge" ) . replaceChildren (
this . emel ( ` div[class="message-error"]> ${ forkawesome _emel ( "exclamation-circle" ) } +{Oops! An error occurred while rendering this chart. Check the developer tools for more information.} ` )
)
2022-04-02 02:00:56 +00:00
return false ;
}
if ( data _item == null ) {
console . warn ( ` Warning: Got null when evaluating value for UIGauge. ` ) ;
return false ;
}
2022-04-04 02:12:47 +00:00
if ( typeof data _item !== "number" ) {
console . warn ( ` Warning: Got ' ${ typeof daata _item } ' when evaluating value for UIGuage. ` ) ;
return false ;
}
2022-04-02 02:00:56 +00:00
2022-04-03 01:36:26 +00:00
this . # _ _insert _item ( label , data _item ) ;
2022-04-04 02:12:47 +00:00
console . log ( ` def ${ this . def . name } | chart_data ` , this . # chart _data ) ;
2022-05-25 01:47:06 +00:00
this . render ( ) ;
2022-03-27 15:24:38 +00:00
}
}
export default UIGauge ;
2022-04-02 02:00:56 +00:00
/ *
2022-03-27 15:24:38 +00:00
var options = {
series : [ {
name : 'Net Profit' ,
data : [ 44 , 55 , 57 , 56 , 61 , 58 , 63 , 60 , 66 ]
} , {
name : 'Revenue' ,
data : [ 76 , 85 , 101 , 98 , 87 , 105 , 91 , 114 , 94 ]
} , {
name : 'Free Cash Flow' ,
data : [ 35 , 41 , 36 , 26 , 45 , 48 , 52 , 53 , 41 ]
} ] ,
chart : {
type : 'bar' ,
height : 350
} ,
plotOptions : {
bar : {
horizontal : false ,
columnWidth : '55%' ,
endingShape : 'rounded'
} ,
} ,
dataLabels : {
enabled : false
} ,
stroke : {
show : true ,
width : 2 ,
colors : [ 'transparent' ]
} ,
xaxis : {
categories : [ 'Feb' , 'Mar' , 'Apr' , 'May' , 'Jun' , 'Jul' , 'Aug' , 'Sep' , 'Oct' ] ,
} ,
yaxis : {
title : {
text : '$ (thousands)'
}
} ,
fill : {
opacity : 1
} ,
tooltip : {
y : {
formatter : function ( val ) {
return "$ " + val + " thousands"
}
}
}
} ;
var chart = new ApexCharts ( document . querySelector ( "#chart" ) , options ) ;
chart . render ( ) ;
2022-04-02 02:00:56 +00:00
* /