mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Panels: Add support for panels with no padding (#20012)
* Panels: Added support to set panel padding to zero * WIP: fullChromeControl work * Tweaks to header position * Reverted some overlay mechanic and now back to no title only * Fixed test * Fixed transparent flag * Added show title * Added font weight to value * Reverted back to no padding option * Fixed issue with border and width and height
This commit is contained in:
parent
a4a9715237
commit
65942efb95
@ -20,8 +20,8 @@ datasources:
|
|||||||
url: http://localhost:3011
|
url: http://localhost:3011
|
||||||
|
|
||||||
- name: gdev-testdata
|
- name: gdev-testdata
|
||||||
type: testdata
|
|
||||||
isDefault: true
|
isDefault: true
|
||||||
|
type: testdata
|
||||||
|
|
||||||
- name: gdev-influxdb
|
- name: gdev-influxdb
|
||||||
type: influxdb
|
type: influxdb
|
||||||
|
@ -74,6 +74,7 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
|||||||
defaults?: TOptions;
|
defaults?: TOptions;
|
||||||
onPanelMigration?: PanelMigrationHandler<TOptions>;
|
onPanelMigration?: PanelMigrationHandler<TOptions>;
|
||||||
onPanelTypeChanged?: PanelTypeChangedHandler<TOptions>;
|
onPanelTypeChanged?: PanelTypeChangedHandler<TOptions>;
|
||||||
|
noPadding?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Legacy angular ctrl. If this exists it will be used instead of the panel
|
* Legacy angular ctrl. If this exists it will be used instead of the panel
|
||||||
@ -95,6 +96,11 @@ export class PanelPlugin<TOptions = any> extends GrafanaPlugin<PanelPluginMeta>
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setNoPadding() {
|
||||||
|
this.noPadding = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is called before the panel first loads if
|
* This function is called before the panel first loads if
|
||||||
* the current version is different than the version that was saved.
|
* the current version is different than the version that was saved.
|
||||||
|
@ -160,7 +160,7 @@ export function calculateLayout(props: Props): LayoutResult {
|
|||||||
export function getTitleStyles(layout: LayoutResult) {
|
export function getTitleStyles(layout: LayoutResult) {
|
||||||
const styles: CSSProperties = {
|
const styles: CSSProperties = {
|
||||||
fontSize: `${layout.titleFontSize}px`,
|
fontSize: `${layout.titleFontSize}px`,
|
||||||
textShadow: '#333 1px 1px 5px',
|
textShadow: '#333 0px 0px 1px',
|
||||||
color: '#EEE',
|
color: '#EEE',
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -175,7 +175,8 @@ export function getValueStyles(layout: LayoutResult) {
|
|||||||
const styles: CSSProperties = {
|
const styles: CSSProperties = {
|
||||||
fontSize: `${layout.valueFontSize}px`,
|
fontSize: `${layout.valueFontSize}px`,
|
||||||
color: '#EEE',
|
color: '#EEE',
|
||||||
textShadow: '#333 1px 1px 5px',
|
textShadow: '#333 0px 0px 1px',
|
||||||
|
fontWeight: 500,
|
||||||
lineHeight: LINE_HEIGHT,
|
lineHeight: LINE_HEIGHT,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -347,7 +348,7 @@ function renderLineGeom(layout: LayoutResult) {
|
|||||||
const lineStyle: any = {
|
const lineStyle: any = {
|
||||||
stroke: '#CCC',
|
stroke: '#CCC',
|
||||||
lineWidth: 2,
|
lineWidth: 2,
|
||||||
shadowBlur: 15,
|
shadowBlur: 10,
|
||||||
shadowColor: '#444',
|
shadowColor: '#444',
|
||||||
shadowOffsetY: 7,
|
shadowOffsetY: 7,
|
||||||
};
|
};
|
||||||
@ -359,7 +360,7 @@ function renderVibrant2Geom(layout: LayoutResult) {
|
|||||||
const lineStyle: any = {
|
const lineStyle: any = {
|
||||||
stroke: '#CCC',
|
stroke: '#CCC',
|
||||||
lineWidth: 2,
|
lineWidth: 2,
|
||||||
shadowBlur: 15,
|
shadowBlur: 10,
|
||||||
shadowColor: '#444',
|
shadowColor: '#444',
|
||||||
shadowOffsetY: -5,
|
shadowOffsetY: -5,
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent, CSSProperties } from 'react';
|
||||||
import { VizOrientation } from '@grafana/data';
|
import { VizOrientation } from '@grafana/data';
|
||||||
|
|
||||||
interface Props<V, D> {
|
interface Props<V, D> {
|
||||||
@ -87,12 +87,13 @@ export class VizRepeater<V, D = {}> extends PureComponent<Props<V, D>, State<V>>
|
|||||||
repeaterStyle.flexDirection = 'column';
|
repeaterStyle.flexDirection = 'column';
|
||||||
itemStyles.marginBottom = `${itemSpacing}px`;
|
itemStyles.marginBottom = `${itemSpacing}px`;
|
||||||
vizWidth = width;
|
vizWidth = width;
|
||||||
vizHeight = height / values.length - itemSpacing;
|
vizHeight = height / values.length - itemSpacing + itemSpacing / values.length;
|
||||||
} else {
|
} else {
|
||||||
repeaterStyle.flexDirection = 'row';
|
repeaterStyle.flexDirection = 'row';
|
||||||
|
repeaterStyle.justifyContent = 'space-between';
|
||||||
itemStyles.marginRight = `${itemSpacing}px`;
|
itemStyles.marginRight = `${itemSpacing}px`;
|
||||||
vizHeight = height;
|
vizHeight = height;
|
||||||
vizWidth = width / values.length - itemSpacing;
|
vizWidth = width / values.length - itemSpacing + itemSpacing / values.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
itemStyles.width = `${vizWidth}px`;
|
itemStyles.width = `${vizWidth}px`;
|
||||||
@ -103,7 +104,7 @@ export class VizRepeater<V, D = {}> extends PureComponent<Props<V, D>, State<V>>
|
|||||||
<div style={repeaterStyle}>
|
<div style={repeaterStyle}>
|
||||||
{values.map((value, index) => {
|
{values.map((value, index) => {
|
||||||
return (
|
return (
|
||||||
<div key={index} style={itemStyles}>
|
<div key={index} style={getItemStylesForIndex(itemStyles, index, values.length)}>
|
||||||
{renderValue(value, vizWidth, vizHeight, dims)}
|
{renderValue(value, vizWidth, vizHeight, dims)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -112,3 +113,17 @@ export class VizRepeater<V, D = {}> extends PureComponent<Props<V, D>, State<V>>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Removes any padding on the last item
|
||||||
|
*/
|
||||||
|
function getItemStylesForIndex(itemStyles: CSSProperties, index: number, length: number): CSSProperties {
|
||||||
|
if (index === length - 1) {
|
||||||
|
return {
|
||||||
|
...itemStyles,
|
||||||
|
marginRight: 0,
|
||||||
|
marginBottom: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return itemStyles;
|
||||||
|
}
|
||||||
|
@ -7,13 +7,14 @@ import { PanelHeader } from './PanelHeader/PanelHeader';
|
|||||||
import { ErrorBoundary } from '@grafana/ui';
|
import { ErrorBoundary } from '@grafana/ui';
|
||||||
// Utils & Services
|
// Utils & Services
|
||||||
import { getTimeSrv, TimeSrv } from '../services/TimeSrv';
|
import { getTimeSrv, TimeSrv } from '../services/TimeSrv';
|
||||||
import { applyPanelTimeOverrides, calculateInnerPanelHeight } from 'app/features/dashboard/utils/panel';
|
import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
|
||||||
import { profiler } from 'app/core/profiler';
|
import { profiler } from 'app/core/profiler';
|
||||||
import { getProcessedDataFrames } from '../state/runRequest';
|
import { getProcessedDataFrames } from '../state/runRequest';
|
||||||
import templateSrv from 'app/features/templating/template_srv';
|
import templateSrv from 'app/features/templating/template_srv';
|
||||||
import config from 'app/core/config';
|
import config from 'app/core/config';
|
||||||
// Types
|
// Types
|
||||||
import { DashboardModel, PanelModel } from '../state';
|
import { DashboardModel, PanelModel } from '../state';
|
||||||
|
import { PANEL_BORDER } from 'app/core/constants';
|
||||||
import {
|
import {
|
||||||
LoadingState,
|
LoadingState,
|
||||||
ScopedVars,
|
ScopedVars,
|
||||||
@ -260,13 +261,22 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const PanelComponent = plugin.panel;
|
const PanelComponent = plugin.panel;
|
||||||
const innerPanelHeight = calculateInnerPanelHeight(panel, height);
|
|
||||||
const timeRange = data.timeRange || this.timeSrv.timeRange();
|
const timeRange = data.timeRange || this.timeSrv.timeRange();
|
||||||
|
|
||||||
|
const headerHeight = this.hasOverlayHeader() ? 0 : theme.panelHeaderHeight;
|
||||||
|
const chromePadding = plugin.noPadding ? 0 : theme.panelPadding;
|
||||||
|
const panelWidth = width - chromePadding * 2 - PANEL_BORDER;
|
||||||
|
const innerPanelHeight = height - headerHeight - chromePadding * 2 - PANEL_BORDER;
|
||||||
|
|
||||||
|
const panelContentClassNames = classNames({
|
||||||
|
'panel-content': true,
|
||||||
|
'panel-content--no-padding': plugin.noPadding,
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{loading === LoadingState.Loading && this.renderLoadingState()}
|
{loading === LoadingState.Loading && this.renderLoadingState()}
|
||||||
<div className="panel-content">
|
<div className={panelContentClassNames}>
|
||||||
<PanelComponent
|
<PanelComponent
|
||||||
id={panel.id}
|
id={panel.id}
|
||||||
data={data}
|
data={data}
|
||||||
@ -274,7 +284,7 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
timeZone={this.props.dashboard.getTimezone()}
|
timeZone={this.props.dashboard.getTimezone()}
|
||||||
options={panel.getOptions()}
|
options={panel.getOptions()}
|
||||||
transparent={panel.transparent}
|
transparent={panel.transparent}
|
||||||
width={width - theme.panelPadding * 2}
|
width={panelWidth}
|
||||||
height={innerPanelHeight}
|
height={innerPanelHeight}
|
||||||
renderCounter={renderCounter}
|
renderCounter={renderCounter}
|
||||||
replaceVariables={this.replaceVariables}
|
replaceVariables={this.replaceVariables}
|
||||||
@ -294,6 +304,23 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasOverlayHeader() {
|
||||||
|
const { panel } = this.props;
|
||||||
|
const { errorMessage, data } = this.state;
|
||||||
|
|
||||||
|
// always show normal header if we have an error message
|
||||||
|
if (errorMessage) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// always show normal header if we have time override
|
||||||
|
if (data.request && data.request.timeInfo) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !panel.hasTitle();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { dashboard, panel, isFullscreen, width, height } = this.props;
|
const { dashboard, panel, isFullscreen, width, height } = this.props;
|
||||||
const { errorMessage, data } = this.state;
|
const { errorMessage, data } = this.state;
|
||||||
@ -302,8 +329,8 @@ export class PanelChrome extends PureComponent<Props, State> {
|
|||||||
const containerClassNames = classNames({
|
const containerClassNames = classNames({
|
||||||
'panel-container': true,
|
'panel-container': true,
|
||||||
'panel-container--absolute': true,
|
'panel-container--absolute': true,
|
||||||
'panel-container--no-title': !panel.hasTitle(),
|
'panel-container--transparent': transparent,
|
||||||
'panel-transparent': transparent,
|
'panel-container--no-title': this.hasOverlayHeader(),
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -103,13 +103,11 @@ export class PanelHeader extends Component<Props, State> {
|
|||||||
<span className="panel-title-text">
|
<span className="panel-title-text">
|
||||||
{title} <span className="fa fa-caret-down panel-menu-toggle" />
|
{title} <span className="fa fa-caret-down panel-menu-toggle" />
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
{this.state.panelMenuOpen && (
|
{this.state.panelMenuOpen && (
|
||||||
<ClickOutsideWrapper onClick={this.closeMenu}>
|
<ClickOutsideWrapper onClick={this.closeMenu}>
|
||||||
<PanelHeaderMenu panel={panel} dashboard={dashboard} />
|
<PanelHeaderMenu panel={panel} dashboard={dashboard} />
|
||||||
</ClickOutsideWrapper>
|
</ClickOutsideWrapper>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{timeInfo && (
|
{timeInfo && (
|
||||||
<span className="panel-time-info">
|
<span className="panel-time-info">
|
||||||
<i className="fa fa-clock-o" /> {timeInfo}
|
<i className="fa fa-clock-o" /> {timeInfo}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import { TimeRange } from '@grafana/data';
|
import { TimeRange } from '@grafana/data';
|
||||||
import { applyPanelTimeOverrides } from 'app/features/dashboard/utils/panel';
|
import { applyPanelTimeOverrides, calculateInnerPanelHeight } from 'app/features/dashboard/utils/panel';
|
||||||
import { advanceTo, clear } from 'jest-date-mock';
|
import { advanceTo, clear } from 'jest-date-mock';
|
||||||
import { dateTime, DateTime } from '@grafana/data';
|
import { dateTime, DateTime } from '@grafana/data';
|
||||||
|
import { PanelModel } from '../state';
|
||||||
|
import { getPanelPlugin } from '../../plugins/__mocks__/pluginMocks';
|
||||||
|
|
||||||
const dashboardTimeRange: TimeRange = {
|
const dashboardTimeRange: TimeRange = {
|
||||||
from: dateTime([2019, 1, 11, 12, 0]),
|
from: dateTime([2019, 1, 11, 12, 0]),
|
||||||
@ -71,4 +73,19 @@ describe('applyPanelTimeOverrides', () => {
|
|||||||
expect((overrides.timeRange.raw.from as DateTime).toISOString()).toEqual(expectedFromDate.toISOString());
|
expect((overrides.timeRange.raw.from as DateTime).toISOString()).toEqual(expectedFromDate.toISOString());
|
||||||
expect((overrides.timeRange.raw.to as DateTime).toISOString()).toEqual(expectedToDate.toISOString());
|
expect((overrides.timeRange.raw.to as DateTime).toISOString()).toEqual(expectedToDate.toISOString());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Calculate panel height', () => {
|
||||||
|
const panelModel = new PanelModel({});
|
||||||
|
const height = calculateInnerPanelHeight(panelModel, 100);
|
||||||
|
|
||||||
|
expect(height).toBe(82);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Calculate panel height with panel plugin zeroChromePadding', () => {
|
||||||
|
const panelModel = new PanelModel({});
|
||||||
|
panelModel.pluginLoaded(getPanelPlugin({ id: 'table' }, null, null).setNoPadding());
|
||||||
|
|
||||||
|
const height = calculateInnerPanelHeight(panelModel, 100);
|
||||||
|
expect(height).toBe(98);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -173,10 +173,7 @@ export function getResolution(panel: PanelModel): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function calculateInnerPanelHeight(panel: PanelModel, containerHeight: number): number {
|
export function calculateInnerPanelHeight(panel: PanelModel, containerHeight: number): number {
|
||||||
return (
|
const chromePadding = panel.plugin && panel.plugin.noPadding ? 0 : config.theme.panelPadding * 2;
|
||||||
containerHeight -
|
const headerHeight = panel.hasTitle() ? config.theme.panelHeaderHeight : 0;
|
||||||
(panel.hasTitle() ? config.theme.panelHeaderHeight : 0) -
|
return containerHeight - headerHeight - chromePadding - PANEL_BORDER;
|
||||||
config.theme.panelPadding * 2 -
|
|
||||||
PANEL_BORDER
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ import {
|
|||||||
|
|
||||||
import { Threshold, ValueMapping, FieldConfig, DataLink, PanelEditorProps, FieldDisplayOptions } from '@grafana/data';
|
import { Threshold, ValueMapping, FieldConfig, DataLink, PanelEditorProps, FieldDisplayOptions } from '@grafana/data';
|
||||||
|
|
||||||
import { SingleStatOptions, SparklineOptions, displayModes, colorModes } from './types';
|
import { SingleStatOptions, SparklineOptions, displayModes } from './types';
|
||||||
import { SparklineEditor } from './SparklineEditor';
|
import { SparklineEditor } from './SparklineEditor';
|
||||||
import {
|
import {
|
||||||
getDataLinksVariableSuggestions,
|
getDataLinksVariableSuggestions,
|
||||||
@ -52,7 +52,6 @@ export class SingleStatEditor extends PureComponent<PanelEditorProps<SingleStatO
|
|||||||
});
|
});
|
||||||
|
|
||||||
onDisplayModeChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, displayMode: value });
|
onDisplayModeChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, displayMode: value });
|
||||||
onColorModeChange = ({ value }: any) => this.props.onOptionsChange({ ...this.props.options, colorMode: value });
|
|
||||||
|
|
||||||
onDefaultsChange = (field: FieldConfig) => {
|
onDefaultsChange = (field: FieldConfig) => {
|
||||||
this.onDisplayOptionsChanged({
|
this.onDisplayOptionsChanged({
|
||||||
@ -91,21 +90,16 @@ export class SingleStatEditor extends PureComponent<PanelEditorProps<SingleStatO
|
|||||||
value={displayModes.find(item => item.value === options.displayMode)}
|
value={displayModes.find(item => item.value === options.displayMode)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-field">
|
|
||||||
<FormLabel width={8}>Color by</FormLabel>
|
|
||||||
<Select
|
|
||||||
width={12}
|
|
||||||
options={colorModes}
|
|
||||||
defaultValue={colorModes[0]}
|
|
||||||
onChange={this.onColorModeChange}
|
|
||||||
value={colorModes.find(item => item.value === options.colorMode)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<SparklineEditor options={options.sparkline} onChange={this.onSparklineChanged} />
|
<SparklineEditor options={options.sparkline} onChange={this.onSparklineChanged} />
|
||||||
</PanelOptionsGroup>
|
</PanelOptionsGroup>
|
||||||
|
|
||||||
<PanelOptionsGroup title="Field (default)">
|
<PanelOptionsGroup title="Field">
|
||||||
<FieldPropertiesEditor showMinMax={true} onChange={this.onDefaultsChange} value={defaults} />
|
<FieldPropertiesEditor
|
||||||
|
showMinMax={true}
|
||||||
|
onChange={this.onDefaultsChange}
|
||||||
|
value={defaults}
|
||||||
|
showTitle={true}
|
||||||
|
/>
|
||||||
</PanelOptionsGroup>
|
</PanelOptionsGroup>
|
||||||
|
|
||||||
<ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={defaults.thresholds} />
|
<ThresholdsEditor onChange={this.onThresholdsChanged} thresholds={defaults.thresholds} />
|
||||||
|
@ -7,5 +7,6 @@ import { SingleStatEditor } from './SingleStatEditor';
|
|||||||
export const plugin = new PanelPlugin<SingleStatOptions>(SingleStatPanel)
|
export const plugin = new PanelPlugin<SingleStatOptions>(SingleStatPanel)
|
||||||
.setDefaults(defaults)
|
.setDefaults(defaults)
|
||||||
.setEditor(SingleStatEditor)
|
.setEditor(SingleStatEditor)
|
||||||
|
.setNoPadding()
|
||||||
.setPanelChangeHandler(sharedSingleStatPanelChangedHandler)
|
.setPanelChangeHandler(sharedSingleStatPanelChangedHandler)
|
||||||
.setMigrationHandler(sharedSingleStatMigrationHandler);
|
.setMigrationHandler(sharedSingleStatMigrationHandler);
|
||||||
|
@ -8,27 +8,15 @@ export interface SparklineOptions {
|
|||||||
// Structure copied from angular
|
// Structure copied from angular
|
||||||
export interface SingleStatOptions extends SingleStatBaseOptions {
|
export interface SingleStatOptions extends SingleStatBaseOptions {
|
||||||
sparkline: SparklineOptions;
|
sparkline: SparklineOptions;
|
||||||
colorMode: ColorMode;
|
|
||||||
displayMode: SingleStatDisplayMode;
|
displayMode: SingleStatDisplayMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const displayModes: Array<SelectableValue<SingleStatDisplayMode>> = [
|
export const displayModes: Array<SelectableValue<SingleStatDisplayMode>> = [
|
||||||
{ value: SingleStatDisplayMode.Classic, label: 'Classic' },
|
{ value: SingleStatDisplayMode.Classic, label: 'Classic' },
|
||||||
{ value: SingleStatDisplayMode.Classic2, label: 'Classic 2' },
|
|
||||||
{ value: SingleStatDisplayMode.Vibrant, label: 'Vibrant' },
|
{ value: SingleStatDisplayMode.Vibrant, label: 'Vibrant' },
|
||||||
{ value: SingleStatDisplayMode.Vibrant2, label: 'Vibrant 2' },
|
{ value: SingleStatDisplayMode.Vibrant2, label: 'Vibrant 2' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export enum ColorMode {
|
|
||||||
Thresholds,
|
|
||||||
Series,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const colorModes: Array<SelectableValue<ColorMode>> = [
|
|
||||||
{ value: ColorMode.Thresholds, label: 'Thresholds' },
|
|
||||||
{ value: ColorMode.Series, label: 'Series' },
|
|
||||||
];
|
|
||||||
|
|
||||||
export const standardFieldDisplayOptions: FieldDisplayOptions = {
|
export const standardFieldDisplayOptions: FieldDisplayOptions = {
|
||||||
values: false,
|
values: false,
|
||||||
calcs: [ReducerID.mean],
|
calcs: [ReducerID.mean],
|
||||||
@ -48,7 +36,6 @@ export const defaults: SingleStatOptions = {
|
|||||||
sparkline: {
|
sparkline: {
|
||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
colorMode: ColorMode.Thresholds,
|
|
||||||
displayMode: SingleStatDisplayMode.Vibrant,
|
displayMode: SingleStatDisplayMode.Vibrant,
|
||||||
fieldOptions: standardFieldDisplayOptions,
|
fieldOptions: standardFieldDisplayOptions,
|
||||||
orientation: VizOrientation.Auto,
|
orientation: VizOrientation.Auto,
|
||||||
|
@ -55,8 +55,8 @@ div.flot-text {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
&.panel-transparent {
|
&--transparent {
|
||||||
background-color: transparent;
|
background-color: $page-bg;
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,8 +82,11 @@ div.flot-text {
|
|||||||
height: calc(100% - #{$panel-header-height});
|
height: calc(100% - #{$panel-header-height});
|
||||||
width: 100%;
|
width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
// Fixes scrolling on mobile devices
|
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
|
&--no-padding {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// For larger screens, set back to hidden to avoid double scroll bars
|
// For larger screens, set back to hidden to avoid double scroll bars
|
||||||
|
Loading…
Reference in New Issue
Block a user