Spaces:
Running
Running
| $(document).ready(function () { | |
| var options = { | |
| slidesToScroll: 1, | |
| slidesToShow: 3, | |
| loop: true, | |
| infinite: true, | |
| autoplay: false, | |
| autoplaySpeed: 3000, | |
| }; | |
| // Initialize all div with carousel class | |
| var carousels = bulmaCarousel.attach('.carousel', options); | |
| // Loop on each carousel initialized | |
| for (var i = 0; i < carousels.length; i++) { | |
| // Add listener to event | |
| carousels[i].on('before:show', (state) => { | |
| console.log(state); | |
| }); | |
| } | |
| // Access to bulmaCarousel instance of an element | |
| var element = document.querySelector('#my-element'); | |
| if (element && element.bulmaCarousel) { | |
| // bulmaCarousel instance is available as element.bulmaCarousel | |
| element.bulmaCarousel.on('before-show', function (state) { | |
| console.log(state); | |
| }); | |
| } | |
| $.getJSON('./static/data/examples.json', function (examplesData) { | |
| const container = document.getElementById('qualitative-results-container'); | |
| if (container) { | |
| // Event delegation for toggle buttons | |
| container.addEventListener('click', function (e) { | |
| const btn = e.target.closest('.toggle-comparison-btn'); | |
| if (!btn) return; | |
| const targetId = btn.dataset.target; | |
| const content = document.getElementById(targetId); | |
| if (content) { | |
| // Use jQuery for smooth slide toggle | |
| $(content).slideToggle(300); | |
| const isCurrentlyVisible = $(content).is(':visible'); | |
| // If it is currently visible, it will be hidden, so we want "Show..." | |
| // If it is currently hidden, it will be shown, so we want "Hide..." | |
| const willBeVisible = !isCurrentlyVisible; | |
| const textSpan = btn.querySelector('span:first-child'); | |
| if (textSpan) { | |
| textSpan.textContent = willBeVisible ? 'Hide comparison' : 'Show comparison with other models'; | |
| } | |
| const iconSpan = btn.querySelector('.icon'); | |
| if (iconSpan) { | |
| iconSpan.style.transition = 'transform 0.3s'; | |
| iconSpan.style.transform = willBeVisible ? 'rotate(180deg)' : 'rotate(0deg)'; | |
| } | |
| } | |
| }); | |
| examplesData.forEach((example, index) => { | |
| const othersId = `others-${index}`; | |
| const othersHtml = example.others | |
| .map((other) => { | |
| const icon = other.status === 'success' ? 'check' : other.status === 'danger' ? 'x' : 'triangle-alert'; | |
| const iconClass = | |
| other.status === 'success' | |
| ? 'has-text-success' | |
| : other.status === 'danger' | |
| ? 'has-text-danger' | |
| : 'has-text-warning'; | |
| const note = other.note ? `<br/><small>${other.note}</small>` : ''; | |
| return ` | |
| <div class="notification is-${other.status} is-light"> | |
| <span class="tag is-${other.status}">${other.model}</span> | |
| <div class="is-flex is-align-items-center mt-1"> | |
| <span class="mr-2">"${other.text}"${note}</span> | |
| <i data-lucide="${icon}" class="${iconClass}" style="flex-shrink: 0;"></i> | |
| </div> | |
| </div> | |
| `; | |
| }) | |
| .join(''); | |
| const html = ` | |
| <div class="box"> | |
| <div class="columns is-vcentered"> | |
| <div class="column is-two-fifths"> | |
| <figure class="image"> | |
| <img src="${example.image}" alt="${example.alt}" /> | |
| </figure> | |
| <figcaption style="font-size: 0.875rem; color: gray; font-style: italic; text-align: center;"> | |
| ${example.source} | |
| </figcaption> | |
| </div> | |
| <div class="column"> | |
| <div class="notification is-info is-light"> | |
| <span class="tag is-info">Question</span> | |
| <p>${example.question}</p> | |
| </div> | |
| <div class="notification is-${example.ours.status} is-light"> | |
| <span class="tag is-${example.ours.status}">LLaVA-PLLuM-12B-nc (Ours)</span> | |
| <div class="is-flex is-align-items-center mt-1"> | |
| <span class="mr-2">"${example.ours.text}"</span> | |
| <i data-lucide="check" class="has-text-${example.ours.status}" style="flex-shrink: 0;"></i> | |
| </div> | |
| </div> | |
| <button class="button is-small is-ghost mt-2 toggle-comparison-btn" data-target="${othersId}"> | |
| <span>Show comparison with other models</span> | |
| <span class="icon"> | |
| <i data-lucide="chevron-down"></i> | |
| </span> | |
| </button> | |
| <div id="${othersId}" class="mt-4" style="display: none;"> | |
| ${othersHtml} | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| `; | |
| container.insertAdjacentHTML('beforeend', html); | |
| }); | |
| } | |
| lucide.createIcons(); | |
| }); | |
| // Scroll to top button logic | |
| const scrollToTopBtn = document.getElementById('scrollToTopBtn'); | |
| const rootElement = document.documentElement; | |
| function handleScroll() { | |
| const scrollTotal = rootElement.scrollHeight - rootElement.clientHeight; | |
| if (rootElement.scrollTop / scrollTotal > 0.1) { | |
| // Show button | |
| scrollToTopBtn.style.display = 'block'; | |
| } else { | |
| // Hide button | |
| scrollToTopBtn.style.display = 'none'; | |
| } | |
| } | |
| function scrollToTop() { | |
| rootElement.scrollTo({ | |
| top: 0, | |
| behavior: 'smooth', | |
| }); | |
| } | |
| if (scrollToTopBtn) { | |
| scrollToTopBtn.addEventListener('click', scrollToTop); | |
| document.addEventListener('scroll', handleScroll); | |
| } | |
| // Smooth scrolling for TOC links | |
| document.querySelectorAll('.menu-list a[href^="#"]').forEach((anchor) => { | |
| anchor.addEventListener('click', function (e) { | |
| e.preventDefault(); | |
| const targetId = this.getAttribute('href'); | |
| const targetSection = document.querySelector(targetId); | |
| if (targetSection) { | |
| targetSection.scrollIntoView({ | |
| behavior: 'smooth', | |
| }); | |
| } | |
| }); | |
| }); | |
| // ScrollSpy for TOC | |
| window.addEventListener('scroll', function () { | |
| const fromTop = window.scrollY + 150; | |
| let currentSectionId = ''; | |
| document.querySelectorAll('.menu-list a[href^="#"]').forEach((link) => { | |
| const targetId = link.getAttribute('href'); | |
| if (targetId === '#') return; | |
| const section = document.querySelector(targetId); | |
| if (section) { | |
| if (section.offsetTop <= fromTop) { | |
| currentSectionId = targetId; | |
| } | |
| } | |
| }); | |
| document.querySelectorAll('.menu-list a').forEach((link) => { | |
| link.classList.remove('is-active'); | |
| if (link.getAttribute('href') === currentSectionId) { | |
| link.classList.add('is-active'); | |
| } | |
| }); | |
| }); | |
| // Chart.js initialization for Training Data Distribution | |
| const chartCtx = document.getElementById('trainingDataChart'); | |
| if (chartCtx) { | |
| new Chart(chartCtx, { | |
| type: 'doughnut', | |
| data: { | |
| datasets: [ | |
| { | |
| // Outer Ring: Datasets | |
| data: [454000, 150000, 145000, 142000, 15000, 390000, 500000, 100000, 104000], | |
| backgroundColor: [ | |
| '#62bdfc', // ALLaVA | |
| '#85cffa', // LLaVA-Instruct | |
| '#a8e1ff', // Q-Instruct | |
| '#cbf2ff', // LVIS-Instruct4V | |
| '#e6f9ff', // A-OKVQA | |
| '#6bf295', // WIT (Green) | |
| '#ff7592', // SynthDoG-PL | |
| '#ffb3c4', // SynthDoG-EN | |
| '#ffe58f', // TallyQA (Yellow) | |
| ], | |
| labels: [ | |
| 'ALLaVA', | |
| 'LLaVA-Instruct', | |
| 'Q-Instruct', | |
| 'LVIS-Instruct4V', | |
| 'A-OKVQA', | |
| 'WIT', | |
| 'SynthDoG-PL', | |
| 'SynthDoG-EN', | |
| 'TallyQA', | |
| ], | |
| borderWidth: 0, | |
| }, | |
| { | |
| // Inner Ring: Categories | |
| data: [906000, 390000, 600000, 104000], | |
| backgroundColor: [ | |
| '#209cee', // General | |
| '#23d160', // Knowledge (Green) | |
| '#ff3860', // OCR | |
| '#ffdd57', // Counting (Yellow) | |
| ], | |
| labels: ['General', 'Knowledge', 'OCR', 'Counting'], | |
| borderWidth: 0, | |
| }, | |
| ], | |
| }, | |
| options: { | |
| responsive: true, | |
| maintainAspectRatio: true, | |
| aspectRatio: 2.75, | |
| events: [], // Disable all interactions | |
| plugins: { | |
| legend: { | |
| position: 'right', | |
| align: 'center', | |
| onClick: null, // Disable legend click | |
| labels: { | |
| usePointStyle: true, | |
| padding: 15, | |
| generateLabels: function (chart) { | |
| const data = chart.data; | |
| const datasets = data.datasets[0]; // Outer ring (datasets) | |
| let legendItems = []; | |
| // Define the structure: Category Name -> Dataset Indices | |
| const structure = [ | |
| { category: 'General', indices: [0, 1, 2, 3, 4] }, | |
| { category: 'Knowledge', indices: [5] }, | |
| { category: 'OCR', indices: [6, 7] }, | |
| { category: 'Counting', indices: [8] }, | |
| ]; | |
| structure.forEach((group, groupIndex) => { | |
| // Add Category Header | |
| legendItems.push({ | |
| text: group.category, | |
| fillStyle: 'rgba(0,0,0,0)', | |
| strokeStyle: 'rgba(0,0,0,0)', | |
| lineWidth: 0, | |
| hidden: false, | |
| index: -1, | |
| fontColor: '#363636', | |
| }); | |
| // Add Datasets for this category | |
| group.indices.forEach((index) => { | |
| const value = datasets.data[index]; | |
| const valueK = Math.round(value / 1000) + 'K'; | |
| const label = `${datasets.labels[index]} (${valueK})`; | |
| legendItems.push({ | |
| text: label, | |
| fillStyle: datasets.backgroundColor[index], | |
| strokeStyle: datasets.backgroundColor[index], | |
| hidden: false, | |
| index: index, | |
| datasetIndex: 0, | |
| pointStyle: 'circle', | |
| }); | |
| }); | |
| }); | |
| return legendItems; | |
| }, | |
| }, | |
| }, | |
| tooltip: { | |
| enabled: false, | |
| }, | |
| }, | |
| animation: false, | |
| }, | |
| }); | |
| } | |
| }); | |