Skip to content

Commit

Permalink
Merge branch 'develop' into feature/276
Browse files Browse the repository at this point in the history
# Conflicts:
#	binocular-frontend-new/src/plugins/interfaces/visualizationPlugin.ts
  • Loading branch information
MaximilianZenz committed Feb 14, 2025
2 parents d40a00d + a66d86c commit 183ad27
Show file tree
Hide file tree
Showing 21 changed files with 6,412 additions and 668 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ function DashboardItem(props: {
}
}, [fileLists, props.item.dataPluginId]);
const [settings, setSettings] = useState(plugin.defaultSettings);
const [dataName] = useState(plugin.name);

/**
* Create Redux Store from Reducer for individual Item and run saga
Expand All @@ -108,7 +109,7 @@ function DashboardItem(props: {
reducer: plugin.reducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(sagaMiddleware, logger),
});
sagaMiddleware.run(() => plugin.saga(dataPlugin));
sagaMiddleware.run(() => plugin.saga(dataPlugin, dataName));
} else {
store = undefined;
}
Expand Down Expand Up @@ -165,8 +166,10 @@ function DashboardItem(props: {
parametersDateRange: ignoreGlobalParameters ? parametersDateRangeLocal : parametersDateRangeGlobal,
}}
dataConnection={dataPlugin}
dataConverter={plugin.dataConverter}
chartContainerRef={chartContainerRef}
store={store}></plugin.chartComponent>
store={store}
dataName={dataName}></plugin.chartComponent>
</ReduxSubAppStoreWrapper>
</DashboardItemPopout>
) : (
Expand Down Expand Up @@ -203,8 +206,10 @@ function DashboardItem(props: {
parametersDateRange: ignoreGlobalParameters ? parametersDateRangeLocal : parametersDateRangeGlobal,
}}
dataConnection={dataPlugin}
dataConverter={plugin.dataConverter}
chartContainerRef={chartContainerRef}
store={store}></plugin.chartComponent>
store={store}
dataName={dataName}></plugin.chartComponent>
</ReduxSubAppStoreWrapper>
) : (
<div>No Data Plugin Selected</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ import { SprintType } from '../../types/data/sprintType.ts';
import { Reducer, Store } from '@reduxjs/toolkit';
import { ParametersType } from '../../types/parameters/parametersType.ts';
import { FileListElementType } from '../../types/data/fileListType.ts';
import { Properties } from '../visualizationPlugins/simpleVisualizationPlugin/src/interfaces/properties.ts';
import { ChartData, Palette } from '../visualizationPlugins/simpleVisualizationPlugin/src/chart/chart.tsx';

export interface VisualizationPlugin<SettingsType> {
export interface VisualizationPlugin<SettingsType, DataType> {
name: string;
chartComponent: (props: {
settings: SettingsType; // Interface for settings defines which settings are transported
Expand All @@ -15,6 +17,10 @@ export interface VisualizationPlugin<SettingsType> {
// !!
// Not every dataPlugin has all capabilities.
// !!
dataConverter: (
data: DataType[],
props: Properties<SettingsType, DataType>,
) => { chartData: ChartData[]; scale: number[]; palette: Palette };
authorList: AuthorType[]; //list of Users set by Binocular
fileList: FileListElementType[]; //list of Users set by Binocular
sprintList: SprintType[]; //list of Sprints set by Binocular
Expand All @@ -23,9 +29,14 @@ export interface VisualizationPlugin<SettingsType> {
store: Store; //Redux store is needed
// for creating the redux dispatch within the chart component so that it can change the store.
// The store gets dynamically created for each visualization item within the components/dashboard/dashboardItem component
dataName?: string | undefined;
}) => ReactNode;
settingsComponent: (props: { settings: SettingsType; setSettings: (newSettings: SettingsType) => void }) => ReactNode;
helpComponent: () => ReactNode;
dataConverter: (
data: DataType[],
props: Properties<SettingsType, DataType>,
) => { chartData: ChartData[]; scale: number[]; palette: Palette };
defaultSettings: unknown;
export: {
getSVGData: (chartContainerRef: RefObject<HTMLDivElement>) => string; // method that extracts and returns a svg element as a string from a RefObject
Expand All @@ -40,5 +51,5 @@ export interface VisualizationPlugin<SettingsType> {
thumbnail: string;
};
reducer: Reducer;
saga: (dataConnection: DataPlugin) => Generator;
saga: (dataConnection: DataPlugin, name?: string) => Generator;
}
15 changes: 10 additions & 5 deletions binocular-frontend-new/src/plugins/pluginRegistry.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import Commits from './visualizationPlugins/changes';
import Builds from './visualizationPlugins/builds';
import ExampleVisualization from './visualizationPlugins/exampleVisualization';
import ExampleStats from './visualizationPlugins/exampleStats';
import ExampleComplex from './visualizationPlugins/exampleComplex';

import MockData from './dataPlugins/mockData';
import BinocularBackend from './dataPlugins/binocularBackend';
import Github from './dataPlugins/github';
import PouchDb from './dataPlugins/pouchDB';

import { VisualizationPlugin } from './interfaces/visualizationPlugin.ts';
import Changes from './visualizationPlugins/changes';
import { DataPluginBuild } from './interfaces/dataPluginInterfaces/dataPluginBuilds.ts';
import createVisualizationPlugin from './visualizationPlugins/simpleVisualizationPlugin';
import { BuildSettings, ChangesSettings } from './visualizationPlugins/simpleVisualizationPlugin/src/settings/settings.tsx';
import { DataPluginCommit } from './interfaces/dataPluginInterfaces/dataPluginCommits.ts';

// should currently work for commits, but fetching the data is still hardcoded to one or the other
const builds = createVisualizationPlugin<BuildSettings, DataPluginBuild>('builds', Builds);
const changes = createVisualizationPlugin<ChangesSettings, DataPluginCommit>('commits', Changes);

//The implicit type here has to be any because every Visualization plugin has a different settings type implied
//eslint-disable-next-line @typescript-eslint/no-explicit-any
export const visualizationPlugins: VisualizationPlugin<any>[] = [Commits, Builds, ExampleVisualization, ExampleStats, ExampleComplex];
export const visualizationPlugins: VisualizationPlugin<any, any>[] = [builds, changes];

//Order = priority used when nothing selected by the user.
export const dataPlugins = [MockData, BinocularBackend, PouchDb, Github];
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
import Chart from './chart/chart.tsx';
import PreviewImage from '../assets/thumbnail.svg';
import Settings, { SettingsType } from './settings/settings.tsx';
import { VisualizationPlugin } from '../../../interfaces/visualizationPlugin.ts';
import { getSVGData } from './utilities/utilities.ts';
import Reducer from './reducer';
import { convertToChartData } from './utilities/dataConverter.ts';
import Saga from './saga';
import Help from './help/help.tsx';
import { DataPluginBuild } from '../../../interfaces/dataPluginInterfaces/dataPluginBuilds.ts';

const Builds: VisualizationPlugin<SettingsType> = {
const Builds: VisualizationPlugin<SettingsType, DataPluginBuild> = {
name: 'Builds',
chartComponent: Chart,
// ts-expect-error
chartComponent: null,
settingsComponent: Settings,
dataConverter: convertToChartData,
helpComponent: Help,
defaultSettings: { splitBuildsPerAuthor: false, visualizationStyle: 'curved' },
defaultSettings: { splitBuildsPerAuthor: false, visualizationStyle: 'curved', showSprints: false },
export: {
getSVGData: getSVGData,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import moment from 'moment/moment';
import { BuildChartData, Palette } from '../chart/chart.tsx';
import { ParametersType } from '../../../../../types/parameters/parametersType.ts';
import chroma from 'chroma-js';
import _ from 'lodash';
import { DataPluginBuild } from '../../../../interfaces/dataPluginInterfaces/dataPluginBuilds.ts';
import { AuthorType } from '../../../../../types/data/authorType.ts';
import { Properties } from '../../../simpleVisualizationPlugin/src/interfaces/properties.ts';
import { BuildSettings } from '../../../simpleVisualizationPlugin/src/settings/settings.tsx';

export function convertBuildDataToChartData(
builds: DataPluginBuild[],
authorList: AuthorType[],
parameters: ParametersType,
splitBuildsPerAuthor: boolean,
interface BuildChartData {
date: number;
[signature: string]: number;
}

interface Palette {
[signature: string]: { main: string; secondary: string };
}

export function convertToChartData(
builds: DataPluginBuild[] | unknown[],
props: Properties<BuildSettings, DataPluginBuild>,
): {
chartData: BuildChartData[];
scale: number[];
Expand All @@ -21,7 +29,9 @@ export function convertBuildDataToChartData(
}

//Sort builds after their build time in case they arnt sorted
const sortedBuilds = _.clone(builds).sort((c1, c2) => new Date(c1.createdAt).getTime() - new Date(c2.createdAt).getTime());
const sortedBuilds = _.clone(builds as DataPluginBuild[]).sort(
(c1, c2) => new Date(c1.createdAt).getTime() - new Date(c2.createdAt).getTime(),
);

const firstTimestamp = sortedBuilds[0].createdAt;
const lastTimestamp = sortedBuilds[sortedBuilds.length - 1].createdAt;
Expand All @@ -32,15 +42,23 @@ export function convertBuildDataToChartData(
let returnValue;

if (sortedBuilds.length > 0) {
if (splitBuildsPerAuthor) {
returnValue = getDataByAuthors(parameters, firstTimestamp, lastTimestamp, sortedBuilds, scale, palette, chartData, authorList);
if (props.settings.splitBuildsPerAuthor) {
returnValue = getDataByAuthors(
props.parameters,
firstTimestamp,
lastTimestamp,
sortedBuilds,
scale,
palette,
chartData,
props.authorList,
);
} else {
returnValue = getDataByStatus(parameters, firstTimestamp, lastTimestamp, sortedBuilds, scale, palette, chartData);
returnValue = getDataByStatus(props.parameters, firstTimestamp, lastTimestamp, sortedBuilds, scale, palette, chartData);
}
} else {
return { chartData: [], palette: {}, scale: [] };
}
// TODO split chartData into positive and negative Data for generalisation
return returnValue;
}

Expand Down Expand Up @@ -306,26 +324,3 @@ function getGranularity(resolution: string): { unit: string; interval: moment.Du
return { interval: moment.duration(1, 'day'), unit: 'day' };
}
}

export enum PositiveNegativeSide {
POSITIVE,
NEGATIVE,
}

export function splitPositiveNegativeData(data: BuildChartData[], side: PositiveNegativeSide) {
return data.map((d) => {
const newD: BuildChartData = { date: d.date };
Object.keys(d).forEach((k) => {
if (k !== 'date') {
if (d[k] >= 0 && side === PositiveNegativeSide.POSITIVE) {
newD[k] = d[k];
} else if (d[k] < 0 && side === PositiveNegativeSide.NEGATIVE) {
newD[k] = d[k];
} else {
newD[k] = 0;
}
}
});
return newD;
});
}

This file was deleted.

Loading

0 comments on commit 183ad27

Please sign in to comment.