mirror of
https://github.com/prometheus/prometheus.git
synced 2025-03-05 20:59:13 -08:00
Resize detector, start building legend, axis font colors
Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
parent
d79ef2b7f7
commit
8e75eb5dfb
29
package-lock.json
generated
29
package-lock.json
generated
|
@ -996,6 +996,14 @@
|
||||||
"@types/react": "*"
|
"@types/react": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@types/react-resize-detector": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react-resize-detector/-/react-resize-detector-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-q/kuav2WHLqCOypvNMWR7S3UKSphE0urlvgkiaKpnGXOPsy6/3BCrr+HzcoaMOvuZW7bFngbheS2gITRl4B1xQ==",
|
||||||
|
"requires": {
|
||||||
|
"@types/react": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/reactstrap": {
|
"@types/reactstrap": {
|
||||||
"version": "7.1.3",
|
"version": "7.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/@types/reactstrap/-/reactstrap-7.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/reactstrap/-/reactstrap-7.1.3.tgz",
|
||||||
|
@ -8917,6 +8925,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
|
||||||
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
|
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
|
||||||
},
|
},
|
||||||
|
"lodash-es": {
|
||||||
|
"version": "4.17.11",
|
||||||
|
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.11.tgz",
|
||||||
|
"integrity": "sha512-DHb1ub+rMjjrxqlB3H56/6MXtm1lSksDp2rA2cNWjG8mlDUYFhUj3Di2Zn5IwSU87xLv8tNIQ7sSwE/YOX/D/Q=="
|
||||||
|
},
|
||||||
"lodash._reinterpolate": {
|
"lodash._reinterpolate": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
|
||||||
|
@ -16969,6 +16982,17 @@
|
||||||
"prop-types": "^15.6.1"
|
"prop-types": "^15.6.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-resize-detector": {
|
||||||
|
"version": "3.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-3.4.0.tgz",
|
||||||
|
"integrity": "sha512-T96I8Iqa1hGWyooeFA2Sl6FdPoMhXWINfEKg2/EJLxhP37+/94VNuyuyz9CRqpmApD83IWRR+lbB3r0ADMoKJg==",
|
||||||
|
"requires": {
|
||||||
|
"lodash": "^4.17.11",
|
||||||
|
"lodash-es": "^4.17.11",
|
||||||
|
"prop-types": "^15.6.2",
|
||||||
|
"resize-observer-polyfill": "^1.5.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"react-scripts": {
|
"react-scripts": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-2.1.3.tgz",
|
||||||
|
@ -17678,6 +17702,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
|
||||||
},
|
},
|
||||||
|
"resize-observer-polyfill": {
|
||||||
|
"version": "1.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||||
|
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
|
||||||
|
},
|
||||||
"resolve": {
|
"resolve": {
|
||||||
"version": "1.8.1",
|
"version": "1.8.1",
|
||||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
|
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
"@types/node": "^11.9.3",
|
"@types/node": "^11.9.3",
|
||||||
"@types/react": "^16.8.2",
|
"@types/react": "^16.8.2",
|
||||||
"@types/react-dom": "^16.8.0",
|
"@types/react-dom": "^16.8.0",
|
||||||
|
"@types/react-resize-detector": "^3.1.0",
|
||||||
"bootstrap": "^4.2.1",
|
"bootstrap": "^4.2.1",
|
||||||
"downshift": "^3.2.2",
|
"downshift": "^3.2.2",
|
||||||
"flot": "^2.1.6",
|
"flot": "^2.1.6",
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
"npm": "^6.7.0",
|
"npm": "^6.7.0",
|
||||||
"react": "^16.7.0",
|
"react": "^16.7.0",
|
||||||
"react-dom": "^16.7.0",
|
"react-dom": "^16.7.0",
|
||||||
|
"react-resize-detector": "^3.4.0",
|
||||||
"react-scripts": "2.1.3",
|
"react-scripts": "2.1.3",
|
||||||
"reactstrap": "^7.1.0",
|
"reactstrap": "^7.1.0",
|
||||||
"tempusdominus-bootstrap-4": "^5.1.2",
|
"tempusdominus-bootstrap-4": "^5.1.2",
|
||||||
|
|
16
src/App.css
16
src/App.css
|
@ -2,6 +2,10 @@ body {
|
||||||
padding-top: 10px; /* TODO remove */
|
padding-top: 10px; /* TODO remove */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
.expression-input {
|
.expression-input {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
@ -113,6 +117,13 @@ div.endtime-input {
|
||||||
|
|
||||||
.graph-legend {
|
.graph-legend {
|
||||||
margin: 15px 0 15px 25px;
|
margin: 15px 0 15px 25px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.graph-legend .legend-swatch {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph {
|
.graph {
|
||||||
|
@ -122,6 +133,10 @@ div.endtime-input {
|
||||||
.graph-chart {
|
.graph-chart {
|
||||||
height: 500px;
|
height: 500px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
/* This is picked up by Flot's axis label font renderer,
|
||||||
|
which ignores "color" and uses "fill" instead. */
|
||||||
|
fill: #495057;
|
||||||
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.graph-chart .flot-overlay {
|
.graph-chart .flot-overlay {
|
||||||
|
@ -151,5 +166,6 @@ div.endtime-input {
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-panel-btn {
|
.add-panel-btn {
|
||||||
|
margin-top: -20px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import ReactResizeDetector from 'react-resize-detector';
|
||||||
|
|
||||||
import { Alert } from 'reactstrap';
|
import { Alert } from 'reactstrap';
|
||||||
|
|
||||||
|
@ -7,10 +8,10 @@ require('flot');
|
||||||
require('flot/source/jquery.flot.crosshair');
|
require('flot/source/jquery.flot.crosshair');
|
||||||
require('flot/source/jquery.flot.legend');
|
require('flot/source/jquery.flot.legend');
|
||||||
require('flot/source/jquery.flot.time');
|
require('flot/source/jquery.flot.time');
|
||||||
require('flot/source/jquery.flot.hover');
|
require('flot/source/jquery.canvaswrapper');
|
||||||
require('flot/source/jquery.flot.resize');
|
|
||||||
require('jquery.flot.tooltip');
|
require('jquery.flot.tooltip');
|
||||||
|
|
||||||
|
import Legend from './Legend';
|
||||||
import metricToSeriesName from './MetricFomat';
|
import metricToSeriesName from './MetricFomat';
|
||||||
|
|
||||||
var graphID = 0;
|
var graphID = 0;
|
||||||
|
@ -32,7 +33,6 @@ interface GraphProps {
|
||||||
class Graph extends PureComponent<GraphProps> {
|
class Graph extends PureComponent<GraphProps> {
|
||||||
private id: number = getGraphID();
|
private id: number = getGraphID();
|
||||||
private chartRef = React.createRef<HTMLDivElement>();
|
private chartRef = React.createRef<HTMLDivElement>();
|
||||||
private legendRef = React.createRef<HTMLDivElement>();
|
|
||||||
|
|
||||||
escapeHTML(str: string) {
|
escapeHTML(str: string) {
|
||||||
var entityMap: {[key: string]: string} = {
|
var entityMap: {[key: string]: string} = {
|
||||||
|
@ -112,9 +112,7 @@ class Graph extends PureComponent<GraphProps> {
|
||||||
mouseActiveRadius: 100,
|
mouseActiveRadius: 100,
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
//show: true,
|
show: false,
|
||||||
labelFormatter: (s: string) => {return ' ' + s},
|
|
||||||
container: this.legendRef.current!,
|
|
||||||
},
|
},
|
||||||
xaxis: {
|
xaxis: {
|
||||||
mode: 'time',
|
mode: 'time',
|
||||||
|
@ -201,12 +199,11 @@ class Graph extends PureComponent<GraphProps> {
|
||||||
}
|
}
|
||||||
|
|
||||||
plot() {
|
plot() {
|
||||||
this.destroyPlot();
|
if (this.chartRef.current === null) {
|
||||||
if (this.chartRef.current === null || this.legendRef.current === null) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.destroyPlot();
|
||||||
$.plot($(this.chartRef.current!), this.getData(), this.getOptions());
|
$.plot($(this.chartRef.current!), this.getData(), this.getOptions());
|
||||||
//window.addEventListener('resize', () => this.plot());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
destroyPlot() {
|
destroyPlot() {
|
||||||
|
@ -231,8 +228,9 @@ class Graph extends PureComponent<GraphProps> {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="graph">
|
<div className="graph">
|
||||||
|
<ReactResizeDetector handleWidth onResize={() => this.plot()} />
|
||||||
<div className="graph-chart" ref={this.chartRef} />
|
<div className="graph-chart" ref={this.chartRef} />
|
||||||
<div className="graph-legend" ref={this.legendRef} />
|
<Legend series={this.getData()}/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
28
src/Legend.tsx
Normal file
28
src/Legend.tsx
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
|
||||||
|
import metricToSeriesName from './MetricFomat';
|
||||||
|
|
||||||
|
interface LegendProps {
|
||||||
|
series: any; // TODO: Type this.
|
||||||
|
}
|
||||||
|
|
||||||
|
class Legend extends PureComponent<LegendProps> {
|
||||||
|
renderLegendItem(s: any) {
|
||||||
|
return (
|
||||||
|
<div key={s.label} className="legend-item">
|
||||||
|
<span className="legend-swatch">.</span>
|
||||||
|
<span className="legend-label">{s.label}</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="graph-legend">
|
||||||
|
{this.props.series.map((s: any) => {return this.renderLegendItem(s)})}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Legend;
|
|
@ -187,49 +187,13 @@ class Panel extends Component<PanelProps, PanelState> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getEndDate = () => {
|
|
||||||
// var self = this;
|
|
||||||
// if (!self.endDate || !self.endDate.val()) {
|
|
||||||
// return moment();
|
|
||||||
// }
|
|
||||||
// return self.endDate.data('DateTimePicker').date();
|
|
||||||
// };
|
|
||||||
|
|
||||||
// getOrSetEndDate = () => {
|
|
||||||
// var self = this;
|
|
||||||
// var date = self.getEndDate();
|
|
||||||
// self.setEndDate(date);
|
|
||||||
// return date;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// setEndDate = (date) => {
|
|
||||||
// var self = this;
|
|
||||||
// self.endDate.data('DateTimePicker').date(date);
|
|
||||||
// };
|
|
||||||
|
|
||||||
// increaseEnd = () => {
|
|
||||||
// var self = this;
|
|
||||||
// var newDate = moment(self.getOrSetEndDate());
|
|
||||||
// newDate.add(self.parseDuration(self.rangeInput.val()) / 2, 'seconds');
|
|
||||||
// self.setEndDate(newDate);
|
|
||||||
// self.submitQuery();
|
|
||||||
// };
|
|
||||||
|
|
||||||
// decreaseEnd = () => {
|
|
||||||
// var self = this;
|
|
||||||
// var newDate = moment(self.getOrSetEndDate());
|
|
||||||
// newDate.subtract(self.parseDuration(self.rangeInput.val()) / 2, 'seconds');
|
|
||||||
// self.setEndDate(newDate);
|
|
||||||
// self.submitQuery();
|
|
||||||
// };
|
|
||||||
|
|
||||||
handleChangeStacking = (stacked: boolean) => {
|
handleChangeStacking = (stacked: boolean) => {
|
||||||
this.setState({stacked: stacked});
|
this.setState({stacked: stacked});
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<>
|
<div className="panel">
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<ExpressionInput
|
<ExpressionInput
|
||||||
|
@ -300,10 +264,10 @@ class Panel extends Component<PanelProps, PanelState> {
|
||||||
</Row>
|
</Row>
|
||||||
<Row>
|
<Row>
|
||||||
<Col>
|
<Col>
|
||||||
<Button className="float-right" color="link" onClick={this.props.removePanel}>Remove Panel</Button>
|
<Button className="float-right" color="link" onClick={this.props.removePanel} size="sm">Remove Panel</Button>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue