Browse Source

make zoom-in work

pull/2/head
rozetko 2 years ago
parent
commit
0725f36d62
  1. 2
      package.json
  2. 5
      src/components/Panel.tsx
  3. 128
      src/models/options/barOptions.ts
  4. 8
      yarn.lock

2
package.json

@ -15,7 +15,7 @@
"license": "GPL V3", "license": "GPL V3",
"devDependencies": { "devDependencies": {
"@chartwerk/gauge-pod": "^0.6.2", "@chartwerk/gauge-pod": "^0.6.2",
"@chartwerk/bar-pod": "^0.6.2", "@chartwerk/bar-pod": "^0.6.3",
"@grafana/data": "latest", "@grafana/data": "latest",
"@grafana/toolkit": "latest", "@grafana/toolkit": "latest",
"@grafana/ui": "latest", "@grafana/ui": "latest",

5
src/components/Panel.tsx

@ -18,9 +18,10 @@ import * as _ from 'lodash';
interface Props extends PanelProps<PanelOptions> {} interface Props extends PanelProps<PanelOptions> {}
export function Panel({ options, data, width, height, timeZone, timeRange, onChangeTimeRange }: Props) { export function Panel({ options, data, width, height, timeRange, onChangeTimeRange }: Props) {
const grafanaSeriesList = getGrafanaSeriesList(data, timeRange); const grafanaSeriesList = getGrafanaSeriesList(data, timeRange);
let chartContainer = useRef(null); let chartContainer = useRef(null);
// we request animation frame here because we need an existing DOM-element at the moment we render the pod // we request animation frame here because we need an existing DOM-element at the moment we render the pod
window.requestAnimationFrame(() => { window.requestAnimationFrame(() => {
console.log('pod', options.visualizationType); console.log('pod', options.visualizationType);
@ -33,7 +34,7 @@ export function Panel({ options, data, width, height, timeZone, timeRange, onCha
break; break;
case Pod.BAR: case Pod.BAR:
const barSeries = new BarSeries(grafanaSeriesList).getChartwerkSeries(); const barSeries = new BarSeries(grafanaSeriesList).getChartwerkSeries();
const chartwerkBarOptions = new BarOptions(grafanaSeriesList, options).getChartwerkOptions(); const chartwerkBarOptions = new BarOptions(grafanaSeriesList, onChangeTimeRange).getChartwerkOptions();
console.log('data', barSeries, chartwerkBarOptions); console.log('data', barSeries, chartwerkBarOptions);
pod = new ChartwerkBarPod((chartContainer as any).current, barSeries, chartwerkBarOptions); pod = new ChartwerkBarPod((chartContainer as any).current, barSeries, chartwerkBarOptions);
break; break;

128
src/models/options/barOptions.ts

@ -1,124 +1,17 @@
import { PanelOptions, Aggregation, Threshold, Icon, IconPosition, Condition } from 'types'; import { AbsoluteTimeRange } from '@grafana/data';
import { filterMetricListByAlias, getAggregatedValueFromSerie } from '../../utils';
import _ from 'lodash';
// Convert Grafana options into Chartwerk Bar options // Convert Grafana options into Chartwerk Bar options
export class BarOptions { export class BarOptions {
private thresholds: Array<{ value: number; color: string }> = []; constructor(private grafanaSeriesList: any[], private changeTimeRange: (timeRange: AbsoluteTimeRange) => void) {
private icons: Array<{ src: string; position: string; size: number }> = []; console.log(this.grafanaSeriesList)
constructor(private grafanaSeriesList: any[], private grafanaOptions: PanelOptions) {
this._setThresholds();
this._setIcons();
}
private _setThresholds(): void {
if (_.isEmpty(this.grafanaOptions.gauge.thresholds.thresholds)) {
return;
}
for (let [idx, threshold] of this.grafanaOptions.gauge.thresholds.thresholds.entries()) {
this._setThreshold(threshold, idx);
}
}
private _setThreshold(threshold: Threshold, idx: number): void {
const value = threshold.useMetric
? this.getLastValueFromMetrics(threshold.metricName, `Threshold ${idx + 1}`)
: threshold.value;
if (value === null || value === undefined) {
// TODO: may be throw an error
return;
}
this.thresholds.push({
value,
color: threshold.color,
});
}
private _setIcons(): void {
if (_.isEmpty(this.grafanaOptions.gauge.icons)) {
return;
}
for (let [idx, icon] of this.grafanaOptions.gauge.icons.entries()) {
this._setIcon(icon, idx);
}
}
private _setIcon(icon: Icon, idx: number): void {
if (!this._areIconConditionsFulfilled(icon, idx)) {
return;
}
this.icons.push({
src: icon.url,
size: icon.size,
position: this._getChartwerkIconPosition(icon.position),
});
}
private _areIconConditionsFulfilled(icon: Icon, iconIdx: number): boolean {
if (_.isEmpty(icon.metrics)) {
return true;
}
// check each condition and return false if something goes wrong
for (let [conditionIdx, metric] of icon.metrics.entries()) {
const value = this.getLastValueFromMetrics(metric, `Icon ${iconIdx + 1}, Condition ${conditionIdx + 1}`);
if (value === null || value === undefined) {
// TODO: may be throw an error
return false;
}
if (!this.checkIconCondition(value, icon.values[conditionIdx], icon.conditions[conditionIdx])) {
return false;
}
}
return true;
}
private checkIconCondition(metricValue: number, inputValue: number, condition: Condition): boolean {
if (inputValue === undefined || inputValue === null) {
return true;
}
switch (condition) {
case Condition.EQUAL:
return metricValue === inputValue;
case Condition.GREATER:
return metricValue > inputValue;
case Condition.GREATER_OR_EQUAL:
return metricValue >= inputValue;
case Condition.LESS:
return metricValue < inputValue;
case Condition.LESS_OR_EQUAL:
return metricValue <= inputValue;
default:
throw new Error(`Unknown condition: ${condition}`);
}
}
private _getChartwerkIconPosition(position: IconPosition): string {
// TODO: use chartwerk types
switch (position) {
case IconPosition.MIDDLE:
return 'middle';
case IconPosition.UPPER_LEFT:
return 'left';
case IconPosition.UPPER_RIGHT:
return 'right';
default:
throw new Error(`Unknown Icon Position ${position}`);
}
} }
getChartwerkOptions(): any { getChartwerkOptions(): any {
return { return {
axis: { axis: {
x: { x: {
format: 'custom', format: 'time',
valueFormatter: (value: any) => {
return 'L' + value;
},
}, },
y: { y: {
format: 'custom', format: 'custom',
@ -132,6 +25,7 @@ export class BarOptions {
matching: false, matching: false,
zoomEvents: { zoomEvents: {
scroll: { zoom: { isActive: false }, pan: { isActive: false } }, scroll: { zoom: { isActive: false }, pan: { isActive: false } },
mouse: { doubleClick: { isActive: false } },
}, },
annotations: [ annotations: [
{ key: 'm-1', color: 'red' }, { key: 'm-1', color: 'red' },
@ -139,17 +33,9 @@ export class BarOptions {
], ],
eventsCallbacks: { eventsCallbacks: {
zoomIn: (range: any) => { zoomIn: (range: any) => {
console.log('range', range); this.changeTimeRange({ from: range[0][0], to: range[0][1] });
}, }
}, },
}; };
} }
getLastValueFromMetrics(metricName: string | undefined, optionName: string): number | null {
// optionName -> helper in Error, mb use option path instead
const filteredSeries = filterMetricListByAlias(this.grafanaSeriesList, metricName, optionName);
const serie = filteredSeries[0];
// Last value for now
return getAggregatedValueFromSerie(serie, Aggregation.LAST);
}
} }

8
yarn.lock

@ -902,10 +902,10 @@
resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.0.tgz#fe364f025ba74f6de6c837a84ef44bdb1d61e68f" resolved "https://registry.yarnpkg.com/@braintree/sanitize-url/-/sanitize-url-6.0.0.tgz#fe364f025ba74f6de6c837a84ef44bdb1d61e68f"
integrity sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w== integrity sha512-mgmE7XBYY/21erpzhexk4Cj1cyTQ9LzvnTxtzM17BJ7ERMNE6W72mQRo0I1Ud8eFJ+RVVIcBNhLFZ3GX4XFz5w==
"@chartwerk/bar-pod@^0.6.2": "@chartwerk/bar-pod@^0.6.3":
version "0.6.2" version "0.6.3"
resolved "https://registry.yarnpkg.com/@chartwerk/bar-pod/-/bar-pod-0.6.2.tgz#780089eed241795ff964639f38305cd2fa7a89d6" resolved "https://registry.yarnpkg.com/@chartwerk/bar-pod/-/bar-pod-0.6.3.tgz#e5ef980cd51d59050949124cefc55d20039b5567"
integrity sha512-2cmuHjdNRo3230oLI1ZRjLANLKfuI5f299WcBAL0eP/6DF5NB8TNV+WrA/Lw+bt9ySop/CtIFEswKhD3Sy+0dA== integrity sha512-mspgcW3YhCiWQw371+7IOFAonIlrNtX9IhAo1zPOTdXWFHkb5JvcR/hnqhOBAenM2zc7xjZKeih/wkbmIqXjHw==
dependencies: dependencies:
"@chartwerk/core" latest "@chartwerk/core" latest

Loading…
Cancel
Save