@steftsotras not sure what is not working since you have not supplied any code. But the following for me works where I load jQuery
in templates/index.html
. I have added a check in download.js
that jQuery
is loaded. But I do not know what you mean by external JS: external from a CDN or installed locally?
├── main.py
├── salary_data.csv
├── static/js
│ └── download.js
├── templates
│ └── index.html
main.py
''' A column salary chart with minimum and maximum values.
This example shows the capability of exporting a csv file from ColumnDataSource.
'''
from os.path import dirname, join
import pandas as pd
from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import (Button, ColumnDataSource, CustomJS, DataTable,
NumberFormatter, RangeSlider, TableColumn)
df = pd.read_csv(join(dirname(__file__), 'salary_data.csv'))
source = ColumnDataSource(data=dict())
def update():
current = df[(df['salary'] >= slider.value[0]) & (df['salary'] <= slider.value[1])].dropna()
source.data = {
'name' : current.name,
'salary' : current.salary,
'years_experience' : current.years_experience,
}
slider = RangeSlider(title="Max Salary", start=10000, end=110000, value=(10000, 50000), step=1000, format="0,0")
slider.on_change('value', lambda attr, old, new: update())
button = Button(label="Download", button_type="success")
button.js_on_event(
"button_click",
CustomJS(
args = dict(source=source),
code = open(join(dirname(__file__), "static/js", "download.js")).read()
)
)
columns = [
TableColumn(field="name", title="Employee Name"),
TableColumn(field="salary", title="Income", formatter=NumberFormatter(format="$0,0.00")),
TableColumn(field="years_experience", title="Experience (years)")
]
data_table = DataTable(source=source, columns=columns, width=800)
controls = column(slider, button)
curdoc().add_root(row(controls, data_table))
curdoc().title = "Export CSV"
update()
index.html
{% extends base %}
{% block preamble %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
{% endblock %}
{% block postamble %}
<style>
h1 {
margin: 2em 0 0 0;
color: #2e484c;
font-family: 'Julius Sans One', sans-serif;
font-size: 1.4em;
text-transform: uppercase;
}
p {
font: "Libre Baskerville", sans-serif;
text-align: justify;
text-justify: inter-word;
}
</style>
{% endblock %}
{% block contents %}
<div>
<h1>Export data to CSV</h1>
<p> This demo uses a <code>CustomJS</code> callback to export <code>DataTable</code> contents to CSV.
<p><b>NOTE</b>: On Safari the CSV will open in a new tab, rather than downloading.</p>
<ul style="list-style-type:circle">
<li>Scrub the "Max Salary" slider and watch the <code>DataTable</code> change.</li>
<li>Click the "Download" button to export data to a CSV file.</li>
</ul>
</div>
{{ super() }}
{% endblock %}
download.js
function table_to_csv(source) {
const columns = Object.keys(source.data)
const nrows = source.get_length()
const lines = [columns.join(',')]
for (let i = 0; i < nrows; i++) {
let row = [];
for (let j = 0; j < columns.length; j++) {
const column = columns[j]
row.push(source.data[column][i].toString())
}
lines.push(row.join(','))
}
return lines.join('\n').concat('\n')
}
const filename = 'data_result.csv'
const filetext = table_to_csv(source)
const blob = new Blob([filetext], { type: 'text/csv;charset=utf-8;' })
//addresses IE
if (navigator.msSaveBlob) {
navigator.msSaveBlob(blob, filename)
} else {
const link = document.createElement('a')
link.href = URL.createObjectURL(blob)
link.download = filename
link.target = '_blank'
link.style.visibility = 'hidden'
link.dispatchEvent(new MouseEvent('click'))
}
if (typeof jQuery != 'undefined') {
alert("jQuery library is loaded!");
}else{
alert("jQuery library is not found!");
}