Skip to content

Commit

Permalink
first draft using @sndcds/mvc
Browse files Browse the repository at this point in the history
  • Loading branch information
roaldchristesen committed Oct 2, 2023
1 parent c4a5f2b commit 5a6f387
Show file tree
Hide file tree
Showing 17 changed files with 535 additions and 309 deletions.
13 changes: 13 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Model from './lib/model.js'
import View from './lib/view.js'
import Router from './lib/router.js'
import Controller from './lib/controller.js'
import Component from './lib/component.js'

export {
Model,
View,
Router,
Controller,
Component
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"staticPath": "static"
},
"dependencies": {
"@sndcds/mvc": "^0.0.8"
"@sndcds/mvc": "^0.0.31"
},
"devDependencies": {
"@parcel/config-default": "^2.9.3",
Expand Down
8 changes: 4 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 68 additions & 3 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { View, Controller, Component, Router } from '@sndcds/mvc'
import { View, Controller } from '@sndcds/mvc'


export default class App extends Controller {
/* eslint no-useless-constructor: 0 */
constructor(model, view) {
super(model, view)

this.onDistrictChanged = this.onDistrictChanged.bind(this) // TODO: Description!
}

initApp(url, id) {
Expand All @@ -17,12 +20,74 @@ export default class App extends Controller {
this.model.setDistrictId(this.districtId)
}

// test if data was found in local storage
if (this.data === null) {
this.fetchData(url)
}
else {
// this.state.onDataChanged(this.data)
this.onDataChanged(this.data)
}
}

renderAgeSection() {
const items = [
{ 'id': 'age-view-1', 'path': ['district_detail', '2021', 'age_groups', 'age_to_under_18'] },
{ 'id': 'age-view-2', 'path': ['district_detail', '2021', 'age_groups', 'age_18_to_under_30'] },
{ 'id': 'age-view-3', 'path': ['district_detail', '2021', 'age_groups', 'age_30_to_under_45'] },
{ 'id': 'age-view-4', 'path': ['district_detail', '2021', 'age_groups', 'age_45_to_under_65'] },
{ 'id': 'age-view-5', 'path': ['district_detail', '2021', 'age_groups', 'age_65_to_under_80'] },
{ 'id': 'age-view-6', 'path': ['district_detail', '2021', 'age_groups', 'age_80_and_above'] },
{ 'id': 'age-view-7', 'path': ['district_detail', '2021', 'age_groups', 'age_0_to_under_7'] },
{ 'id': 'age-view-8', 'path': ['district_detail', '2021', 'age_groups', 'age_60_and_above'] }
]

let sum = 0
items.forEach((item) => {
sum += this.getNestedValue(this.model.districtObject, item.path)
})

let barOffset = 0
items.forEach((item) => {
const c = this.componentById(item.id)
const d = this.getNestedValue(this.model.districtObject, item.path)
const percentage = d / sum * 100
c.setProperties(
{
'value': this.formatNumber(d),
'percentage': this.formatNumber(percentage),
barOffset
})
barOffset += percentage
})
}

onDataChanged(data) {
this.model.setDataObject(data)
this.model.setDistrictObject(this.model.districtId)

const d = { 'data': this.model.data, 'districtId': this.model.districtId }
const c = this.componentById('district-select')
c.setWithData(d)
c.bindDistrictChanged(this.onDistrictChanged)

this.renderAgeSection()
}

onDistrictChanged(id) {
this.model.setDistrictId(id + 1)
this.model.setDistrictObject(id + 1)

this.renderAgeSection()
}

/**
* Generates a random RGB color.
*
* @returns {string} A random RGB color string.
*/
static randomColor() {
const red = Math.floor(Math.random() * 256)
const green = Math.floor(Math.random() * 256)
const blue = Math.floor(Math.random() * 256)
return `rgb(${red}, ${green}, ${blue})`
}
}
3 changes: 1 addition & 2 deletions src/appModel.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { Model } from '@sndcds/mvc'


export default class AppModel extends Model {
constructor() {
super()

// override library defaults
this.data = null
this.districtNames = null
this.districtObject = null
Expand Down
40 changes: 40 additions & 0 deletions src/components/button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { Component } from '@sndcds/mvc'


export default class Button extends Component {
constructor(parent, id, setupData) {
super(parent, id, setupData)

this.label = 'Button'
this.onClick = undefined

this.setProperties(setupData)
}

defaultClass() {
return 'custom-button'
}

propertyNames() {
const names = [
'label', 'onClick'
]
return super.propertyNames(names)
}

propertiesChanged() {
if (this.e !== null) {
this.e.innerText = this.label
}
}

build() {
this.e = this.addDomElement('button')
this.e.innerText = this.label

this.buildChilds()

this.e.addEventListener('click', () => this.onClick(this))
// this.e.addEventListener('click', this.onClick)
}
}
18 changes: 14 additions & 4 deletions src/testcomponent.js → src/components/demoComponent.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import { Component } from '@sndcds/mvc'

export default class TestComponent extends Component {
/* eslint no-useless-constructor: 0 */

export default class DemoComponent extends Component {
constructor(parent, id, setupData) {
super(parent, id, setupData)
this.demoProperty = 0

this.setProperties(setupData)
}

defaultClass() {
return 'custom-demo-component'
}

propertyNames() {
return super.propertyNames(['demoProperty'])
}

setMessage(message) {
Expand All @@ -20,10 +31,9 @@ export default class TestComponent extends Component {
}

build() {
this.e = this.domCreateElement('p')
this.e = this.addDomElement('p')
this.e.innerText = 'Hello'
this.e.style.backgroundColor = '#999'
this.parent.e.appendChild(this.e)
this.buildChilds()
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import { Component } from '@sndcds/mvc'

export default class DistrictSelectComponent extends Component {
/* eslint no-useless-constructor: 0 */

export default class DistrictSelect extends Component {
constructor(parent, id, setupData) {
super(parent, id, setupData)
this.setProperties(setupData)
}

defaultClass() {
return 'custom-district-select'
}

propertyNames() {
return super.propertyNames()
}

build() {
this.e = this.domCreateElement('div')
this.parent.e.appendChild(this.e)
this.e = this.addDomElement('div')
}

setProperties(data) {
console.trace()
setWithData(data) {
const selectElement = this.domCreateElement('select')

data.data.forEach((item) => {
Expand Down
19 changes: 19 additions & 0 deletions src/components/grid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Component } from '@sndcds/mvc'


export default class Grid extends Component {
constructor(parent, id, setupData) {
super(parent, id, setupData)
this.setProperties(setupData)
}

defaultClass() {
return 'sc-grid'
}

build() {
this.e = this.addDomElement('div')
this.e.style.display = 'grid'
this.buildChilds()
}
}
102 changes: 102 additions & 0 deletions src/components/numPercentView.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { Component } from '@sndcds/mvc'


/**
* Component for displaying a label, value, bar and percentage.
* Can be used for displaying numeric information, i. e. of statistics and other number related contexts.
*
* @since 20.9.2023
*/
export default class NumPercentView extends Component {
/**
* Create a NumPercentView.
*
* @param {Component} parent - The parent component.
* @param {String} id - The id of the new Component.
* @param {any} setupData - Optional set up data.
*/
constructor(parent, id, setupData) {
super(parent, id, setupData)
this.label = 'Label'
this.value = 100
this.percentage = 10
this.barOffset = 0
this.barColor1 = '#999'
this.barColor2 = '#333'

this.setProperties(setupData)
}

defaultClass() {
return 'custom-num-percent'
}

/**
* Build the DOM Elements for HTML rendering og the component.
*
* This method mus be overridden in derived classes.
*
* Styling:
* One solution is to assign classes to the emelemts.
*/
build() {
this.e = this.addDomElement('div')

let a = this.e.appendChild(this.domCreateElement('div'))
a.style.textAlign = 'center'
a.innerText = this.label
a.className = this.prefixedClassName('label')

a = this.e.appendChild(this.domCreateElement('div'))
a.style.textAlign = 'center'
a.innerText = this.value
a.className = this.prefixedClassName('value')

const gradient = this.gradient()

a = this.e.appendChild(this.domCreateElement('div'))
a.style.textAlign = 'left'
a.style.background = gradient
a.className = this.prefixedClassName('bar')

a = this.e.appendChild(this.domCreateElement('div'))
a.style.textAlign = 'center'
a.innerText = `${this.percentage} %`
a.className = this.prefixedClassName('percentage')

this.buildChilds()
}

propertyNames() {
const names = [
'label',
'value',
'percentage',
'barOffset',
'barColor1',
'barColor2'
]

return super.propertyNames(names)
}

propertiesChanged() {
if (this.e !== null) {
this.e.children.item(1).innerText = this.value
this.e.children.item(2).style.background = this.gradient()
this.e.children.item(3).innerText = `${this.percentage} %`
}
}


gradient() {
const p = parseFloat(this.percentage)
const color1 = this.barColor1
const color2 = this.barColor2
const spot1 = `${this.barOffset}%`
const spot2 = `${this.barOffset + 0.1}%`
const spot3 = `${this.barOffset + p - 0.1}%`
const spot4 = `${this.barOffset + p}%`
return `linear-gradient(90deg, ${color1} 0%, ${color1} ${spot1}, ${color2} ${spot2}, ${color2} ${spot3}, ${color1} ${spot4})`
}
}
Loading

0 comments on commit 5a6f387

Please sign in to comment.