Google charts how to get crosshairs to remain after selection in React - reactjs

I've searched extensively for this issue here and haven't been able to figure this out. I have a google chart in my app and have a callback function in place to get the details of each point when selected so that I can update a modal to display more info elsewhere.
However, when I have this callback activated and the user clicks the item, the crosshairs do not stay. When I don't have the callback active, they do remain and I get a nice small circle around the selected point like this:
image of crosshairs
Here are the chartevent details I have in place which are working to return the details of the point. Is the chartevent option perhaps overriding a crosshair default?
Grateful for any advice.
Cheers.
const chartEvents = [{
eventName: "select",
options: {
tooltip: {
trigger: "selection"
}
},
callback: ({ chartWrapper }) => {
const chart = chartWrapper.getChart().getSelection()[0].row;
this.setState((prevState) => ({ selectedMonth: chart }))
this.setChangedMonth()
}
}]

Related

How to add 3rd party editor to Wagtail 2.2+?

We have been using Froala editor within Wagtail for years, and even though Draftail is nice, the end user wants to continue to use Frola, especially as a license fee has been paid for it, and it offers extra functionality that they use.
I have used the following which works great for any version of Wagtail prior to version 2.2:
https://github.com/jaydensmith/wagtailfroala/pull/5/commits/d64d00831375489cfacefa7af697a9e76fb7f175
However in Wagtail version 2.2 this has changed:
https://docs.wagtail.org/en/stable/releases/2.2.html#javascript-templates-in-modal-workflows-are-deprecated, this causes selecting images within Froala to no longer work correctly. You get to pick the image, but it fails to move onto the 2nd dialog to select alignment and then click insert.
It looks like wagtailfroala/static/froala/js/froala.js needs to be changed to add onload to the ModalWorkflow.
$.FE.RegisterCommand('insertImage', {
title: 'Insert Image',
undo: false,
focus: true,
refreshAfterCallback: false,
popup: true,
callback: function () {
var editor = this;
return ModalWorkflow({
url: window.chooserUrls.imageChooser + '?select_format=true',
responses: {
imageChosen: function(imageData) {
editor.edit.off();
var $img = $(imageData.html);
$img.on('load', function() {
_loadedCallback(editor, $(this));
});
// Make sure we have focus.
// Call the event.
editor.edit.on();
editor.events.focus(true);
editor.selection.restore();
editor.undo.saveStep();
// Insert marker and then replace it with the image.
if (editor.opts.imageSplitHTML) {
editor.markers.split();
} else {
editor.markers.insert();
}
var $marker = editor.$el.find('.fr-marker');
$marker.replaceWith($img);
editor.html.wrap();
editor.selection.clear();
editor.events.trigger('contentChanged');
editor.undo.saveStep();
editor.events.trigger('image.inserted', [$img]);
}
}
});
},
plugin: 'image'
});
But what needs to be added to make it work? I can't find any documentation or examples on how do to this? Please help or point me in the direction of the documentation for how this should be done.
Thank you so much in advance.

Fluent UI DetailsList - Is there a way to add filters to each column

I am using Fluent UI DetailsList. My table looks like below:
I need filters below every column (text or drop-down) as shown below:
Please let me know if this is possible? Or maybe a way to display custom header (using html) ?
This actually turned out to be easier than I thought it'd be...
If you're ok with clicking the column header to reveal the choices (vs having the dropdown directly under the title) then this can be achieved using the ContextualMenu component in conjunction with DetailsList. I got it working by tweaking from the variable row height example in the official docs: https://developer.microsoft.com/en-us/fluentui#/controls/web/detailslist/variablerowheights.
Add a ContextualMenu underneath your DetailsList:
<DetailsList
items={items}
columns={columns}
/>
{this.state.contextualMenuProps && <ContextualMenu {...this.state.contextualMenuProps} />}
Inside your column definition, set the hasDropdown action so the user gets a UI indicator that they can/should click the header, and call a contextMenu method (note I'm using onColumnContextMenu as well as onColumnClick so it doesn't matter if they left or right click the header:
{
key: 'dept',
name: 'Department',
fieldName: 'dept',
minWidth: 125,
maxWidth: 200,
onColumnContextMenu: (column, ev) => {
this.onColumnContextMenu(column, ev);
},
onColumnClick: (ev, column) => {
this.onColumnContextMenu(column, ev);
},
columnActionsMode: ColumnActionsMode.hasDropdown,
}
When the onColumnContextMenu method gets invoked, we need to build the context menu properties that will get consumed by the ContextualMenu component. Note the dismissal method as well, which clears out the state so the menu is hidden.
private onContextualMenuDismissed = (): void => {
this.setState({
contextualMenuProps: undefined,
});
}
private onColumnContextMenu = (column: IColumn, ev: React.MouseEvent<HTMLElement>): void => {
if (column.columnActionsMode !== ColumnActionsMode.disabled) {
this.setState({
contextualMenuProps: this.getContextualMenuProps(ev, column),
});
}
};
Finally, inside of getContextualMenuProps you need to determine what the options should be for the user to click. In this example, I'm simply giving sort options (you'll need to add an onClick handler to actually do something when the user clicks the item), but I'll use the column to determine what those items should actually be and paint the filters into the items collection so the user can select one to filter.
private getContextualMenuProps = (ev: React.MouseEvent<HTMLElement>, column: IColumn): IContextualMenuProps => {
const items: IContextualMenuItem[] = [
{
key: 'aToZ',
name: 'A to Z',
iconProps: { iconName: 'SortUp' },
canCheck: true,
checked: column.isSorted && !column.isSortedDescending,
},
{
key: 'zToA',
name: 'Z to A',
iconProps: { iconName: 'SortDown' },
canCheck: true,
checked: column.isSorted && column.isSortedDescending,
}
];
return {
items: items,
target: ev.currentTarget as HTMLElement,
directionalHint: DirectionalHint.bottomLeftEdge,
gapSpace: 10,
isBeakVisible: true,
onDismiss: this.onContextualMenuDismissed,
}
}
Note the target on the ContextualMenuProps object, which is what tells the ContextualMenu where to lock itself onto (in this case, the column header that you clicked to instantiate the menu.
Detail list filter for each column without context menu -
https://codesandbox.io/s/rajesh-patil74-jzuiy?file=/src/DetailsList.CustomColumns.Example.tsx
For instance - Providing filter in text field associated with each column will apply filter on color column.

React Dnd useDrag is not working properly?

I'm using react dnd and it's useDrag method not working properly. Let me elaborate the situation:
User will drag list item from left to right as stated below:
Final outcome of right side will be like this below pic,
every list items list 1, 2, 3 will be draggable everywhere and droppable.
The list items List 1 useDrag code is :
const [{ isDragging }, drag, preview] = useDrag({
item: {
type: 'tool',
id: id
},
canDrag: true,
begin(props, monitor, component) {
document.querySelectorAll(".rowWrapper").forEach(function(item){
item.classList.add("rowBorder", "pd-row-drag", "mb-row-drag");
});
document.querySelectorAll(".drop-area").forEach(function(element) {
element.classList.add("dropAreaPosition");
});
document.querySelectorAll(".rowBorderOverlay").forEach(function(element) {
element.classList.add("hideElement");
});
document.querySelectorAll(".rowActions").forEach(function(element) {
element.classList.add("hideElement");
});
},
end(props, monitor, component) {
document.querySelectorAll(".rowWrapper").forEach(function(element) {
element.classList.remove("rowBorder", "pd-row-drag", "mb-row-drag");
});
document.querySelectorAll(".dropZone").forEach(function(element) {
element.classList.remove("showDropZone");
});
document.querySelectorAll(".drop-area").forEach(function(element) {
element.classList.remove("placeHolder","dropAreaPosition");
});
document.querySelectorAll(".rowActions").forEach(function(element) {
element.classList.remove("hideElement");
});
},
collect: monitor => ({
item: monitor.getItem(),
isDragging: !!monitor.isDragging()
}),
});
What I'm doing here is, when dragging begins I'm doing the above stuff like adding classes/removing. By doing like this, useDrag is not working properly when you drag list 1 the full container is not draggable only the portion of it.
if I remove begin, end I can drag the entire container, I don't know what's causing the problem here ?
Any help on this really appreciable ? or how do I do the stuff like adding classes/removing whild dragging or drag begin ?

Office Fabric React Nav Icons not shown and iconClassName not being applied

My nav items need to have colour and icon changes.
I'm finding however that the set of icons I seem to have and the iconClassName do not seem to be being shown
{
key: 'upload',
name: 'MAU',
icon: 'AlertSolid',
iconClassName: 'bg-90',
onClick: () => { return; },
['data-automation-id']: 'uploadNonFocusButton'
}
It appears that there is a limited set of icons supported within the Nav and CommandBar. Is this correct? I'm also surprised that the iconClassName is not being picked up.

Saving state of hbox widths after splitter move

I'm trying to save the visual state of a panel. The Panel consists of two child containers, with hbox/flex layout and a splitter between them.
{
xtype:'panel',
layout: {
align: 'stretch',
type: 'hbox'
},
items:[
{
xtype:'container',
title: 'left panel',
flex:1
},
{
xtype:'splitter'
},
{
xtype:'container',
title: 'left panel',
flex:2
}
]
}
I already have a working state manager. The "left panel" contains a grid, and the grid is storing it's column states just fine. The state manager fires from a controllers init function by:
var stateProvider=Ext.create('Ext.state.LocalStorageProvider');
Ext.state.Manager.setProvider(stateProvider);
The grid uses the framework standard approach for storing it's state by setting stateId: 'GridState' and stateful:true.
However I'm unable to figure out how ExtJS want's me to do the same with the flex values of the main layout. I've tried setting stateful and stateId on the splitter. I've tried without events, and with stateEvents: ['move']. I've also tried setting stateful on the leftpanel and with stateEvents to resize. Finally I've tried setting stateful on the parent panel, with and without stateEvents: afterlayout.
I do know that it's possible to fetch the event after the splitter is moved. Then I could store the flex values as custom states and manually look for them somewhere in the layout/render process, however I guess there must be a more standard approach for a problem that seems so trivial.
What is the standard framework approach for storing the "splitter position" / "flex values" of a hbox/vbox layout?
Yes there is a standard way to add states. And there is no default state for your splitter so you'll have to add these functions:
Example state:
getState: function () {
var me = this;
var state = {};
state.yourCustomState = 'state'; //you can save what you want
return state;
},
applyState: function (state) {
var me = this;
if (state && state.yourCustomState) {
//Do stuff
}
}
And you need your state to be triggered, you can use stateEvents: http://docs.sencha.com/extjs/4.1.3/#!/api/Ext.resizer.Splitter-method-addStateEvents
You can add the resize event to your stateEvents.

Resources