mirror of https://github.com/grafana/grafana
parent
a702603e7b
commit
0e10fdb415
@ -0,0 +1,189 @@ |
|||||||
|
import _ from 'lodash'; |
||||||
|
import React from 'react'; |
||||||
|
|
||||||
|
const LEGEND_STATS = ['min', 'max', 'avg', 'current', 'total']; |
||||||
|
|
||||||
|
export interface GraphLegendProps { |
||||||
|
seriesList: any[]; |
||||||
|
hiddenSeries: any; |
||||||
|
values?: boolean; |
||||||
|
min?: boolean; |
||||||
|
max?: boolean; |
||||||
|
avg?: boolean; |
||||||
|
current?: boolean; |
||||||
|
total?: boolean; |
||||||
|
alignAsTable?: boolean; |
||||||
|
rightSide?: boolean; |
||||||
|
sideWidth?: number; |
||||||
|
sort?: 'min' | 'max' | 'avg' | 'current' | 'total'; |
||||||
|
sortDesc?: boolean; |
||||||
|
className?: string; |
||||||
|
} |
||||||
|
|
||||||
|
export interface GraphLegendState {} |
||||||
|
|
||||||
|
export class GraphLegend extends React.PureComponent<GraphLegendProps, GraphLegendState> { |
||||||
|
sortLegend() { |
||||||
|
let seriesList = this.props.seriesList || []; |
||||||
|
if (this.props.sort) { |
||||||
|
seriesList = _.sortBy(seriesList, function(series) { |
||||||
|
let sort = series.stats[this.props.sort]; |
||||||
|
if (sort === null) { |
||||||
|
sort = -Infinity; |
||||||
|
} |
||||||
|
return sort; |
||||||
|
}); |
||||||
|
if (this.props.sortDesc) { |
||||||
|
seriesList = seriesList.reverse(); |
||||||
|
} |
||||||
|
} |
||||||
|
return seriesList; |
||||||
|
} |
||||||
|
|
||||||
|
render() { |
||||||
|
const { className = '', hiddenSeries } = this.props; |
||||||
|
const { values, min, max, avg, current, total } = this.props; |
||||||
|
const seriesValuesProps = { values, min, max, avg, current, total }; |
||||||
|
const seriesList = this.sortLegend(); |
||||||
|
return ( |
||||||
|
<div className={`${className} graph-legend`}> |
||||||
|
<div className={`graph-legend-content ${this.props.alignAsTable ? 'graph-legend-table' : ''}`}> |
||||||
|
<div className="graph-legend-scroll"> |
||||||
|
{this.props.alignAsTable ? ( |
||||||
|
<LegendTable seriesList={seriesList} hiddenSeries={hiddenSeries} {...seriesValuesProps} /> |
||||||
|
) : ( |
||||||
|
seriesList.map((series, i) => ( |
||||||
|
<LegendSeriesItem |
||||||
|
key={series.id} |
||||||
|
series={series} |
||||||
|
index={i} |
||||||
|
hiddenSeries={hiddenSeries} |
||||||
|
{...seriesValuesProps} |
||||||
|
/> |
||||||
|
)) |
||||||
|
)} |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
interface LegendTableProps { |
||||||
|
seriesList: any[]; |
||||||
|
hiddenSeries: any; |
||||||
|
values?: boolean; |
||||||
|
min?: boolean; |
||||||
|
max?: boolean; |
||||||
|
avg?: boolean; |
||||||
|
current?: boolean; |
||||||
|
total?: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
class LegendTable extends React.PureComponent<LegendTableProps> { |
||||||
|
render() { |
||||||
|
const seriesList = this.props.seriesList; |
||||||
|
const { values, min, max, avg, current, total } = this.props; |
||||||
|
const seriesValuesProps = { values, min, max, avg, current, total }; |
||||||
|
const headerStyle: React.CSSProperties = { |
||||||
|
textAlign: 'left', |
||||||
|
}; |
||||||
|
|
||||||
|
return ( |
||||||
|
<tbody> |
||||||
|
<tr> |
||||||
|
<th colSpan={2} style={headerStyle} /> |
||||||
|
{LEGEND_STATS.map( |
||||||
|
statName => seriesValuesProps[statName] && <LegendTableHeader key={statName} statName={statName} /> |
||||||
|
)} |
||||||
|
</tr> |
||||||
|
{seriesList.map((series, i) => ( |
||||||
|
<LegendSeriesItem |
||||||
|
key={series.id} |
||||||
|
series={series} |
||||||
|
index={i} |
||||||
|
hiddenSeries={this.props.hiddenSeries} |
||||||
|
{...seriesValuesProps} |
||||||
|
/> |
||||||
|
))} |
||||||
|
</tbody> |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
interface LegendTableHeaderProps { |
||||||
|
statName: string; |
||||||
|
sortDesc?: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
function LegendTableHeader(props: LegendTableHeaderProps) { |
||||||
|
return ( |
||||||
|
<th className="pointer" data-stat={props.statName}> |
||||||
|
{props.statName} |
||||||
|
<span className={props.sortDesc ? 'fa fa-caret-down' : 'fa fa-caret-up'} /> |
||||||
|
</th> |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
interface LegendSeriesItemProps { |
||||||
|
series: any; |
||||||
|
index: number; |
||||||
|
hiddenSeries: any; |
||||||
|
values?: boolean; |
||||||
|
min?: boolean; |
||||||
|
max?: boolean; |
||||||
|
avg?: boolean; |
||||||
|
current?: boolean; |
||||||
|
total?: boolean; |
||||||
|
} |
||||||
|
|
||||||
|
class LegendSeriesItem extends React.Component<LegendSeriesItemProps> { |
||||||
|
constructor(props) { |
||||||
|
super(props); |
||||||
|
} |
||||||
|
|
||||||
|
render() { |
||||||
|
const { series, index, hiddenSeries } = this.props; |
||||||
|
const seriesOptionClasses = getOptionSeriesCSSClasses(series, hiddenSeries); |
||||||
|
const valueItems = this.props.values ? renderLegendValues(this.props, series) : []; |
||||||
|
return ( |
||||||
|
<div className={`graph-legend-series ${seriesOptionClasses}`} data-series-index={index}> |
||||||
|
<div className="graph-legend-icon"> |
||||||
|
<i className="fa fa-minus pointer" style={{ color: series.color }} /> |
||||||
|
</div> |
||||||
|
<a className="graph-legend-alias pointer" title={series.aliasEscaped}> |
||||||
|
{series.aliasEscaped} |
||||||
|
</a> |
||||||
|
{valueItems} |
||||||
|
</div> |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function LegendValue(props) { |
||||||
|
const value = props.value; |
||||||
|
const valueName = props.valueName; |
||||||
|
return <div className={`graph-legend-value ${valueName}`}>{value}</div>; |
||||||
|
} |
||||||
|
|
||||||
|
function renderLegendValues(props: LegendSeriesItemProps, series) { |
||||||
|
const legendValueItems = []; |
||||||
|
for (const valueName of LEGEND_STATS) { |
||||||
|
if (props[valueName]) { |
||||||
|
const valueFormatted = series.formatValue(series.stats[valueName]); |
||||||
|
legendValueItems.push(<LegendValue key={valueName} valueName={valueName} value={valueFormatted} />); |
||||||
|
} |
||||||
|
} |
||||||
|
return legendValueItems; |
||||||
|
} |
||||||
|
|
||||||
|
function getOptionSeriesCSSClasses(series, hiddenSeries) { |
||||||
|
const classes = []; |
||||||
|
if (series.yaxis === 2) { |
||||||
|
classes.push('graph-legend-series--right-y'); |
||||||
|
} |
||||||
|
if (hiddenSeries[series.alias]) { |
||||||
|
classes.push('graph-legend-series-hidden'); |
||||||
|
} |
||||||
|
return classes.join(' '); |
||||||
|
} |
||||||
Loading…
Reference in new issue