-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
834a524
commit a15c385
Showing
4 changed files
with
318 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,18 @@ | ||
# singleBar | ||
Simple single bar chart (uses p5.js) | ||
|
||
# Parameters | ||
|
||
* `values`: Array of numeric values (between 3 and 5 values in length) (no default) | ||
* `hideValues`: Do not display the numeric values (default: false) | ||
* `save`: Automatically download as PNG (the value of the `save` parameter is the filename) (no default) | ||
|
||
# Use | ||
|
||
* Copy the HTML and JS files to a local folder | ||
* Note: you must change the path to the JS file in the HTML (line 8) if you don't store them in the same folder | ||
* *optional* Start a web server (Note: the page works when opening the HTML file from your browser without going through a web server) | ||
* Open the HTML file - the page will open with a default array & show you the corresponding URL with all the parameters | ||
|
||
# Sample | ||
![Sample Image](singleBar-sample.png) |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
<!-- @format --> | ||
|
||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<title>P5.js Single Bar Chart</title> | ||
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.3.1/p5.min.js"></script> | ||
<script src="./singleBar.js"></script> | ||
</head> | ||
<body> | ||
<!-- no body is needed. P5.js creates the canvas and draws to it directly --> | ||
<script> | ||
// Debugging method | ||
let debug = true | ||
function dbg(msg) { | ||
if (debug) { | ||
console.log(msg) | ||
} | ||
} | ||
|
||
// Value boxes | ||
let i1, i2, i3, i4, i5 | ||
|
||
let bullet // bullet chart object | ||
let canvas // canvas | ||
|
||
let a = 5 // Default value[0] | ||
let b = 3 // Default value[1] | ||
let c = 2 // Default value[2] | ||
let d = 7 // Default value[3] | ||
let e = 12 // Default value[4] | ||
|
||
let cbHide, helpDiv // HTML elements for checkbox and link text | ||
|
||
/* | ||
* Create bar in a single run - no looping | ||
*/ | ||
function setup() { | ||
let params = getURLParams() | ||
|
||
// Update or remove these settings based on your preference | ||
// Only `values` is required | ||
const values = params.values ? params.values.split(',') : [a, b, c, d] | ||
const width = params.width || false | ||
const height = params.height || false | ||
|
||
const hideValues = | ||
(params.hideValues && | ||
(params.hideValues == 'true' || params.hideValues == 'yes')) || | ||
false | ||
|
||
const showValues = !hideValues | ||
|
||
if (values) { // Values were supplied, so set them | ||
a = values[0] | ||
b = values[1] | ||
c = values[2] | ||
d = values[3] | ||
e = values[4] | ||
} else { // No values, so use the defaults | ||
values = [a, b, c, d] | ||
} | ||
// If you remove variables above, remove them from this constructor call, too | ||
sb = new SingleBar(values, showValues) //, width, height) | ||
|
||
// The bullet object calculates the proper width and height of the canvas | ||
canvas = createCanvas(sb.getWidth(), sb.getHeight()) | ||
sb.display() | ||
noLoop() // Do not execute the draw() method | ||
|
||
let inputSize = 30 | ||
i1 = createInput(a).size(inputSize).input(inputEvent) | ||
i2 = createInput(b).size(inputSize).input(inputEvent) | ||
i3 = createInput(c).size(inputSize).input(inputEvent) | ||
i4 = createInput(d).size(inputSize).input(inputEvent) | ||
i5 = createInput(e).size(inputSize).input(inputEvent) | ||
|
||
cbHide = createCheckbox('hide values', hideValues).changed(checkEvent) | ||
|
||
helpDiv = createDiv() | ||
updateHelpDiv() | ||
|
||
if (params.save) { | ||
let filename = params.save || 'singleBar' | ||
saveCanvas(canvas, filename, 'png') | ||
} | ||
} | ||
|
||
/** | ||
* When one of the value boxes changes, | ||
* set the new values and trigger a display refresh | ||
* | ||
* @memberof SingleBar | ||
*/ | ||
function inputEvent() { | ||
if (i5.value()) { | ||
sb.setValues([ | ||
i1.value(), | ||
i2.value(), | ||
i3.value(), | ||
i4.value(), | ||
i5.value(), | ||
]) | ||
} else if (i4.value()) { | ||
sb.setValues([i1.value(), i2.value(), i3.value(), i4.value()]) | ||
} else { | ||
// min 3 values | ||
sb.setValues([i1.value(), i2.value(), i3.value()]) | ||
} | ||
updateHelpDiv() | ||
sb.display() | ||
} | ||
|
||
/** | ||
* Toggle the hideValues checkbox | ||
* then refresh bar display | ||
* | ||
* @memberof SingleBar | ||
*/ | ||
function checkEvent() { | ||
sb.setShowValues(!this.checked()) | ||
updateHelpDiv() | ||
sb.display() | ||
} | ||
|
||
/** | ||
* Show the hyperlink for the currently displayed bar | ||
* | ||
* @memberof SingleBar | ||
*/ | ||
function updateHelpDiv() { | ||
helpDiv.html( | ||
`<a href='singleBar.html?values=${sb.values.join( | ||
',' | ||
)}&hideValues=${cbHide.checked()}'>singleBar.html?values=${sb.values.join( | ||
',' | ||
)}&hideValues=${cbHide.checked()}</a>` | ||
) | ||
} | ||
|
||
function draw() { | ||
// no-op - the chart is drawn in the setup() and *Event() methods | ||
} | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
/** @format */ | ||
|
||
const DEFAULT_MAX = 100 // Total of all values | ||
const DEFAULT_WIDTH = 400 // Total width of the bar | ||
const DEFAULT_HEIGHT = 20 // Height of the bar | ||
|
||
// Default colors based on # of values supplied | ||
const DEFAULT_COLORS_3 = ['#EF476F', '#FFD166', '#06D6A0'] | ||
const DEFAULT_COLORS_4 = ['#EF476F', '#FFD166', '#06D6A0', '#073B4C'] | ||
const DEFAULT_COLORS_5 = ['#EF476F', '#FFD166', '#06D6A0', '#118AB2', '#073B4C'] | ||
|
||
const DEFAULT_FONT_COLORS = ['white', 'black', 'black', 'white', 'white'] | ||
|
||
const DEFAULT_SHOW_VALUES = false | ||
|
||
/** | ||
* Class to create SingleBar object | ||
* Requires: p5.js | ||
*/ | ||
class SingleBar { | ||
/** | ||
* Constructor | ||
* @param {number} values - Values (comma-separated) | ||
* @param {number} width - Width of the canvas | ||
* @param {number} height - Height of the canvas | ||
* @param {number} barHeight - Height of the value bar | ||
* | ||
*/ | ||
constructor( | ||
values, | ||
showValues = DEFAULT_SHOW_VALUES, | ||
width = DEFAULT_WIDTH, | ||
height = DEFAULT_HEIGHT | ||
) { | ||
this.buffer = 0 // Horizontal buffer | ||
this.vbuffer = 0 // Vertical buffer (above/below chart) | ||
|
||
this.setValues(values.map((x) => +x)) | ||
|
||
this.canvasWidth = width | ||
this.canvasHeight = height | ||
this.showValues = showValues | ||
|
||
// Calculate the bounding box of the chart | ||
this.chartX = 0 | ||
this.chartY = 0 | ||
|
||
this.chartWidth = this.canvasWidth - this.chartX // No buffer | ||
this.chartHeight = this.canvasHeight // No buffer | ||
|
||
// points per pixel | ||
this.ppp = this.chartWidth / this.max | ||
noLoop() | ||
} | ||
|
||
/** | ||
* Set the array of values | ||
* Note: will be converted to numbers (or fail) | ||
* | ||
* @param {Array} v Array of numeric values | ||
* @memberof SingleBar | ||
*/ | ||
setValues(v) { | ||
this.binCount = v.length | ||
this.values = v.map((x) => +x) | ||
console.log(`this.values = `, this.values) | ||
this.max = this.values.reduce((p, c) => (p += c)) | ||
this.ppp = this.chartWidth / this.max | ||
|
||
// Set up the bins and colors | ||
switch (this.binCount) { | ||
case 3: | ||
this.colors = DEFAULT_COLORS_3 | ||
break | ||
case 4: | ||
this.colors = DEFAULT_COLORS_4 | ||
break | ||
case 5: | ||
this.colors = DEFAULT_COLORS_5 | ||
break | ||
default: | ||
this.colors = [] | ||
break | ||
} | ||
this.fontColors = DEFAULT_FONT_COLORS | ||
} | ||
|
||
/** | ||
* Show the values? | ||
* | ||
* @param {boolean} s Display | ||
* @memberof SingleBar | ||
*/ | ||
setShowValues(s) { | ||
this.showValues = s | ||
} | ||
|
||
/** | ||
* Standard p5js display() function | ||
* Note: noloop() is set to prevent refresh | ||
* | ||
* @memberof SingleBar | ||
*/ | ||
display() { | ||
// Quantitiatve Bins | ||
noStroke() | ||
let shade = 0 | ||
let prevW = 0 | ||
|
||
textAlign(CENTER, CENTER) | ||
|
||
// Create the shaded backgrounds | ||
for (let i = 0; i < this.binCount; i++) { | ||
let thisW = this.ppp * this.values[i] | ||
|
||
fill(this.colors[i]) | ||
rect(this.chartX + prevW, 0, thisW, this.chartHeight) | ||
|
||
// Print the value | ||
if (this.showValues) { | ||
fill(this.fontColors[i]) | ||
if (this.values[i] > 0) { | ||
text(this.values[i], prevW + thisW / 2, this.canvasHeight / 2) | ||
} | ||
} | ||
// Catch the width for the next loop | ||
prevW += thisW | ||
} | ||
} | ||
|
||
/** | ||
* Get the canvas width | ||
* @returns {number} Canvas width | ||
*/ | ||
getWidth() { | ||
return this.canvasWidth | ||
} | ||
|
||
/** | ||
* Get the canvas height | ||
* @returns {number} Canvas height | ||
*/ | ||
getHeight() { | ||
return this.canvasHeight | ||
} | ||
} | ||
|
||
/** | ||
* Print debug message | ||
* @param {string} msg Debug message | ||
*/ | ||
function dbg(msg) { | ||
if (debug) { | ||
console.log(msg) | ||
} | ||
} |