Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Colourful ModFill #501

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions doc/pull-request-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ The PR submitter should:

## For PR reviewers

- The new code is readable, meets our principles, and of good quality.
- All new or changed features are appropriately documented.
- Tests are appropriately modified for all new or changed features. If it is
a bugfix PR there must be at least one new test. Most other PRs should
Expand All @@ -53,7 +54,11 @@ The PR submitter should:
reviewer, but a number of possible actions that seem related to the
changes in the PR must definitely be tried in this fashion before
approving for merge.
- At the end of the review process, before merging, add a commit to update
the
["Contributors" section of the "About" document](about.md#contributors) to
include the submitter's name, if it is not already present.
- In particular, if there is a new or significantly altered visualizer or
sequence, running it on a sequence with (say) a million entries (but not
infinitely many, since that case is more typically caught) does not
hang/block the browser.

At the end of the review process, before merging, add a commit to update the
["Contributors" section of the "About" document](about.md#contributors) to
include the submitter's name, if it is not already present.
14 changes: 14 additions & 0 deletions doc/visualizer-basics.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,20 @@ Sequence information is found in `this.seq`. This is a `SequenceInterface`
object, so it will always have a method `getElement(n)` that returns the `n`th
entry in the sequence.

It's important to realize that while your `draw()` method is operating, the
browser can't do anything else. So it's important to limit how much
computation you do in any one call to `draw()`. That's why you're encouraged
to do animations that just change things somewhat on each frame. For example,
if you are doing a visualization that involves summary statistics on the
values of a sequence (maybe it computes their mean and standard deviation),
don't try to compute all the entries of a sequence that might conceivably have
millions of entries in a single call to `draw()`. Instead think about using an
[incremental algorithm](https://math.stackexchange.com/questions/102978) for
computing these statistics, and add a hundred or so terms on each frame, and
progressively display on each frame the summary of what you've processed so
far. You'll often find that animation tells you more about the sequence than
the single final summary would have, anyway.

You have to implement the `draw()` method, even if it does nothing. Your
visualizer can't be loaded into Numberscope without it. The
`P5VisualizerTemplate` uses `draw()` to write the value of the current entry
Expand Down
6 changes: 6 additions & 0 deletions doc/visualizer-in-depth.md
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,12 @@ you: return `true` if you have handled any need to reset (and so the framework
should NOT call `reset()`), and false if you do want the framework to
`reset()`.

### Draw your visualization

The P5Visualizer provides a utility method `hatchRect(x, y, w, h)` that draws
a rectangle with corner at (x, y) and width w and height h, filled with
diagonal hatch lines.

### Show or stop the visualization; depart from a page element

You shouldn't frequently need to implement `show()`, `stop()`, or `depart()`.
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions e2e/tests/gallery.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ test.describe('Gallery', () => {
await page.locator('.card-body >> nth=2').click()
await expect(page.url()).not.toContain('gallery')
await expect(
await page.locator('#sequenceTab .item-name').innerText()
).toMatch('Formula: 12')
await page.locator('#sequenceTab .item-name')
).toContainText(/12$/)
await expect(
await page.locator('#visualiserTab .item-name').innerText()
).toMatch('Mod Fill')
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 4 additions & 2 deletions e2e/tests/scope.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,13 @@ test.describe('Scope: on some featured visualization', () => {
})

test('Changing a sequence', async ({page}) => {
const lookFor = 'Random'
const andThenFind = 'Random integers 0 to 9'
await page.locator('#sequenceTab .visualizer-info').click()
await page.locator('.results .card-body').first().click()
await page.getByText(lookFor, {exact: true}).click()
await expect(
await page.locator('#sequenceTab .item-name').innerText()
).toMatch('Formula: n')
).toMatch(andThenFind)
})

test('minimizing a tab', async ({page}) => {
Expand Down
490 changes: 246 additions & 244 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,12 @@
"axios": "^1.6.8",
"bigint-isqrt": "^0.3.2",
"bigint-mod-arith": "^3.3.1",
"dompurify": "^3.2.1",
"interactjs": "^1.10.27",
"p5": "^1.11.0",
"p5.brush": "^1.1.2",
"vue": "^3.4.31",
"vue-router": "^4.4.0"
"temml": "^0.10.31",
"vue": "^3.5.13",
"vue-router": "^4.4.5"
},
"devDependencies": {
"@eslint/js": "^9.10.0",
Expand Down
11 changes: 7 additions & 4 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@

<script setup lang="ts">
import {RouterView} from 'vue-router'

import {reactivateOEIS} from '@/sequences/sequences'

reactivateOEIS()
</script>

<!-- Global styles. This style tag is explicitly unscoped. -->
Expand Down Expand Up @@ -43,6 +39,12 @@
margin: 0;
padding: 0;
}
math {
display: inline-flex;
align-items: baseline;
flex-wrap: wrap;
row-gap: 6px;
}
:root {
/* Font sizes */
--ns-size-body: 12px;
Expand All @@ -60,6 +62,7 @@
/* Colors */
--ns-color-primary: #809fff;
--ns-color-white: #ffffff;
--ns-color-pale: #e5e5e5;
--ns-color-light: #b5b5b5;
--ns-color-grey: #636363;
--ns-color-black: #2f2f2f;
Expand Down
Binary file added src/assets/img/ModFill/DanceNo73.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/ModFill/OEISA070826.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/img/ModFill/PrimeResidues.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 80 additions & 0 deletions src/components/BasicToggleSwitch.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template>
<div
class="toggle-switch"
:class="{checked: modelValue}"
@click="toggle" />
</template>

<script setup lang="ts">
// Thanks for this component go to:
// https://skirtles-code.github.io/vue-examples/components/toggle-switch

const props = defineProps({
modelValue: {
required: true,
type: Boolean,
},
})

const emit = defineEmits(['update:modelValue'])

const toggle = () => {
emit('update:modelValue', !props.modelValue)
}
</script>

<style scoped>
.toggle-switch {
background: #ddd;
border-radius: 0.75em;
box-shadow: 0.0625em 0.0625em 0.0625em rgba(0, 0, 0, 0.08) inset;
cursor: pointer;
flex: none;
height: 1.5em;
position: relative;
transition: background-color 150ms;
width: 3em;
}

.toggle-switch::before {
background: #fff;
background-image: radial-gradient(
circle at 0.375em 0.375em,
rgba(0, 0, 0, 0) 0,
rgba(0, 0, 0, 0.05) 1em
);
border-radius: 0.625em;
box-shadow: 0.0625em 0.0625em 0.0625em rgba(0, 0, 0, 0.08);
content: '';
display: block;
height: 1.25em;
left: 0.125em;
position: absolute;
top: 0.125em;
transition: left 150ms;
width: 1.25em;
will-change: left;
}

.checked::before {
background-image: radial-gradient(
circle at 0.375em 0.375em,
rgba(0, 0, 0, 0) 0,
rgba(0, 0, 0, 0.05) 1em
);
left: 1.625em;
}

.toggle-switch:hover {
box-shadow: 0.0625em 0.0625em 0.125em rgba(0, 0, 0, 0.12) inset;
}

.toggle-switch:hover::before {
background-image: radial-gradient(
circle at 0.375em 0.375em,
rgba(0, 0, 0, 0) 0,
rgba(0, 0, 0, 0.0375) 1em
);
box-shadow: 0.0625em 0.0625em 0.0625em rgba(0, 0, 0, 0.12);
}
</style>
5 changes: 2 additions & 3 deletions src/components/ParamEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@
@click="openSwitcher">
<div class="visualizer-info" style="flex-grow: 1">
<h1>Current {{ title }}</h1>
<div class="item-name">
{{ paramable.name
}}<a
<div ref="itemName" class="item-name">
<span v-safe-html="paramable.htmlName" /><a
v-if="paramable.name.match(/A\d{6}\s*$/)"
:href="oeisLinkFor(paramable.name)"
target="_blank"
Expand Down
8 changes: 2 additions & 6 deletions src/components/SpecimenBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,11 @@
@click="refresh">
refresh
</div>
<!-- eslint-disable vue/no-v-html -->
<!-- Note: as playPause is either 'play' or 'pause', it is
definitely safe. -->
<div
id="pause-button"
v-safe-html="playPause"
class="button material-icons-sharp"
@click="togglePause"
v-html="playPause" />
<!--eslint-enable-->
@click="togglePause" />
<div
id="share-button"
class="button material-icons-sharp"
Expand Down
68 changes: 29 additions & 39 deletions src/components/SpecimenCard.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,15 @@
<template>
<div :id="`SC-${specimenName}`" class="card-body" @click="openSpecimen">
<Thumbnail :query />
<div :id="spec.id || cid" class="card-body" @click="openSpecimen">
<Thumbnail :query="spec.query" />
<div class="card-title-box">
<div>
<h5 class="card-title">
{{ specimenName
}}<a
v-if="specimenName.match(/A\d{6}\s*$/)"
:href="oeisLinkFor(specimenName)"
target="_blank"
@click.stop>
<div class="info material-icons-sharp external">
launch
</div>
</a>
<SpecimenTitle :spec />
</h5>
<p class="card-text">
{{ useSub }}
</p>
<p v-safe-html="spec.subtitle" class="card-text" />
</div>
<div
v-if="!permanent"
v-if="spec.canDelete"
style="padding-right: 15px"
@click.stop="deleteSpecimen">
<span class="delete-button material-icons-sharp">
Expand All @@ -33,52 +22,53 @@

<script lang="ts">
import {defineComponent} from 'vue'
import {Specimen} from '../shared/Specimen'
import {
deleteSpecimen,
nameOfQuery,
oeisLinkFor,
} from '../shared/browserCaching'
import type {PropType} from 'vue'

import SpecimenTitle from './SpecimenTitle.vue'
import Thumbnail from './Thumbnail.vue'

import {addSequence} from '@/shared/browserCaching'
import {parseSpecimenQuery} from '@/shared/specimenEncoding'

export interface CardSpecimen {
query: string
id?: string // defaults to SC-NNNN, autogenerated serial number NNNN
title?: string // defaults to the name encoded in the query
subtitle: string
lastEdited?: string
canDelete?: boolean // if not present defaults to false
}

let cid_count = 0

export default defineComponent({
name: 'SpecimenCard',
components: {
SpecimenTitle,
Thumbnail,
},
props: {
query: {type: String, required: true},
lastEdited: {type: String, default: ''},
subtitle: {type: String, default: ''},
permanent: {type: Boolean},
spec: {type: Object as PropType<CardSpecimen>, required: true},
cid: {
type: String,
default: function () {
return 'Card-' + cid_count++
return 'SC-' + cid_count++
},
},
},
emits: ['specimenDeleted', 'selected'],
data() {
return {specimenName: '', useSub: ''}
},
mounted() {
this.specimenName = nameOfQuery(this.query)
if (this.subtitle) this.useSub = this.subtitle
else this.useSub = Specimen.getSequenceNameFromQuery(this.query)
},
methods: {
openSpecimen() {
this.$router.push(`/?${this.query}`)
const {sequenceKind, sequenceQuery} = parseSpecimenQuery(
this.spec.query
)
addSequence(sequenceKind, sequenceQuery)
this.$router.push(`/?${this.spec.query}`)
this.$emit('selected')
},
deleteSpecimen() {
deleteSpecimen(this.specimenName)
this.$emit('specimenDeleted', this.specimenName)
this.$emit('specimenDeleted')
},
oeisLinkFor,
},
})
</script>
Expand Down
Loading