observablehq: is it possible to have inputs with custom html? - accordion

I would like to have multiple inputs, such as Inputs.select, collapsed into an accordion menu in an observablehq notebook. I managed to create an accordion menu using custom html (js/css/html), but I am struggling to add the inputs in the accordion menu. Here is an observablehq notebook with the accordion menu. I would like to have the inputs as part of Section 1/Section 2.

Yup! I have examples in this notebook.
You can use Inputs.form to combine several inputs in one cell—
viewof form = Inputs.form({
option1: Inputs.checkbox(["A", "B"], {label: "Select some"}),
option2: Inputs.range([0, 100], {label: "Amount", step: 1}),
option3: Inputs.radio(["A", "B"], {label: "Select one"}),
option4: Inputs.select(["A", "B"], {label: "Select one"})
})
And you can nest Inputs.form, and pass it a template option, to put the inputs in different accordion sections:
viewof nestedForm = Inputs.form([
Inputs.form({
a: Inputs.range([0, 100], { label: "Amount", step: 1 }),
b: Inputs.select(["A", "B"], { label: "Select one" })
}),
Inputs.form({
a: Inputs.range([0, 100], { label: "Number", step: 1 }),
b: Inputs.checkbox(["C", "D", "E"], { label: "Select any" })
})
], {template: inputs => htl.html`<div>
<details><summary>Section 1</summary>${inputs[0]}</details>
<details><summary>Section 2</summary>${inputs[1]}</details>
</div>`})

Related

How to find google charts (Sankey) select events selection data - including tooltip column

I am creating a Sankey chart via react-google-charts. Each time when clicked on the link between the nodes I am printing the data which has been working fine until recently.
Assume my Sankey diagram to be like this and I clicked on the link between A & P:
[A] ----> [P] ------> [X]
[B] ----> [Q] ------> [Y]
[C] ----> [R] ------> [Z]
let myOptions = {
sankey: {
link: {
interactivity: true
}
}
}
...
...
<Chart
chartType='Sankey'
data={
[
['From', 'To', 'Weight', {role: 'tooltip', type: 'string'}],
['A', 'P', 1, 'i111'],
['B', 'Q', 1, 'j333'],
['C', 'R', 1, 'k444'],
['P', 'X', 1, 'l555'],
['Q', 'Y', 1, 'l666'],
['R', 'Z', 1, 'n999']
]
}
columns
options={myOptions}
chartEvents={[
{
eventName: 'select',
callback: ({chartWrapper}) => {
const chart = chartWrapper.getChart()
const selection = chart.getSelection()
if (selection.length === 1) {
const [selectedItem] = selection
const {row} = selectedItem
// below line was working until recently, but not anymore
console.log(chartWrapper.getDataTable().Vf[row].c)
// updated the property key after which it works
console.log(chartWrapper.getDataTable().Wf[row].c)
// returns [{v: 'A'}, {v: 'P'}, {v: 1}, {v: 'i111'}]
}
}
}
]}
/>
I can also get the selection data like this but it does not give me the final column value i.e., tooltip in this case.
console.log(chartWrapper.getDataTable().cache[row])
// returns [{Me: 'A'}, {Me: 'P'}, {Me: '1'}]
Is there any other way for me to get the data apart from what I have done above? Especially the line
chartWrapper.getDataTable().Wf[row].c
Having a property value hardcoded has broken my UI thrice in recent times and I would like to avoid doing so.
to my knowledge, the sankey chart will only allow you to select the nodes,
not the links between the nodes.
and this is only allowed after setting the interactivity option.
options: {
sankey: {
node: {
interactivity: true
}
}
}
the selection returns the name of the node selected,
which can appear in the data table multiple times.
in the following example, I've added an additional "P" node to demonstrate.
when the select event fires, you can get the name of the node selected from the chart's selection.
then you must search through the rows in the data table to find the row with the matching node name.
once you've found the data table row for the selected node name,
you can use data table method getValue to retrieve the values for that row.
see following working snippet...
google.charts.load('current', {
packages: ['controls', 'sankey']
}).then(function () {
var chartWrapper = new google.visualization.ChartWrapper({
chartType: 'Sankey',
containerId: 'chart',
dataTable: google.visualization.arrayToDataTable([
['From', 'To', 'Weight', {role: 'tooltip', type: 'string'}],
['A', 'P', 1, 'i111'],
['B', 'Q', 1, 'j333'],
['C', 'R', 1, 'k444'],
['P', 'X', 1, 'l555'],
['P', 'Y', 2, 'l555'],
['Q', 'Y', 1, 'l666'],
['R', 'Z', 1, 'n999']
]),
options: {
sankey: {
node: {
interactivity: true
}
}
}
});
google.visualization.events.addListener(chartWrapper, 'ready', function () {
google.visualization.events.addListener(chartWrapper.getChart(), 'select', selectEvent);
});
chartWrapper.draw();
function selectEvent() {
var chart = chartWrapper.getChart();
var data = chartWrapper.getDataTable();
var selection = chart.getSelection();
if (selection.length > 0) {
// find data table rows for selected node name
var nodeName = selection[0].name;
var nodeRows = data.getFilteredRows([{
column: 0,
value: nodeName
}]);
// find row values for selected node name
nodeRows.forEach(function (row) {
var valFrom = data.getValue(row, 0);
var valTo = data.getValue(row, 1);
var valWeight = data.getValue(row, 2);
var valTooltip = data.getValue(row, 3);
console.log(valFrom, valTo, valWeight, valTooltip);
});
}
}
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>

How to change the width of box in react-google-charts table?

Now, I have created table using - https://react-google-charts.com/table-chart#simple-example.
But I am unable to change the width of box using react.
I have found the documentation of Bar-format using JavaScript - https://developers.google.com/chart/interactive/docs/reference#barformat
Could anyone please help me to solve this ?
export default class App4 extends React.Component {
render() {
return (
<div className={"todo-item2"}>
<Chart
width={'500px'}
height={'300px'}
chartType="Table"
loader={<div>Loading Chart</div>}
data={[
[
{ type: 'string', label: 'DATE' },
{ type: 'string', label: 'GAME - 1' },
{ type: 'string', label: 'GAME - 2' },
{ type: 'string', label: 'GAME - 3' },
],
['2020-04-01', 'Team A (Home) vs Team B (Visitor)', 'Team C (Home) vs Team D (Visitor)', 'Team E (Home) vs Team F (Visitor)'],
['2020-04-02', 'Team F (Home) vs Team A (Visitor)', 'Team D (Home) vs Team C (Visitor)', 'Team F (Home) vs Team B (Visitor)'],
['2020-04-03', 'Team B (Home) vs Team A (Visitor)', 'Team C (Home) vs Team D (Visitor)', 'Team F (Home) vs Team E (Visitor)'],
]}
options={{
showRowNumber: false,
width: '10000px',
//height: '500px',
}}
rootProps={{ 'data-testid': '1' }}
/>
</div>
);
}
}
ReactDOM.render(<App4 />, document.getElementById("root"));
Please see the image
use the following config options to change the width,
or any other style of the table cells.
first, we must include...
allowHtml: true
next, we assign a css class name to the table cells...
cssClassNames: {
tableCell: 'game-cell'
}
e.g.
options={{
allowHtml: true,
cssClassNames: {
tableCell: 'game-cell'
},
showRowNumber: false,
}}
then we add the css class to the page somewhere,
either in a <style> tag, or in a separate css file using the <link> tag
.game-cell {
width: 400px;
}
if you want to assign a specific width to the cells, use the above css.
if you want to prevent wrapping to two lines, use the following...
.game-cell {
white-space: nowrap;
}

Unwanted scrollbar in column header of react-data-grid

Issue
In the header of my react-data-grid table, an unwanted scrollbar appears. This doesn't happen for most examples I ahve seen. The scrollbar is unnecessary and distracting.
I've found issues where people want to remove vertical scrollbars, but not one where it just affects the header. I definitely want to KEEP the vertical scrollbars for the data in row 2 and onwards (once it appears), but I do not want a separate little scrollbar in the header.
Example
Please see this codepen for a replication of the issue:
https://codesandbox.io/s/gracious-paper-7zo4u?file=/src/App.js:0-690
Code
import React from "react";
import ReactDataGrid from "react-data-grid"; // 6.1.0
const cols = [
{key: 'a', name: 'alpha', editable: false, sortable: false},
{key: 'b', name: 'beta', editable: false, sortable: false}
];
const data = [
{a: 1, b: 1},
{a: 2, b: 2},
{a: 3, b: 3}
];
class App extends React.Component {
onGridRowsUpdated = ({ fromRow, toRow, updated }) => {
console.log('CALLED >> onGridRowsUpdated');
};
render() {
return (
<ReactDataGrid
columns={cols}
rowGetter={i => data[i]}
rowsCount={data.length}
onGridRowsUpdated={this.onGridRowsUpdated}
enableCellSelect={true}
/>
);
}
}
export default App;
Picture
See right side of the header, it has a mini-scroll bar that is unwanted

applyTransaction remove not working with id

I'm using ag-grid in Angular9 project. I'm using Transactions to do CRUD operations in grid when my backend request resolve. I need to provide RowNodeId myself, i dont want to use object-references as i have large data set.
Thing is, i've provided the ID and i can add/update item in the grid but i'm unable to delete the item. In Doc it mentions, you only need to provide id to remove the item but i'm getting the following error.
Here's the code.
class HostAppListPage
{
#ViewChild('agGrid', {static: true}) grid:AgGridAngular;
constructor()
{
}
ngOnInit()
{
this.grid.getRowNodeId = (data) => {
return data.entityId;
};
this.columns = [
{headerName: 'App Name', field: 'name', rowDrag: true, headerCheckboxSelection: true, checkboxSelection: true},
{headerName: 'App Id', field: 'id'},
{headerName: 'Compatibility', field: COMPATIBILITY'},
{headerName: 'Creation', field: 'createdAtToString'},
{headerName: 'Last Update', field: 'updatedAtToString'}
];
}
deleteRow()
{
let ids = this.gridApi.getSelectedNodes()
// .map((row) => {
// return {id: row.entityId}
// return row.entityId;
// });
console.log(ids);
this.grid.api.applyTransaction({remove: ids});
}
I tried both with and without map statement, nothing worked
but my Add and Update works fine.
Replace map with following code.
.map((row) => {
return {entityId: row.data.entityId};
});
it should be the the same field (entityId) which i set in getRowNodeId function.
In a typical situation, where one does not define a getRowNodeId, one should be able to do:
const removeData: any[] = [{id: rowNode0.id}, {id: rowNode1.id}, ...];
applyTransaction({remove: removeData});
where rowNode0, rowNode1, etc. are the nodes you want to remove.
However when you provide your own getRowNodeId callback, ag-grid will fetch the id's by applying your callback on the data you provided. Therefore, the name(s) in the data must match those used in your callback. That's why return {id: row.entityId} doesn't work, but return {entityId: row.entityId} does.
In other words, if one defines:
this.grid.getRowNodeId = (data) => {
return data.column1 + data.column5 + data.column2;
};
Then one would need to provide
const removeData: any[] = [
{column1: 'a1', column2: 'b1', column5: 'c1'},
{column1: 'a2', column2: 'b2', column5: 'c2'},
{column1: 'a3', column2: 'b3', column5: 'c3'},
];
so that ag-grid would have all the names it needs to find the id's via the given getRowNodeId.

How to hide column in angular datatable excel export but show column on screen?

I have this code to enable the excel export button:
self.dtOptions = DTOptionsBuilder.newOptions()
.withButtons([
{
extend: 'excel',
text: 'Export to Excel',
title: 'banana report'
}]);
Previously I have used this code to hide the column in the datatable but have it show up in the excel:
self.dtColumnDefs = [
DTColumnDefBuilder.newColumnDef(11).notVisible()
];
But how can I do the opposite? How can I hide in excel but not the datatable?
Use exportOptions. For example
.withButtons([
{
extend: 'excel',
text: 'Export to Excel',
title: 'banana report',
exportOptions: {
columns: [ 0, 1, 6, 7 ]
}
}])
Will only export the specifed column indexes. See
https://datatables.net/extensions/buttons/examples/html5/columns.html
https://datatables.net/extensions/buttons/examples/print/columns.html