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

Donut charts #29

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 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
43 changes: 43 additions & 0 deletions client/css/analysis.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
:root {
/* the higher the number, the less filled */
--percent: 8;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the higher the number, the less filled

Why did you do it like that? Also, why did you put the variable on :root instead of on the donut chart container?

You could make the --percent variable work like an actual percentage by doing this:

  • set the pathLength attribute of the circle element to 100; then the browser will always do stroke calculations as if the circle's circumference is 100 units (which means a stroke dash offset of 1 will actually offset the stroke by 1%)
  • use calc() to do subtraction at the site where you use the variable:
    stroke-dashoffset: calc(100 - var(--percent));

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I put the variable on root because there is no container in this pr to add it to.
  2. I did it like this so that in JS, I could easily change the --percent variable for each donut from there and it would fill the circle accordingly. 440 is approximately 2πr where r is 70 as seen in the code.
    • For example, if Perspective returns 70% toxicity, do 440 - 440*.70 in js and then set the --percent variable from there. Very simple.
  3. I tried to set the pathLength attribute to 100 and try it that way, but changing the stroke-dashoffset had no effect.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And you can use calc() if you want the donut to fill up counterclockwise instead of clockwise

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very very nice. Thank you

}

.item {
display: block;
}

.item h2 {
text-align:center;
width: 100%;
}

svg {
-webkit-transform: rotate(-90deg);
transform: rotate(-90deg);
display: block; /* svg is auto display-inline*/
margin: auto;
overflow: visible;
}

.circle_animation {
stroke-dasharray: 440; /* circumference of the circle */
stroke-dashoffset: 440;
}

.donut .circle_animation {
-webkit-animation: donut 1s ease-out forwards;
animation: donut 1s ease-out forwards;
}

@-webkit-keyframes donut {
to {
stroke-dashoffset: var(--percent); /* half filled is 220*/
}
}

@keyframes donut {
to {
stroke-dashoffset: var(--percent);
}
}
seunomonije marked this conversation as resolved.
Show resolved Hide resolved
93 changes: 76 additions & 17 deletions client/js/analysis.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,86 @@


// Will be overwritten in merge
window.onload = function() {
seunomonije marked this conversation as resolved.
Show resolved Hide resolved
// Listen for on submit click
let formSubmit = document.getElementById("formSubmit");
formSubmit.addEventListener("click", fetchAndShowResponse, false);
}
// Listen for on submit click
const formSubmit = document.getElementById('formSubmit');
formSubmit.addEventListener('click', fetchAndShowResponse, false);
};

/**
* Grabs response from server
*/
* Will be overwritten in merge
*/
async function fetchAndShowResponse() {
const response = await fetch('/api/musix');
const value = await response.json();
changeInnerText("response", value);
return value;
const response = await fetch('/api/musix');
const value = await response.json();
changeInnerText('response', value);
return value;
}

/**
* Change the contents of div
* @param elId the id of the element
* @param value the value to insert as innerText
* Will be overwritten in merge
* @param elId
* @param value
*/
function changeInnerText(elId, value) {
const el = document.getElementById(elId);
el.innerText = value;
const el = document.getElementById(elId);
el.innerText = value;
}

/**
* Adds a new chart to the page
*/
function addElement() {
const div = document.createElement('div');
div.className = 'item donut';

const header = document.createElement('h2');
header.innerText = 'Toxicity';
div.appendChild(header);

const svg = createSVGElement('svg');
svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
const g = buildCircle();
svg.appendChild(g);
div.appendChild(svg);

const currentDiv = document.getElementById('id');
document.body.insertBefore(div, currentDiv);
}

/**
* Builds the circles within the svg tag
*/
function buildCircle() {
const g = createSVGElement('g');

const insideCircle = createSVGElement('circle');

insideCircle.setAttribute('r', '70');
insideCircle.setAttribute('cx', '50%');
insideCircle.setAttribute('cy', '50%');
insideCircle.setAttribute('stroke-width', '20');
insideCircle.setAttribute('stroke', '#f2f2f2');
insideCircle.setAttribute('fill', 'none');

const outsideCircle = createSVGElement('circle');

outsideCircle.setAttribute('class', 'circle_animation');
outsideCircle.setAttribute('r', '70');
outsideCircle.setAttribute('cx', '50%');
outsideCircle.setAttribute('cy', '50%');
outsideCircle.setAttribute('stroke-width', '20');
outsideCircle.setAttribute('stroke', '#ffb6c1'); // light pink
outsideCircle.setAttribute('fill', 'none');

g.appendChild(insideCircle);
g.appendChild(outsideCircle);

return g;
}

/**
* Creates an SVG Element
* @param el
*/
function createSVGElement(el) {
return document.createElementNS('http://www.w3.org/2000/svg', el);
}