graph legend: refactor
This commit is contained in:
@@ -5,7 +5,6 @@ import EmptyListCTA from './components/EmptyListCTA/EmptyListCTA';
|
||||
import { SearchResult } from './components/search/SearchResult';
|
||||
import { TagFilter } from './components/TagFilter/TagFilter';
|
||||
import { SideMenu } from './components/sidemenu/SideMenu';
|
||||
import { GraphLegend } from 'app/plugins/panel/graph/Legend';
|
||||
|
||||
export function registerAngularDirectives() {
|
||||
react2AngularDirective('passwordStrength', PasswordStrength, ['password']);
|
||||
@@ -18,5 +17,4 @@ export function registerAngularDirectives() {
|
||||
['onSelect', { watchDepth: 'reference' }],
|
||||
['tagOptions', { watchDepth: 'reference' }],
|
||||
]);
|
||||
react2AngularDirective('graphLegendReact', GraphLegend, ['seriesList', 'className']);
|
||||
}
|
||||
|
||||
@@ -2,30 +2,53 @@ import React from 'react';
|
||||
import { ColorPickerPopover } from './ColorPickerPopover';
|
||||
import { react2AngularDirective } from 'app/core/utils/react2angular';
|
||||
|
||||
export interface Props {
|
||||
series: any;
|
||||
export interface SeriesColorPickerProps {
|
||||
// series: any;
|
||||
color: string;
|
||||
yaxis?: number;
|
||||
onColorChange: (color: string) => void;
|
||||
onToggleAxis?: () => void;
|
||||
}
|
||||
|
||||
export class SeriesColorPicker extends React.PureComponent<SeriesColorPickerProps, any> {
|
||||
render() {
|
||||
return (
|
||||
<div className="graph-legend-popover">
|
||||
{this.props.yaxis && <AxisSelector yaxis={this.props.yaxis} onToggleAxis={this.props.onToggleAxis} />}
|
||||
<ColorPickerPopover color={this.props.color} onColorSelect={this.props.onColorChange} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface AxisSelectorProps {
|
||||
yaxis: number;
|
||||
onToggleAxis: () => void;
|
||||
}
|
||||
|
||||
export class SeriesColorPicker extends React.Component<Props, any> {
|
||||
interface AxisSelectorState {
|
||||
yaxis: number;
|
||||
}
|
||||
|
||||
export class AxisSelector extends React.PureComponent<AxisSelectorProps, AxisSelectorState> {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.onColorChange = this.onColorChange.bind(this);
|
||||
this.state = {
|
||||
yaxis: this.props.yaxis,
|
||||
};
|
||||
this.onToggleAxis = this.onToggleAxis.bind(this);
|
||||
}
|
||||
|
||||
onColorChange(color) {
|
||||
this.props.onColorChange(color);
|
||||
}
|
||||
|
||||
onToggleAxis() {
|
||||
this.setState({
|
||||
yaxis: this.state.yaxis === 2 ? 1 : 2,
|
||||
});
|
||||
this.props.onToggleAxis();
|
||||
}
|
||||
|
||||
renderAxisSelection() {
|
||||
const leftButtonClass = this.props.series.yaxis === 1 ? 'btn-success' : 'btn-inverse';
|
||||
const rightButtonClass = this.props.series.yaxis === 2 ? 'btn-success' : 'btn-inverse';
|
||||
render() {
|
||||
const leftButtonClass = this.state.yaxis === 1 ? 'btn-success' : 'btn-inverse';
|
||||
const rightButtonClass = this.state.yaxis === 2 ? 'btn-success' : 'btn-inverse';
|
||||
|
||||
return (
|
||||
<div className="p-b-1">
|
||||
@@ -39,15 +62,6 @@ export class SeriesColorPicker extends React.Component<Props, any> {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="graph-legend-popover">
|
||||
{this.props.series.yaxis && this.renderAxisSelection()}
|
||||
<ColorPickerPopover color={this.props.series.color} onColorSelect={this.onColorChange} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
react2AngularDirective('seriesColorPicker', SeriesColorPicker, ['series', 'onColorChange', 'onToggleAxis']);
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import Drop from 'tether-drop';
|
||||
import { SeriesColorPicker } from './SeriesColorPicker';
|
||||
|
||||
export interface WithSeriesColorPickerProps {
|
||||
color: string;
|
||||
yaxis?: number;
|
||||
optionalClass?: string;
|
||||
onColorChange: (newColor: string) => void;
|
||||
onToggleAxis?: () => void;
|
||||
}
|
||||
|
||||
export default function withSeriesColorPicker(WrappedComponent) {
|
||||
return class extends React.Component<WithSeriesColorPickerProps, any> {
|
||||
pickerElem: any;
|
||||
colorPickerDrop: any;
|
||||
|
||||
static defaultProps = {
|
||||
optionalClass: '',
|
||||
yaxis: undefined,
|
||||
onToggleAxis: () => {},
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.openColorPicker = this.openColorPicker.bind(this);
|
||||
}
|
||||
|
||||
openColorPicker() {
|
||||
if (this.colorPickerDrop) {
|
||||
this.destroyDrop();
|
||||
}
|
||||
|
||||
const { color, yaxis, onColorChange, onToggleAxis } = this.props;
|
||||
const dropContent = (
|
||||
<SeriesColorPicker color={color} yaxis={yaxis} onColorChange={onColorChange} onToggleAxis={onToggleAxis} />
|
||||
);
|
||||
const dropContentElem = document.createElement('div');
|
||||
ReactDOM.render(dropContent, dropContentElem);
|
||||
|
||||
const drop = new Drop({
|
||||
target: this.pickerElem,
|
||||
content: dropContentElem,
|
||||
position: 'top center',
|
||||
classes: 'drop-popover',
|
||||
openOn: 'hover',
|
||||
hoverCloseDelay: 200,
|
||||
remove: true,
|
||||
tetherOptions: {
|
||||
constraints: [{ to: 'scrollParent', attachment: 'none both' }],
|
||||
},
|
||||
});
|
||||
|
||||
drop.on('close', this.closeColorPicker.bind(this));
|
||||
|
||||
this.colorPickerDrop = drop;
|
||||
this.colorPickerDrop.open();
|
||||
}
|
||||
|
||||
closeColorPicker() {
|
||||
setTimeout(() => {
|
||||
this.destroyDrop();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
destroyDrop() {
|
||||
if (this.colorPickerDrop && this.colorPickerDrop.tether) {
|
||||
this.colorPickerDrop.destroy();
|
||||
this.colorPickerDrop = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { optionalClass, onColorChange, ...wrappedComponentProps } = this.props;
|
||||
return (
|
||||
<div className={optionalClass} ref={e => (this.pickerElem = e)} onClick={this.openColorPicker}>
|
||||
<WrappedComponent {...wrappedComponentProps} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
+29
-186
@@ -1,18 +1,15 @@
|
||||
import _ from 'lodash';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { TimeSeries } from 'app/core/core';
|
||||
import CustomScrollbar from 'app/core/components/CustomScrollbar/CustomScrollbar';
|
||||
import Drop from 'tether-drop';
|
||||
import { ColorPickerPopover } from 'app/core/components/colorpicker/ColorPickerPopover';
|
||||
|
||||
const LEGEND_STATS = ['min', 'max', 'avg', 'current', 'total'];
|
||||
import { LegendItem, LEGEND_STATS } from './LegendSeriesItem';
|
||||
|
||||
interface LegendProps {
|
||||
seriesList: TimeSeries[];
|
||||
optionalClass?: string;
|
||||
onToggleSeries?: (series: TimeSeries, event: Event) => void;
|
||||
onToggleSort?: (sortBy, sortDesc) => void;
|
||||
onToggleAxis?: (series: TimeSeries) => void;
|
||||
onColorChange?: (series: TimeSeries, color: string) => void;
|
||||
}
|
||||
|
||||
@@ -41,24 +38,24 @@ interface LegendSortProps {
|
||||
|
||||
export type GraphLegendProps = LegendProps & LegendDisplayProps & LegendValuesProps & LegendSortProps;
|
||||
|
||||
const defaultGraphLegendProps: Partial<GraphLegendProps> = {
|
||||
values: false,
|
||||
min: false,
|
||||
max: false,
|
||||
avg: false,
|
||||
current: false,
|
||||
total: false,
|
||||
alignAsTable: false,
|
||||
rightSide: false,
|
||||
sort: undefined,
|
||||
sortDesc: false,
|
||||
optionalClass: '',
|
||||
};
|
||||
|
||||
export interface GraphLegendState {}
|
||||
|
||||
export class GraphLegend extends React.PureComponent<GraphLegendProps, GraphLegendState> {
|
||||
static defaultProps = defaultGraphLegendProps;
|
||||
export class GraphLegend extends React.PureComponent<GraphLegendProps> {
|
||||
static defaultProps: Partial<GraphLegendProps> = {
|
||||
values: false,
|
||||
min: false,
|
||||
max: false,
|
||||
avg: false,
|
||||
current: false,
|
||||
total: false,
|
||||
alignAsTable: false,
|
||||
rightSide: false,
|
||||
sort: undefined,
|
||||
sortDesc: false,
|
||||
optionalClass: '',
|
||||
onToggleSeries: () => {},
|
||||
onToggleSort: () => {},
|
||||
onToggleAxis: () => {},
|
||||
onColorChange: () => {},
|
||||
};
|
||||
|
||||
sortLegend() {
|
||||
let seriesList = this.props.seriesList || [];
|
||||
@@ -107,6 +104,7 @@ export class GraphLegend extends React.PureComponent<GraphLegendProps, GraphLege
|
||||
onToggleSeries: (s, e) => this.onToggleSeries(s, e),
|
||||
onToggleSort: (sortBy, sortDesc) => this.props.onToggleSort(sortBy, sortDesc),
|
||||
onColorChange: (series, color) => this.props.onColorChange(series, color),
|
||||
onToggleAxis: series => this.props.onToggleAxis(series),
|
||||
...seriesValuesProps,
|
||||
...sortProps,
|
||||
};
|
||||
@@ -124,7 +122,7 @@ class LegendSeriesList extends React.PureComponent<GraphLegendProps> {
|
||||
const { seriesList, hiddenSeries, values, min, max, avg, current, total } = this.props;
|
||||
const seriesValuesProps = { values, min, max, avg, current, total };
|
||||
return seriesList.map((series, i) => (
|
||||
<LegendSeriesItem
|
||||
<LegendItem
|
||||
key={series.id}
|
||||
series={series}
|
||||
index={i}
|
||||
@@ -132,137 +130,12 @@ class LegendSeriesList extends React.PureComponent<GraphLegendProps> {
|
||||
{...seriesValuesProps}
|
||||
onLabelClick={e => this.props.onToggleSeries(series, e)}
|
||||
onColorChange={color => this.props.onColorChange(series, color)}
|
||||
onToggleAxis={() => this.props.onToggleAxis(series)}
|
||||
/>
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
interface LegendSeriesProps {
|
||||
series: TimeSeries;
|
||||
index: number;
|
||||
onLabelClick?: (event) => void;
|
||||
onColorChange?: (color: string) => void;
|
||||
}
|
||||
|
||||
type LegendSeriesItemProps = LegendSeriesProps & LegendDisplayProps & LegendValuesProps;
|
||||
|
||||
class LegendSeriesItem extends React.PureComponent<LegendSeriesItemProps> {
|
||||
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}>
|
||||
<LegendSeriesLabel
|
||||
label={series.aliasEscaped}
|
||||
color={series.color}
|
||||
onLabelClick={e => this.props.onLabelClick(e)}
|
||||
onColorChange={e => this.props.onColorChange(e)}
|
||||
/>
|
||||
{valueItems}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface LegendSeriesLabelProps {
|
||||
label: string;
|
||||
color: string;
|
||||
onLabelClick?: (event) => void;
|
||||
onColorChange?: (color: string) => void;
|
||||
}
|
||||
|
||||
class LegendSeriesLabel extends React.PureComponent<LegendSeriesLabelProps> {
|
||||
pickerElem: any;
|
||||
colorPickerDrop: any;
|
||||
|
||||
openColorPicker() {
|
||||
if (this.colorPickerDrop) {
|
||||
this.destroyDrop();
|
||||
}
|
||||
|
||||
const dropContent = <ColorPickerPopover color={this.props.color} onColorSelect={this.props.onColorChange} />;
|
||||
const dropContentElem = document.createElement('div');
|
||||
ReactDOM.render(dropContent, dropContentElem);
|
||||
|
||||
const drop = new Drop({
|
||||
target: this.pickerElem,
|
||||
content: dropContentElem,
|
||||
position: 'top center',
|
||||
classes: 'drop-popover',
|
||||
openOn: 'hover',
|
||||
hoverCloseDelay: 200,
|
||||
remove: true,
|
||||
tetherOptions: {
|
||||
constraints: [{ to: 'scrollParent', attachment: 'none both' }],
|
||||
},
|
||||
});
|
||||
|
||||
drop.on('close', this.closeColorPicker.bind(this));
|
||||
|
||||
this.colorPickerDrop = drop;
|
||||
this.colorPickerDrop.open();
|
||||
}
|
||||
|
||||
closeColorPicker() {
|
||||
setTimeout(() => {
|
||||
this.destroyDrop();
|
||||
}, 100);
|
||||
}
|
||||
|
||||
destroyDrop() {
|
||||
if (this.colorPickerDrop && this.colorPickerDrop.tether) {
|
||||
this.colorPickerDrop.destroy();
|
||||
this.colorPickerDrop = null;
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { label, color } = this.props;
|
||||
return [
|
||||
<div
|
||||
key="icon"
|
||||
className="graph-legend-icon"
|
||||
ref={e => (this.pickerElem = e)}
|
||||
onClick={() => this.openColorPicker()}
|
||||
>
|
||||
<i className="fa fa-minus pointer" style={{ color: color }} />
|
||||
</div>,
|
||||
<a className="graph-legend-alias pointer" title={label} key="label" onClick={e => this.props.onLabelClick(e)}>
|
||||
{label}
|
||||
</a>,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
interface LegendValueProps {
|
||||
value: string;
|
||||
valueName: string;
|
||||
asTable?: boolean;
|
||||
}
|
||||
|
||||
function LegendValue(props: LegendValueProps) {
|
||||
const value = props.value;
|
||||
const valueName = props.valueName;
|
||||
if (props.asTable) {
|
||||
return <td className={`graph-legend-value ${valueName}`}>{value}</td>;
|
||||
}
|
||||
return <div className={`graph-legend-value ${valueName}`}>{value}</div>;
|
||||
}
|
||||
|
||||
function renderLegendValues(props: LegendSeriesItemProps, series, asTable = false) {
|
||||
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} asTable={asTable} />
|
||||
);
|
||||
}
|
||||
}
|
||||
return legendValueItems;
|
||||
}
|
||||
|
||||
class LegendTable extends React.PureComponent<Partial<GraphLegendProps>> {
|
||||
onToggleSort(stat) {
|
||||
let sortDesc = this.props.sortDesc;
|
||||
@@ -305,14 +178,16 @@ class LegendTable extends React.PureComponent<Partial<GraphLegendProps>> {
|
||||
)}
|
||||
</tr>
|
||||
{seriesList.map((series, i) => (
|
||||
<LegendSeriesItemAsTable
|
||||
<LegendItem
|
||||
key={series.id}
|
||||
asTable={true}
|
||||
series={series}
|
||||
index={i}
|
||||
hiddenSeries={this.props.hiddenSeries}
|
||||
{...seriesValuesProps}
|
||||
onLabelClick={e => this.props.onToggleSeries(series, e)}
|
||||
onColorChange={color => this.props.onColorChange(series, color)}
|
||||
onToggleAxis={() => this.props.onToggleAxis(series)}
|
||||
{...seriesValuesProps}
|
||||
/>
|
||||
))}
|
||||
</tbody>
|
||||
@@ -329,46 +204,14 @@ interface LegendTableHeaderProps {
|
||||
function LegendTableHeaderItem(props: LegendTableHeaderProps & LegendSortProps) {
|
||||
const { statName, sort, sortDesc } = props;
|
||||
return (
|
||||
<th className="pointer" data-stat={statName} onClick={e => props.onClick(e)}>
|
||||
<th className="pointer" onClick={e => props.onClick(e)}>
|
||||
{statName}
|
||||
{sort === statName && <span className={sortDesc ? 'fa fa-caret-down' : 'fa fa-caret-up'} />}
|
||||
</th>
|
||||
);
|
||||
}
|
||||
|
||||
class LegendSeriesItemAsTable extends React.PureComponent<LegendSeriesItemProps> {
|
||||
render() {
|
||||
const { series, index, hiddenSeries } = this.props;
|
||||
const seriesOptionClasses = getOptionSeriesCSSClasses(series, hiddenSeries);
|
||||
const valueItems = this.props.values ? renderLegendValues(this.props, series, true) : [];
|
||||
return (
|
||||
<tr className={`graph-legend-series ${seriesOptionClasses}`} data-series-index={index}>
|
||||
<td>
|
||||
<LegendSeriesLabel
|
||||
label={series.aliasEscaped}
|
||||
color={series.color}
|
||||
onLabelClick={e => this.props.onLabelClick(e)}
|
||||
onColorChange={e => this.props.onColorChange(e)}
|
||||
/>
|
||||
</td>
|
||||
{valueItems}
|
||||
</tr>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getOptionSeriesCSSClasses(series, hiddenSeries) {
|
||||
const classes = [];
|
||||
if (series.yaxis === 2) {
|
||||
classes.push('graph-legend-series--right-y');
|
||||
}
|
||||
if (hiddenSeries[series.alias] && hiddenSeries[series.alias] === true) {
|
||||
classes.push('graph-legend-series-hidden');
|
||||
}
|
||||
return classes.join(' ');
|
||||
}
|
||||
|
||||
export class Legend extends React.Component<GraphLegendProps, GraphLegendState> {
|
||||
export class Legend extends React.Component<GraphLegendProps> {
|
||||
render() {
|
||||
return (
|
||||
<CustomScrollbar>
|
||||
@@ -0,0 +1,173 @@
|
||||
import React from 'react';
|
||||
import { TimeSeries } from 'app/core/core';
|
||||
import withColorPicker from 'app/core/components/colorpicker/withColorPicker';
|
||||
|
||||
export const LEGEND_STATS = ['min', 'max', 'avg', 'current', 'total'];
|
||||
|
||||
export interface LegendLabelProps {
|
||||
index: number;
|
||||
series: TimeSeries;
|
||||
asTable?: boolean;
|
||||
hiddenSeries?: any;
|
||||
onLabelClick?: (event) => void;
|
||||
onColorChange?: (color: string) => void;
|
||||
onToggleAxis?: () => void;
|
||||
}
|
||||
|
||||
export interface LegendValuesProps {
|
||||
values?: boolean;
|
||||
min?: boolean;
|
||||
max?: boolean;
|
||||
avg?: boolean;
|
||||
current?: boolean;
|
||||
total?: boolean;
|
||||
}
|
||||
|
||||
type LegendItemProps = LegendLabelProps & LegendValuesProps;
|
||||
|
||||
export class LegendItem extends React.PureComponent<LegendItemProps> {
|
||||
static defaultProps = {
|
||||
asTable: false,
|
||||
hiddenSeries: undefined,
|
||||
onLabelClick: () => {},
|
||||
onColorChange: () => {},
|
||||
onToggleAxis: () => {},
|
||||
};
|
||||
|
||||
render() {
|
||||
const { series, hiddenSeries, asTable } = this.props;
|
||||
const { aliasEscaped, color, yaxis } = this.props.series;
|
||||
const seriesOptionClasses = getOptionSeriesCSSClasses(series, hiddenSeries);
|
||||
const valueItems = this.props.values ? renderLegendValues(this.props, series, asTable) : [];
|
||||
const seriesLabel = (
|
||||
<LegendSeriesLabel
|
||||
label={aliasEscaped}
|
||||
color={color}
|
||||
yaxis={yaxis}
|
||||
onLabelClick={this.props.onLabelClick}
|
||||
onColorChange={this.props.onColorChange}
|
||||
onToggleAxis={this.props.onToggleAxis}
|
||||
/>
|
||||
);
|
||||
|
||||
if (asTable) {
|
||||
return (
|
||||
<tr className={`graph-legend-series ${seriesOptionClasses}`}>
|
||||
<td>{seriesLabel}</td>
|
||||
{valueItems}
|
||||
</tr>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className={`graph-legend-series ${seriesOptionClasses}`}>
|
||||
{seriesLabel}
|
||||
{valueItems}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface LegendSeriesLabelProps {
|
||||
label: string;
|
||||
color: string;
|
||||
yaxis?: number;
|
||||
onLabelClick?: (event) => void;
|
||||
}
|
||||
|
||||
class LegendSeriesLabel extends React.PureComponent<LegendSeriesLabelProps & LegendSeriesIconProps> {
|
||||
static defaultProps = {
|
||||
yaxis: undefined,
|
||||
onLabelClick: () => {},
|
||||
};
|
||||
|
||||
render() {
|
||||
const { label, color, yaxis } = this.props;
|
||||
const { onColorChange, onToggleAxis } = this.props;
|
||||
return [
|
||||
<LegendSeriesIcon
|
||||
key="icon"
|
||||
color={color}
|
||||
yaxis={yaxis}
|
||||
onColorChange={onColorChange}
|
||||
onToggleAxis={onToggleAxis}
|
||||
/>,
|
||||
<a className="graph-legend-alias pointer" title={label} key="label" onClick={e => this.props.onLabelClick(e)}>
|
||||
{label}
|
||||
</a>,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
interface LegendSeriesIconProps {
|
||||
color: string;
|
||||
yaxis?: number;
|
||||
onColorChange?: (color: string) => void;
|
||||
onToggleAxis?: () => void;
|
||||
}
|
||||
|
||||
function SeriesIcon(props) {
|
||||
return <i className="fa fa-minus pointer" style={{ color: props.color }} />;
|
||||
}
|
||||
|
||||
class LegendSeriesIcon extends React.PureComponent<LegendSeriesIconProps> {
|
||||
static defaultProps = {
|
||||
yaxis: undefined,
|
||||
onColorChange: () => {},
|
||||
onToggleAxis: () => {},
|
||||
};
|
||||
|
||||
render() {
|
||||
const { color, yaxis } = this.props;
|
||||
const IconWithColorPicker = withColorPicker(SeriesIcon);
|
||||
|
||||
return (
|
||||
<IconWithColorPicker
|
||||
optionalClass="graph-legend-icon"
|
||||
color={color}
|
||||
yaxis={yaxis}
|
||||
onColorChange={this.props.onColorChange}
|
||||
onToggleAxis={this.props.onToggleAxis}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
interface LegendValueProps {
|
||||
value: string;
|
||||
valueName: string;
|
||||
asTable?: boolean;
|
||||
}
|
||||
|
||||
function LegendValue(props: LegendValueProps) {
|
||||
const value = props.value;
|
||||
const valueName = props.valueName;
|
||||
if (props.asTable) {
|
||||
return <td className={`graph-legend-value ${valueName}`}>{value}</td>;
|
||||
}
|
||||
return <div className={`graph-legend-value ${valueName}`}>{value}</div>;
|
||||
}
|
||||
|
||||
function renderLegendValues(props: LegendItemProps, series, asTable = false) {
|
||||
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} asTable={asTable} />
|
||||
);
|
||||
}
|
||||
}
|
||||
return legendValueItems;
|
||||
}
|
||||
|
||||
function getOptionSeriesCSSClasses(series, hiddenSeries) {
|
||||
const classes = [];
|
||||
if (series.yaxis === 2) {
|
||||
classes.push('graph-legend-series--right-y');
|
||||
}
|
||||
if (hiddenSeries[series.alias] && hiddenSeries[series.alias] === true) {
|
||||
classes.push('graph-legend-series-hidden');
|
||||
}
|
||||
return classes.join(' ');
|
||||
}
|
||||
@@ -22,7 +22,7 @@ import { alignYLevel } from './align_yaxes';
|
||||
import config from 'app/core/config';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Legend, GraphLegendProps } from './Legend';
|
||||
import { Legend, GraphLegendProps } from './Legend/Legend';
|
||||
|
||||
import { GraphCtrl } from './module';
|
||||
|
||||
@@ -98,6 +98,7 @@ class GraphElement {
|
||||
onToggleSeries: this.ctrl.toggleSeries.bind(this.ctrl),
|
||||
onToggleSort: this.ctrl.toggleSort.bind(this.ctrl),
|
||||
onColorChange: this.ctrl.changeSeriesColor.bind(this.ctrl),
|
||||
onToggleAxis: this.ctrl.toggleAxis.bind(this.ctrl),
|
||||
};
|
||||
const legendReactElem = React.createElement(Legend, legendProps);
|
||||
const legendElem = this.elem.parent().find('.graph-legend');
|
||||
|
||||
Reference in New Issue
Block a user