Is there any widget equivalent to a carousel?

Hi guys,

I think it’s all in the question, I’m looking for a widget that will look like a carousel(to scroll through images).
Do you guys have heard about it, or already implemented it ?
Thanks in advance.

Looking at it.

Hi @Adam

A starting point would be something like the below. Could you try it out and post a Feature Request for what you need on Github?

import param

import panel as pn
from panel.layout.base import NamedListLike
from panel.reactive import ReactiveHTML
import altair as alt
from vega_datasets import data

pn.extension("ace", sizing_mode="stretch_width", template="fast")


# ReactiveHTML: https://panel.holoviz.org/user_guide/Custom_Components.html#reactivehtml-components
# SplideJS: https://splidejs.com/
class Carrousel(ReactiveHTML, NamedListLike):
    objects = param.List()

    _template = """
<style>
.splide__slide{
  text-align: center;
}
</style>
<div id="splide" style="height:100%;width:100%;">
  <div class="splide__track" style="height:100%;width:100%;">
		<ul class="splide__list">
            {% for object in objects %}
			<li id="slide" class="splide__slide">${object}</li>
			{% endfor %}
		</ul>
  </div>
</div>
"""
    _scripts = {
        "render": """
new Splide( splide ).mount();      
"""
    }

    __javascript__ = ["https://cdn.jsdelivr.net/npm/@splidejs/splide@3.6.12/dist/js/splide.min.js"]
    __css__ = [
        "https://cdn.jsdelivr.net/npm/@splidejs/splide@3.6.12/dist/css/splide.min.css",
        "https://cdn.jsdelivr.net/npm/@splidejs/splide@3.6.12/dist/css/splide-core.min.css",
        "https://cdn.jsdelivr.net/npm/@splidejs/splide@3.6.12/dist/css/themes/splide-default.min.css",
    ]

    def __init__(self, *objects, **params):
        NamedListLike.__init__(self, *objects, **params)
        ReactiveHTML.__init__(self, objects=self.objects, **params)

    @property
    def _child_names(self):
        return {"objects": self._names}

png_url = "https://discourse.holoviz.org/uploads/default/original/2X/d/df522eab6aa981cc034faae4bd31d366a8e669b5.png"
png = pn.pane.PNG(png_url, embed=False)
answer_text = """
NO

BUT YOU CAN EASILY BUILD ONE WITH REACTIVEHTML!

LETS TRY IT WITH AN ALTAIR PLOT AND A TERMINAL!
"""

answer = pn.pane.Markdown(answer_text, style={"font-size": "40px"})

def get_altair_plot():

    source = data.movies.url

    pts = alt.selection(type="single", encodings=['x'])

    rect = alt.Chart(data.movies.url).mark_rect().encode(
        alt.X('IMDB_Rating:Q', bin=True),
        alt.Y('Rotten_Tomatoes_Rating:Q', bin=True),
        alt.Color('count()',
            scale=alt.Scale(scheme='greenblue'),
            legend=alt.Legend(title='Total Records')
        )
    )

    circ = rect.mark_point().encode(
        alt.ColorValue('grey'),
        alt.Size('count()',
            legend=alt.Legend(title='Records in Selection')
        )
    ).transform_filter(
        pts
    )

    bar = alt.Chart(source).mark_bar().encode(
        x='Major_Genre:N',
        y='count()',
        color=alt.condition(pts, alt.ColorValue("steelblue"), alt.ColorValue("grey"))
    ).properties(
        width=550,
        height=200
    ).add_selection(pts)

    plot = alt.vconcat(
        rect + circ,
        bar
    ).resolve_legend(
        color="independent",
        size="independent"
    )
    return plot

plot = pn.pane.Vega(get_altair_plot())

terminal = pn.widgets.Terminal(
    "Welcome to the Panel Terminal!\nI'm based on xterm.js\n\nPython 🐍  Panel ❤️   SplideJS 😊 \n",
    options={"cursorBlink": True},
    height=300, width=300,
)


Carrousel(png, answer, plot, terminal, height=800).servable()

accent = "#FF8896"
pn.state.template.param.update(
    site="Awesome Panel DataApp",
    title="Custom Carousel",
    accent_base_color=accent,
    header_background=accent,
)
1 Like