Rajat Dabade b339f0509b
Improved graph panel full view (#3039)
* feat: done with prd full view

* refactor: updated some variable and naming convection

* feat: when click on label only select associated graph

* feat: made the table scrollable

* feat: update the table column length

* feat: save notification after saving state

* refactor: removed unwanted code

* refactor: renamed some file

* fix: linter issue

* fix: position of save button

* refactor: seperated widgetGraphComponent from gridGraphComponent

* feat: fetching the localstorage data while initial loading of graph

* fix: dependency of graphVisibilityHandler for other component

* refactor: updated the notification msg on save

* fix: linter error

* refactor: remove the update logic of graph from graph component

* refactor: created utils and move some utility code

* refactor: place the checkbox component in fullview

* refactor: updated the utils function added enun localstorage

* refactor: added enum for table columns data

* refactor: name changes to graphVisibilityStates

* refactor: shifted the type to types.ts

* refactor: sepearated the type from graph componnet

* refactor: seperated graphOptions from graph component

* refactor: updated imports

* refactor: shifted the logic to utils

* refactor: remove unused file and check for full view

* refactor: using PanelType instead of GraphType

* refactor: changed the variable name

* refactor: provided checks of useEffect

* test: added unit test case for utility function

* refactor: one on one maping of props and value

* refactor: panelTypeAndGraphManagerVisibility as a props

* refactor: remove the enforing of type in useChartMutable

* refactor: updated the test case

* refactor: moved types to types.ts files

* refactor: separated types from components

* refactor: one to one mapping and cancel feature

* refactor: remove unwanted useEffect and used eventEmitter

* fix: only open chart visibility will change issue

* refactor: removed unwanted useEffect

* refactor: resolve the hang issue for full view

* refactor: legend to checkbox connection, separated code

* refactor: updated styled component GraphContainer

* chore: removed unwanted consoles

* refactor: ux changes

* fix: eslint and updated test case

* refactor: review comments

* chore: fix types

* refactor: made utils for getIsGraphLegendToggleAvailable

* refactor: removed the ref mutation from graphPanelSwitch

* refactor: resolve the issue of chart state not getting reflect outside fullview

* refactor: common utility for toggle graphs visibility in chart

* refactor: shifted ref to perticular component level

* test: removed extra space

* chore: close on save and NaN infinity check

* refactor: added yAxisUnit to GraphManager table header

* refactor: create a function for appending yAxisUnit to table header

* fix: decimal upto 2 decimal points

---------

Co-authored-by: Vishal Sharma <makeavish786@gmail.com>
Co-authored-by: Pranay Prateek <pranay@signoz.io>
Co-authored-by: Palash Gupta <palashgdev@gmail.com>
2023-08-02 20:41:09 +05:30

115 lines
3.5 KiB
TypeScript

import { Chart, ChartType, Plugin } from 'chart.js';
import { Events } from 'constants/events';
import { colors } from 'lib/getRandomColor';
import { get } from 'lodash-es';
import { eventEmitter } from 'utils/getEventEmitter';
const getOrCreateLegendList = (
chart: Chart,
id: string,
isLonger: boolean,
): HTMLUListElement => {
const legendContainer = document.getElementById(id);
let listContainer = legendContainer?.querySelector('ul');
if (!listContainer) {
listContainer = document.createElement('ul');
listContainer.style.display = 'flex';
// listContainer.style.flexDirection = isLonger ? 'column' : 'row';
listContainer.style.margin = '0';
listContainer.style.padding = '0';
listContainer.style.overflowY = 'scroll';
listContainer.style.justifyContent = isLonger ? 'start' : 'center';
listContainer.style.alignItems = isLonger ? 'start' : 'center';
listContainer.style.minHeight = '2rem';
listContainer.style.height = '100%';
listContainer.style.flexWrap = 'wrap';
listContainer.style.justifyContent = 'center';
listContainer.style.fontSize = '0.75rem';
legendContainer?.appendChild(listContainer);
}
return listContainer;
};
export const legend = (id: string, isLonger: boolean): Plugin<ChartType> => ({
id: 'htmlLegend',
afterUpdate(chart): void {
const ul = getOrCreateLegendList(chart, id || 'legend', isLonger);
// Remove old legend items
while (ul.firstChild) {
ul.firstChild.remove();
}
// Reuse the built-in legendItems generator
const items = get(chart, [
'options',
'plugins',
'legend',
'labels',
'generateLabels',
])
? get(chart, ['options', 'plugins', 'legend', 'labels', 'generateLabels'])(
chart,
)
: null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
items?.forEach((item: Record<any, any>, index: number) => {
const li = document.createElement('li');
li.style.alignItems = 'center';
li.style.cursor = 'pointer';
li.style.display = 'flex';
li.style.marginLeft = '10px';
// li.style.marginTop = '5px';
li.onclick = (): void => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const { type } = chart.config;
if (type === 'pie' || type === 'doughnut') {
// Pie and doughnut charts only have a single dataset and visibility is per item
chart.toggleDataVisibility(index);
} else {
chart.setDatasetVisibility(
item.datasetIndex,
!chart.isDatasetVisible(item.datasetIndex),
);
eventEmitter.emit(Events.UPDATE_GRAPH_MANAGER_TABLE, {
name: id,
index: item.datasetIndex,
});
}
chart.update();
};
// Color box
const boxSpan = document.createElement('span');
boxSpan.style.background = `${item.strokeStyle}` || `${colors[0]}`;
boxSpan.style.borderColor = `${item?.strokeStyle}`;
boxSpan.style.borderWidth = `${item.lineWidth}px`;
boxSpan.style.display = 'inline-block';
boxSpan.style.minHeight = '0.75rem';
boxSpan.style.marginRight = '0.5rem';
boxSpan.style.minWidth = '0.75rem';
boxSpan.style.borderRadius = '50%';
if (item.text) {
// Text
const textContainer = document.createElement('span');
textContainer.style.margin = '0';
textContainer.style.padding = '0';
textContainer.style.textDecoration = item.hidden ? 'line-through' : '';
const text = document.createTextNode(item.text);
textContainer.appendChild(text);
li.appendChild(boxSpan);
li.appendChild(textContainer);
ul.appendChild(li);
}
});
},
});