mirror of
				https://github.com/beestat/app.git
				synced 2025-11-03 18:37:01 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			509 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			509 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/**
 | 
						|
 * A chart. Mostly just a wrapper for the Highcharts stuff so the defaults
 | 
						|
 * don't have to be set every single time.
 | 
						|
 */
 | 
						|
beestat.component.chart = function() {
 | 
						|
  var self = this;
 | 
						|
 | 
						|
  this.addEventListener('render', function() {
 | 
						|
    self.chart_.reflow();
 | 
						|
  });
 | 
						|
 | 
						|
  beestat.component.apply(this, arguments);
 | 
						|
};
 | 
						|
beestat.extend(beestat.component.chart, beestat.component);
 | 
						|
 | 
						|
beestat.component.chart.prototype.rerender_on_breakpoint_ = false;
 | 
						|
 | 
						|
/**
 | 
						|
 * Decorate. Calls all the option getters and renders the chart.
 | 
						|
 *
 | 
						|
 * @param {rocket.Elements} parent
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.decorate_ = function(parent) {
 | 
						|
  var options = {};
 | 
						|
 | 
						|
  options.credits = this.get_options_credits_();
 | 
						|
  options.exporting = this.get_options_exporting_();
 | 
						|
  options.chart = this.get_options_chart_();
 | 
						|
  options.title = this.get_options_title_();
 | 
						|
  options.subtitle = this.get_options_subtitle_();
 | 
						|
  options.legend = this.get_options_legend_();
 | 
						|
  options.plotOptions = this.get_options_plotOptions_();
 | 
						|
  options.xAxis = this.get_options_xAxis_();
 | 
						|
  options.yAxis = this.get_options_yAxis_();
 | 
						|
  options.series = this.get_options_series_();
 | 
						|
  options.tooltip = this.get_options_tooltip_();
 | 
						|
 | 
						|
  options.chart.renderTo = parent[0];
 | 
						|
 | 
						|
  this.chart_ = Highcharts.chart(options);
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Reset the chart zoom level all the way out.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.reset_zoom = function() {
 | 
						|
  this.chart_.zoomOut();
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Export the chart to a PNG.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.export = function() {
 | 
						|
  this.chart_.exportChartLocal();
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the legend options.
 | 
						|
 *
 | 
						|
 * @return {object} The legend options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_legend_ = function() {
 | 
						|
  return {
 | 
						|
    'itemStyle': {
 | 
						|
      'color': '#ecf0f1',
 | 
						|
      'font-weight': '500'
 | 
						|
    },
 | 
						|
    'itemHoverStyle': {
 | 
						|
      'color': '#bdc3c7'
 | 
						|
    },
 | 
						|
    'itemHiddenStyle': {
 | 
						|
      'color': '#7f8c8d'
 | 
						|
    },
 | 
						|
    'labelFormatter': this.get_options_legend_labelFormatter_(),
 | 
						|
 | 
						|
 | 
						|
    // 'layout': 'vertical',
 | 
						|
    // 'align': 'right',
 | 
						|
    // 'verticalAlign': 'top'
 | 
						|
 | 
						|
    // 'maxHeight': 1000, // To prevent the navigation thing
 | 
						|
    // 'floating': true,
 | 
						|
    // 'verticalAlign': 'top',
 | 
						|
    // 'y': 50,
 | 
						|
    // 'borderWidth': 1
 | 
						|
    //
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the legend labelFormatter options.
 | 
						|
 *
 | 
						|
 * @return {Function} The legend labelFormatter options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_legend_labelFormatter_ = function() {
 | 
						|
  return function() {
 | 
						|
    return beestat.series[this.name].name;
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the plotOptions.
 | 
						|
 *
 | 
						|
 * @return {object} The plotOptions.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_plotOptions_ = function() {
 | 
						|
  return {
 | 
						|
    'series': {
 | 
						|
      'animation': false,
 | 
						|
      'marker': {
 | 
						|
        'enabled': false
 | 
						|
      },
 | 
						|
      'states': {
 | 
						|
        'hover': {
 | 
						|
          'enabled': false
 | 
						|
        },
 | 
						|
        'inactive': {
 | 
						|
          'opacity': 1
 | 
						|
        }
 | 
						|
      },
 | 
						|
      'connectNulls': this.get_options_plotOptions_series_connectNulls_()
 | 
						|
    },
 | 
						|
    'column': {
 | 
						|
      'pointPadding': 0,
 | 
						|
      'borderWidth': 0,
 | 
						|
      'stacking': 'normal',
 | 
						|
      'dataLabels': {
 | 
						|
        'enabled': false
 | 
						|
      }
 | 
						|
    }
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get whether or not to connect nulls.
 | 
						|
 *
 | 
						|
 * @return {boolean} Whether or not to connect nulls.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_plotOptions_series_connectNulls_ = function() {
 | 
						|
  return false;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the title options.
 | 
						|
 *
 | 
						|
 * @return {object} The title options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_title_ = function() {
 | 
						|
  return {
 | 
						|
    'text': null
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the subtitle options
 | 
						|
 *
 | 
						|
 * @return {object} The subtitle options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_subtitle_ = function() {
 | 
						|
  return {
 | 
						|
    'text': null
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the chart options.
 | 
						|
 *
 | 
						|
 * @return {object} The chart options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_chart_ = function() {
 | 
						|
  return {
 | 
						|
    'style': {
 | 
						|
      'fontFamily': 'Montserrat'
 | 
						|
    },
 | 
						|
    'spacing': [
 | 
						|
      beestat.style.size.gutter,
 | 
						|
      0,
 | 
						|
      0,
 | 
						|
      0
 | 
						|
    ],
 | 
						|
    'zoomType': this.get_options_chart_zoomType_(),
 | 
						|
    'panning': true,
 | 
						|
    'panKey': 'ctrl',
 | 
						|
    'backgroundColor': beestat.style.color.bluegray.base,
 | 
						|
    'resetZoomButton': {
 | 
						|
      'theme': {
 | 
						|
        'display': 'none'
 | 
						|
      }
 | 
						|
    },
 | 
						|
    'height': this.get_options_chart_height_(),
 | 
						|
    'events': this.get_options_chart_events_()
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the events list for the chart.
 | 
						|
 *
 | 
						|
 * @return {number} The events list for the chart.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_chart_events_ = function() {
 | 
						|
  return null;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the height of the chart.
 | 
						|
 *
 | 
						|
 * @return {number} The height of the chart.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_chart_height_ = function() {
 | 
						|
  return null;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the zoomType option. Return null for no zoom.
 | 
						|
 *
 | 
						|
 * @return {string} The zoom type.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_chart_zoomType_ = function() {
 | 
						|
  return 'x';
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the export options.
 | 
						|
 *
 | 
						|
 * @return {object} The export options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_exporting_ = function() {
 | 
						|
  return {
 | 
						|
    'enabled': false,
 | 
						|
    'sourceWidth': 980,
 | 
						|
    'scale': 1,
 | 
						|
    'filename': this.get_options_exporting_filename_(),
 | 
						|
    'chartOptions': {
 | 
						|
      'credits': {
 | 
						|
        'text': 'beestat.io'
 | 
						|
      },
 | 
						|
      'title': {
 | 
						|
        'align': 'left',
 | 
						|
        'text': this.get_options_exporting_chartOptions_title_text_(),
 | 
						|
        'margin': beestat.style.size.gutter,
 | 
						|
        'style': {
 | 
						|
          'color': '#fff',
 | 
						|
          'font-weight': beestat.style.font_weight.bold,
 | 
						|
          'font-size': beestat.style.font_size.large
 | 
						|
        }
 | 
						|
      },
 | 
						|
      'subtitle': {
 | 
						|
        'align': 'left',
 | 
						|
        'text': this.get_options_exporting_chartOptions_subtitle_text_(),
 | 
						|
        'style': {
 | 
						|
          'color': '#fff',
 | 
						|
          'font-weight': beestat.style.font_weight.light,
 | 
						|
          'font-size': beestat.style.font_size.normal
 | 
						|
        }
 | 
						|
      },
 | 
						|
      'chart': {
 | 
						|
        'style': {
 | 
						|
          'fontFamily': 'Montserrat, Helvetica, Sans-Serif'
 | 
						|
        },
 | 
						|
        'spacing': [
 | 
						|
          beestat.style.size.gutter,
 | 
						|
          beestat.style.size.gutter,
 | 
						|
          beestat.style.size.gutter,
 | 
						|
          beestat.style.size.gutter
 | 
						|
        ],
 | 
						|
        'events': this.get_options_exporting_chart_events_()
 | 
						|
      }
 | 
						|
    }
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the exported chart title.
 | 
						|
 *
 | 
						|
 * @return {string} The exported chart title.
 | 
						|
 */
 | 
						|
beestat.component.chart.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.chart.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.chart.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 events list for the chart on export.
 | 
						|
 *
 | 
						|
 * @return {string} The events list for the chart on export.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_exporting_chart_events_ = function() {
 | 
						|
  return null;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the credits options.
 | 
						|
 *
 | 
						|
 * @return {boolean} The credits options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_credits_ = function() {
 | 
						|
  return false;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the xAxis options.
 | 
						|
 *
 | 
						|
 * @return {object} The xAxis options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_xAxis_ = function() {
 | 
						|
  return {
 | 
						|
    'categories': this.data_.x,
 | 
						|
    'lineColor': beestat.style.color.bluegray.light,
 | 
						|
    'tickLength': 0,
 | 
						|
    'labels': {
 | 
						|
      'style': {
 | 
						|
        'color': beestat.style.color.gray.base
 | 
						|
      },
 | 
						|
      'formatter': this.get_options_xAxis_labels_formatter_()
 | 
						|
    }
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the xAxis label formatter options. Needs to be overridden.
 | 
						|
 *
 | 
						|
 * @return {object} The xAxis label formatter options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_xAxis_labels_formatter_ = function() {
 | 
						|
  return null;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the yAxis label formatter options. Needs to be overridden.
 | 
						|
 *
 | 
						|
 * @return {object} The yAxis label formatter options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_yAxis_ = function() {
 | 
						|
  return null;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the series options. Needs to be overridden.
 | 
						|
 *
 | 
						|
 * @return {object} The series options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_series_ = function() {
 | 
						|
  return null;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the tooltip options.
 | 
						|
 *
 | 
						|
 * @return {object} The tooltip options.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_tooltip_ = function() {
 | 
						|
  return {
 | 
						|
    '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': this.get_options_tooltip_positioner_(),
 | 
						|
    'formatter': this.get_options_tooltip_formatter_()
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the tooltip formatter. Needs to be overridden.
 | 
						|
 *
 | 
						|
 * @return {Function} The tooltip formatter.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_tooltip_formatter_ = function() {
 | 
						|
  return null;
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the tooltip positioner. Makes sure the tooltip is positioned nicely.
 | 
						|
 *
 | 
						|
 * @return {Function} The tooltip positioner.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.get_options_tooltip_positioner_ = function() {
 | 
						|
  var self = this;
 | 
						|
  return function(tooltip_width, tooltip_height, point) {
 | 
						|
    var plot_width = self.chart_.plotWidth;
 | 
						|
 | 
						|
    var fits_on_left = (point.plotX - tooltip_width) > 0;
 | 
						|
    var fits_on_right = (point.plotX + tooltip_width) < plot_width;
 | 
						|
 | 
						|
    var x;
 | 
						|
    var y = 60;
 | 
						|
    if (fits_on_left === true) {
 | 
						|
      x = point.plotX - tooltip_width + self.chart_.plotLeft;
 | 
						|
    } else if (fits_on_right === true) {
 | 
						|
      x = point.plotX + self.chart_.plotLeft;
 | 
						|
    } else {
 | 
						|
      x = self.chart_.plotLeft;
 | 
						|
    }
 | 
						|
 | 
						|
    return {
 | 
						|
      'x': x,
 | 
						|
      'y': y
 | 
						|
    };
 | 
						|
  };
 | 
						|
};
 | 
						|
 | 
						|
/**
 | 
						|
 * Get the HTML needed to render a tooltip.
 | 
						|
 *
 | 
						|
 * @param {string} title The tooltip title.
 | 
						|
 * @param {array} sections Data inside the tooltip.
 | 
						|
 *
 | 
						|
 * @return {string} The tooltip HTML.
 | 
						|
 */
 | 
						|
beestat.component.chart.prototype.tooltip_formatter_helper_ = function(title, sections) {
 | 
						|
  var tooltip = $.createElement('div')
 | 
						|
    .style({
 | 
						|
      'background-color': beestat.style.color.bluegray.dark,
 | 
						|
      'padding': beestat.style.size.gutter / 2
 | 
						|
    });
 | 
						|
 | 
						|
  var title_div = $.createElement('div')
 | 
						|
    .style({
 | 
						|
      'font-weight': beestat.style.font_weight.bold,
 | 
						|
      'font-size': beestat.style.font_size.large,
 | 
						|
      'margin-bottom': beestat.style.size.gutter / 4,
 | 
						|
      'color': beestat.style.color.gray.light
 | 
						|
    })
 | 
						|
    .innerText(title);
 | 
						|
  tooltip.appendChild(title_div);
 | 
						|
 | 
						|
  var table = $.createElement('table')
 | 
						|
    .setAttribute({
 | 
						|
      'cellpadding': '0',
 | 
						|
      'cellspacing': '0'
 | 
						|
    });
 | 
						|
  tooltip.appendChild(table);
 | 
						|
 | 
						|
  sections.forEach(function(section, i) {
 | 
						|
    if (section.length > 0) {
 | 
						|
      section.forEach(function(item) {
 | 
						|
        var tr = $.createElement('tr').style('color', item.color);
 | 
						|
        table.appendChild(tr);
 | 
						|
 | 
						|
        var td_label = $.createElement('td')
 | 
						|
          .style({
 | 
						|
            'font-weight': beestat.style.font_weight.bold
 | 
						|
          })
 | 
						|
          .innerText(item.label);
 | 
						|
        tr.appendChild(td_label);
 | 
						|
 | 
						|
        var td_value = $.createElement('td').innerText(item.value)
 | 
						|
          .style({
 | 
						|
            'padding-left': beestat.style.size.gutter / 4
 | 
						|
          });
 | 
						|
        tr.appendChild(td_value);
 | 
						|
      });
 | 
						|
 | 
						|
      if (i < sections.length) {
 | 
						|
        var spacer_tr = $.createElement('tr');
 | 
						|
        table.appendChild(spacer_tr);
 | 
						|
 | 
						|
        var spacer_td = $.createElement('td')
 | 
						|
          .style('padding-bottom', beestat.style.size.gutter / 4);
 | 
						|
        spacer_tr.appendChild(spacer_td);
 | 
						|
      }
 | 
						|
    }
 | 
						|
  });
 | 
						|
 | 
						|
  return tooltip[0].outerHTML;
 | 
						|
};
 |