Skip to content
This repository has been archived by the owner on Jun 4, 2024. It is now read-only.

Issue 596 - Add Markdown presentation #606

Merged
merged 49 commits into from
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation #606

merged 49 commits into from
Jan 7, 2020

Conversation

Marc-Andre-Rivet
Copy link
Contributor

@Marc-Andre-Rivet Marc-Andre-Rivet commented Sep 30, 2019

Fixes #596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
@shammamah-zz shammamah-zz force-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4 Compare December 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz shammamah-zz force-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fb Compare December 3, 2019 20:06
Copy link
Contributor Author

@Marc-Andre-Rivet Marc-Andre-Rivet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();
Copy link
Contributor Author

@Marc-Andre-Rivet Marc-Andre-Rivet Dec 5, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

    private static md: Remarkable = new Remarkable({
        highlight: (value: string, language: string) => {
            const hljs: any = (window as any).hljs;

            if (!hljs) {
                return '';
            }

            if (language && hljs.getLanguage(language)) {
                try {
                    return hljs.highlight(language, value).value;
                } catch (_) { }
            }

            try {
                return hljs.highlightAuto(value).value;
            } catch (_) { }

            return '';
        }
    });

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;
Copy link
Contributor Author

@Marc-Andre-Rivet Marc-Andre-Rivet Dec 17, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.

@@ -23,14 +23,14 @@ declare module 'fast-isnumeric' {
}

declare class Remarkable {
constructor();
constructor(options?: any);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

render(value: string): any;
}

declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;
Copy link
Contributor Author

@Marc-Andre-Rivet Marc-Andre-Rivet Dec 19, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

tslint.json Outdated
@@ -9,6 +9,7 @@
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz shammamah-zz force-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409 Compare December 20, 2019 20:43
@shammamah-zz shammamah-zz force-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831 Compare December 23, 2019 20:52
@Marc-Andre-Rivet
Copy link
Contributor Author

Marc-Andre-Rivet commented Jan 7, 2020

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable

app = dash.Dash(__name__)

data=[
    dict(a=1, b='''```javascript
return 20;```
'''),
    dict(a=1, b='''```js
console.log(\'pouet\');
        '''),
    dict(a=1, b='```js console.log(\'pouet\'); ```'),
    dict(a=1, b='```js console.log(\'pouet\'); ```'),
    dict(a=1, b='```js console.log(\'pouet\'); ```')
]

app.layout = Div([
    DataTable(
        columns=[
            dict(name='a', id='a', editable=True),
            dict(name='b', id='b', type='text', presentation='markdown')
        ],
        data=data,
        editable=False
    ),
    DataTable(
        columns=[
            dict(name='a', id='a'),
            dict(name='b', id='b', type='text', presentation='markdown')
        ],
        data=data,
        editable=False
    ),
])

app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet Marc-Andre-Rivet merged commit bbe12fe into dev Jan 7, 2020
@Marc-Andre-Rivet Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana
Copy link

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells
3 participants