Skip to content

Commit

Permalink
Pushing v1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
ardeora committed Sep 24, 2021
1 parent 03dcc62 commit 476c617
Show file tree
Hide file tree
Showing 15 changed files with 597 additions and 154 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
# Changelog

## GRNOC Worldview Plugin 1.1.0 -- Fri Sep 2021
* More Universal Data Mapping
* Bug Fixes

## GRNOC Worldview Plugin 1.0.1 -- Tue Apr 2021

* Hides zoom in/zoom out/editing controls when in presentation view
* Ability to have custom legend text colors

## GRNOC Worldview Plugin 1.0.0 -- Thu Apr 2021
### Key Features
- Create network maps
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

VERSION = 1.0.1
VERSION = 1.1.0
NAME = globalnoc-worldview-panel

rpm: dist
Expand Down
2 changes: 1 addition & 1 deletion globalnoc-worldview-panel.spec
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
Name: globalnoc-worldview-panel
Version: 1.0.1
Version: 1.1.0
Release: 1%{?dist}
Summary: Network Map Panel For Grafana

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "globalnoc-worldview-panel",
"version": "1.0.1",
"version": "1.1.0",
"description": "",
"scripts": {
"build": "grafana-toolkit plugin:build",
Expand All @@ -26,4 +26,4 @@
"react-virtualized-auto-sizer": "^1.0.5",
"uuid": "^8.3.2"
}
}
}
174 changes: 95 additions & 79 deletions src/AtlasPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, { Component } from 'react';
import { PanelProps, SelectableValue, urlUtil } from '@grafana/data';
import { SimpleOptions, CircuitDataType } from 'types';
import { SimpleOptions } from 'types';
import { v4 as uuidv4 } from 'uuid';
import { DataUtil } from './util/DataUtil';
// import { DataUtil } from './util/DataUtil';
import { Select, Icon } from '@grafana/ui';
import { cx } from 'emotion';
import { getMapSelectorTheme } from './util/MapSelector';
Expand All @@ -23,22 +23,18 @@ interface FetchSession {
[key: string]: string;
}

interface DataDictionary {
[key: string]: {
// Node Name
[key: string]: {
// Interface Name
input?: CircuitDataType[];
output?: CircuitDataType[];
};
};
interface DataValue {
aggregate_group: string;
data_target: string;
values: Array<[number, number]>;
}

let editFromPanel = false;
let fetchSession: FetchSession = {};
let mapUpdated = false;
let lastDataDictionaryCreated = '';
let dataDictionary: DataDictionary = {};
let dataValues: DataValue[] = [];
// let dataDictionary: DataDictionary = {};
let styles = getMapSelectorTheme(config.theme);

export class AtlasPanel extends Component<Props, AtlasPanelState> {
Expand Down Expand Up @@ -166,7 +162,7 @@ export class AtlasPanel extends Component<Props, AtlasPanelState> {
editorButton.style.display = 'none';
if (atlas.editor.sidebar.sbContainer) {
atlas.editor.hideToolbar();
atlas.editor.hideSidebar();
atlas.editor.hideSidebar();
}

atlas.removeAllTopologies();
Expand Down Expand Up @@ -235,11 +231,21 @@ export class AtlasPanel extends Component<Props, AtlasPanelState> {

// Remove all existing topologies and add new one
atlas.removeAllTopologies();
atlas.addTopology(topology);
setData();
// if (!display) {
// atlas.hideTopology(map.name);
// }
console.log(topology);
if (Array.isArray(topology)) {
for (const topo of topology) {
atlas.addTopology(topo);
}
} else {
atlas.addTopology(topology);
}

try {
setData();
} catch (error) {
console.log('Could not set data :(');
}

reinforceView(lat, lng);
}
}
Expand All @@ -266,8 +272,21 @@ export class AtlasPanel extends Component<Props, AtlasPanelState> {

setMapTile() {
let { atlas } = this.state;
let { mapTile } = this.props.options;
atlas.showTile(mapTile);
let { mapTile, mapTileURL } = this.props.options;

if (!mapTileURL) {
mapTileURL = '';
}

if (mapTile) {
atlas.addTile({
url: mapTileURL,
maxZoom: 20,
name: 'custom',
});
}

mapTile ? atlas.showTile('custom') : atlas.showTile('map');
}

setWeatherTile() {
Expand All @@ -285,12 +304,13 @@ export class AtlasPanel extends Component<Props, AtlasPanelState> {
let { atlas } = this.state;
let { legend } = this.props.options;

atlas.changeLegendProperty('lines', 'type', legend.type);
atlas.changeLegendValues('lines', legend.threshold, legend.colors);

if (legend.display) {
atlas.legends.lines.show();
atlas.changeLegendProperty('lines', 'orientation', legend.orientation);
atlas.changeLegendProperty('lines', 'size', legend.size + '%');
atlas.changeLegendProperty('lines', 'type', legend.type);
atlas.changeLegendValues('lines', legend.threshold, legend.colors);

let labelBar = atlas.legends.lines.labelBar as HTMLDivElement;
let labels = Array.from(labelBar.children) as HTMLDivElement[];
Expand All @@ -302,6 +322,15 @@ export class AtlasPanel extends Component<Props, AtlasPanelState> {
}
}

setDataMappingOptions() {
let { dataMappings } = this.props.options;
let { atlas } = this.state;

for (const property in dataMappings) {
atlas.changeCircuitColoringProperties(property, dataMappings[property]);
}
}

setTopologyUpdateListeners() {
let { atlas } = this.state;

Expand Down Expand Up @@ -372,7 +401,7 @@ export class AtlasPanel extends Component<Props, AtlasPanelState> {

setTopologyData() {
let { data } = this.props;

console.log('DATA', data);
// Only create a new data dictionary if data is fetched again
if (data.state === 'Done' && lastDataDictionaryCreated !== data.request!.requestId) {
this.createDataDictionary();
Expand All @@ -382,73 +411,60 @@ export class AtlasPanel extends Component<Props, AtlasPanelState> {
}

addDataToCircuits() {
let { topologies } = this.state.atlas;
let aggregateMetric = this.props.options.legend.target;

for (const topologyName in topologies) {
let { lines } = topologies[topologyName];

for (const line of lines) {
if (!line.metadata?.targets) {
continue;
}
let values: CircuitDataType[][] = [];
for (const target of line.metadata.targets) {
let node = target.node_name;
let intf = target.interface_name;
if (dataDictionary[node] && dataDictionary[node][intf]) {
if (dataDictionary[node][intf].input) {
values.push(dataDictionary[node][intf].input!);
}
if (dataDictionary[node][intf].output) {
values.push(dataDictionary[node][intf].output!);
}
}
}

let [inputAggregate, outputAggregate] = DataUtil.aggregateData(values, aggregateMetric);

if (inputAggregate) {
let dataObj = {
label: line.data.label,
input: { now: inputAggregate },
output: { now: outputAggregate },
};
if (line.metadata) {
dataObj = {
...dataObj,
...line.metadata,
};
}
line.set('data', dataObj);
}
}
}
this.state.atlas.applyData(dataValues);
this.setDataMappingOptions();
}

createDataDictionary() {
let { series, request } = this.props.data;
lastDataDictionaryCreated = request!.requestId;
dataDictionary = {};
dataValues = [];

let data_aggregates = this.props.options.dataAggregateGroups;

if (data_aggregates.length === 0) {
data_aggregates.push({
aggregate_group: 'data',
pattern: '.*',
});
}

for (const data of series) {
try {
let [node, intf, altIntf, value] = data.name!.split('+');
let values = data.fields[1].values['buffer'];
if (!dataDictionary[node]) {
dataDictionary[node] = {};
}
if (!dataDictionary[node][intf]) {
dataDictionary[node][intf] = {};
let data_target: string = data.name!;
let speeds = data.fields[1].values.toArray().reverse() as number[];
let timestamps = data.fields[0].values.toArray().reverse() as number[];

let values: Array<[number, number]> = [];

for (let i = 0; i < speeds.length; i++) {
const speed = speeds[i];
const time = timestamps[i];
values.push([time, speed]);
}
dataDictionary[node][intf][value] = values;
if (intf !== altIntf) {
if (!dataDictionary[node][altIntf]) {
dataDictionary[node][altIntf] = {};

let aggregate_group: string | undefined;

for (const aggregates of data_aggregates) {
if (!aggregates.pattern) {
continue;
}
let regex = new RegExp(aggregates.pattern);
if (regex.test(data_target)) {
aggregate_group = aggregates.aggregate_group;
break;
}
dataDictionary[node][altIntf][value] = values;
}

if (aggregate_group) {
dataValues.push({
data_target,
values,
aggregate_group,
});
}
} catch (error) {
dataDictionary = {};
dataValues = [];
return;
}
}
Expand Down
38 changes: 19 additions & 19 deletions src/config/AtlasOptions.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
var lineHtml = `<div class=\"atlas4-tt-container\" style=\"width: 250px;background: #ffffffd4;box-shadow: 0 3px 14px rgba(0,0,0,0.4);border-radius: 5px;\/* box-sizing: border-box; *\/padding: 10px 0;\">\r\n <h4 class=\"atlas4-tt-topology\" style=\"\r\n font-size: 18px;\r\n font-weight: 500;\r\n color: #4f505f;\r\n text-align: center;\r\n text-transform: uppercase;\r\n \">$topology<\/h4>\r\n <h6 class=\"atlas4-tt-label\" style=\"\r\n font-size: 12px;\r\n color: #4f505f;\r\n font-weight: 500;\r\n text-align: center;\r\n \">$label<\/h6>\r\n <img class=\"atlas4-tt-image\" img_src=\"$image\" alt=\"$topology\" style=\"\r\n display: block;\r\n margin: 10px auto;\r\n max-height: 50px; max-width: 225px; \"\/>\r\n <div class=\"atlas4-tt-column atlas4-tt-column-line\" style=\"padding: 0px 20px;font-size: 0;\">\r\n <p style=\"\r\n margin: 0;\r\n font-size: 12px;\r\n display: inline-block;\r\n width: 20%;\r\n \">Input<\/p>\r\n <p style=\"\r\n margin: 0;\r\n font-size: 12px;\r\n display: inline-block;\r\n width: 80%;\r\n text-align: end;\r\n \">$input.now<\/p>\r\n <\/div>\r\n <div class=\"atlas4-tt-column atlas4-tt-column-line\" style=\"padding: 0px 20px;font-size: 0;\">\r\n <p style=\"\r\n margin: 0;\r\n font-size: 12px;\r\n display: inline-block;\r\n width: 20%;\r\n \">Output<\/p>\r\n <p style=\"\r\n margin: 0;\r\n font-size: 12px;\r\n display: inline-block;\r\n width: 80%;\r\n text-align: end;\r\n \">$output.now<\/p>\r\n <\/div>\r\n<\/div>`
var pointHtml = `<div class=\"atlas4-tt-container\" style=\"\r\n width: 100px;\r\n background: #ffffffd4;\r\n box-shadow: 0 0px 8px rgba(0,0,0,0.4);\r\n border-radius: 5px;\r\n padding: 10px 10px;\r\n \">\r\n <div>\r\n <h4 class=\"atlas4-tt-topology\" style=\"\r\n font-size: 16px;\r\n text-align: center;\r\n text-transform: uppercase;\r\n \">$topology<\/h4>\r\n <img class=\"atlas4-tt-image\" img_src=\"$image\" style=\"\r\n margin: 6px 0px; max-width: 50px; max-height: 50px; position: relative; left: 50%; transform: translate(-50%, 0);\">\r\n <\/div>\r\n <h6 class=\"atlas4-tt-label\" style=\"\r\n text-align: center;\r\n font-size: 14px;\r\n font-weight: 500;\r\n \">$label<\/h6>\r\n<\/div>`
import pointHtml from './pointHtml.js';
import lineHtml from './lineHtml.js';

const mapOptions = {
debug: true,
Expand Down Expand Up @@ -58,23 +58,21 @@ const tileOptions = [
id: 'mapbox.streets',
default: true,
name: 'map'
},
{
url: 'https://api.mapbox.com/styles/v1/grnoc/ckm2bqp58b1fr17o0xc82mn52/tiles/{z}/{x}/{y}',
token: 'pk.eyJ1IjoiZ3Jub2MiLCJhIjoiY2ttMmJvcWt4MXB3cDJucWVxN2ltZ2JoOCJ9.ZKpOkAW4qvdQZoX_Rk18QQ',
maxZoom: 20,
attribution: 'Nope',
id: 'mapbox.satellite',
name: 'satellite'
},
{
url: 'https://api.mapbox.com/styles/v1/grnoc/cknkjwibv0ksy17o6ohjkk3t2/tiles/{z}/{x}/{y}',
token: 'pk.eyJ1IjoiZ3Jub2MiLCJhIjoiY2ttMmJvcWt4MXB3cDJucWVxN2ltZ2JoOCJ9.ZKpOkAW4qvdQZoX_Rk18QQ',
maxZoom: 20,
attribution: 'Nope',
id: 'mapbox.monochrome',
name: 'dark'
}
// {
// url: 'https://api.mapbox.com/styles/v1/grnoc/ckm2bqp58b1fr17o0xc82mn52/tiles/{z}/{x}/{y}',
// token: 'pk.eyJ1IjoiZ3Jub2MiLCJhIjoiY2ttMmJvcWt4MXB3cDJucWVxN2ltZ2JoOCJ9.ZKpOkAW4qvdQZoX_Rk18QQ',
// maxZoom: 20,
// attribution: 'Nope',
// id: 'mapbox.satellite',
// name: 'satellite'
// },
// {
// url: 'https://api.mapbox.com/styles/v1/grnoc/cknkjwibv0ksy17o6ohjkk3t2/tiles/{z}/{x}/{y}',
// token: 'pk.eyJ1IjoiZ3Jub2MiLCJhIjoiY2ttMmJvcWt4MXB3cDJucWVxN2ltZ2JoOCJ9.ZKpOkAW4qvdQZoX_Rk18QQ',
// maxZoom: 20,
// name: 'dark'
// }
]

const overlayTileOptions = [
Expand Down Expand Up @@ -105,7 +103,9 @@ const pointOptions = {
}

const lineOptions = {
dataTarget: 'input.now',
dataTarget: 'chooseMax',
dataAggregate: 'first',
colorCriteria: 'now',
weight: 3,
opacity: 1,
smoothFactor: 1,
Expand Down
2 changes: 1 addition & 1 deletion src/config/lineHtml.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 476c617

Please sign in to comment.