Skip to content

Instantly share code, notes, and snippets.

@chibaye
Created May 3, 2019 14:05
Show Gist options
  • Save chibaye/6cfaff2632fa7332cbe38b9f53f439ee to your computer and use it in GitHub Desktop.
Save chibaye/6cfaff2632fa7332cbe38b9f53f439ee to your computer and use it in GitHub Desktop.
SVG Line Graph
<div id="wrapper">
<div class="explanation">
<h1>Svg Line Graph</h1>
<p>Make your own graph, type in atleast two numbers below, and the default graph will clear and it will generate one based on your input</p>
<p>Your values are...</p>
<p id="yourValues"></p>
<input type="input" id="value" name="value" placeholder="Value (number)"/>
<input type="button" value="add value" onclick="addValue()"/>
<input type="button" value="clear chart" onclick="clearChart()"/>
</div>
<div class="chart"></div>
</div>
console.clear();
var chart = {
element : "",
chart : "",
polygon : "",
width : 100,
height : 50,
maxValue : 0,
values : [],
points : [],
vSteps : 5,
measurements : [],
calcMeasure : function(){
this.measurements = [];
for(x=0; x < this.vSteps; x++){
var measurement = Math.ceil((this.maxValue / this.vSteps) * (x +1));
this.measurements.push(measurement);
}
this.measurements.reverse();
},
/**
* Get Element
* Take the selector being passed, determine if
* the selector is a class (".") or an id ("#"), and get the element
* @param {String} element - the element selector
*/
getElement : function(element){
if(element.indexOf(".") == 0){
this.element = document.getElementsByClassName("chart")[0]
}
else if(element.indexOf("#") == 0){
this.element = document.getElementById("chart");
}
else {
console.error("Please select a valid element");
}
},
/**
* Create Chart
* - calc the max value
* - calc the points for the polygon
* - create a chart <svg>
* - set width, height, and viewbox attributes on <svg>
* - create a <polygon>
* - set points on <polygon>
* - calc the vertical measurements
* @param {array} values - the values to plot on the chart
*/
createChart : function(element, values){
this.getElement(element);
this.values = values;
// Do some calculations
this.calcMaxValue();
this.calcPoints();
this.calcMeasure();
// Clear any existing
this.element.innerHTML = "";
// Create the <svg>
this.chart = document.createElementNS("http://www.w3.org/2000/svg", "svg");
this.chart.setAttribute("width", "100%");
this.chart.setAttribute("height", "100%");
this.chart.setAttribute("viewBox", "0 0 " + chart.width + " " + chart.height);
// Create the <polygon>
this.polygon = document.createElementNS('http://www.w3.org/2000/svg','polygon');
this.polygon.setAttribute("points", this.points);
this.polygon.setAttribute("class", "line");
if(this.values.length > 1){
var measurements = document.createElement("div");
measurements.setAttribute("class", "chartMeasurements");
for(x=0; x < this.measurements.length; x++){
var measurement = document.createElement("div");
measurement.setAttribute("class", "chartMeasurement");
measurement.innerHTML = this.measurements[x];
measurements.appendChild(measurement);
}
this.element.appendChild(measurements);
// Append the <svg> to the target <div>
this.element.appendChild(this.chart);
// Append the polygon to the target <svg>
this.chart.appendChild(this.polygon);
}
},
/**
* Calc Points
* Calculate all the points for the polygon
*/
calcPoints : function(){
this.points = [];
if(this.values.length > 1){
// First point is bottom left hand side (max value is the bottom of graph)
var points = "0," + chart.height + " ";
// Loop through each value
for(x=0; x < this.values.length; x++){
// Calculate the perecentage of this value/the max value
var perc = this.values[x] / this.maxValue;
// Steps is a percentage (100) / the total amount of values
var steps = 100 / ( this.values.length - 1 );
// Create the point, limit points to 2 decimal points,
// Y co-ord is calculated by the taking the chart height,
// then subtracting (chart height * the percentage of this point)
// Remember the & co-ord is measured from the top not the bottom like a traditional graph
var point = (steps * (x )).toFixed(2) + "," + (this.height - (this.height * perc)).toFixed(2) + " ";
// Add this point
points += point;
}
// Add the final point (bottom right)
points += "100," + this.height;
this.points = points;
}
// output the values for display
document.getElementById("yourValues").innerHTML= this.values;
},
/**
* Calculate Max Value
* Find the highest value in the array, and then
* add 10% to it so the graph doesn't touch the top of the chart
*/
calcMaxValue : function(){
this.maxValue = 0;
for(x=0; x < this.values.length; x++){
if(this.values[x] > this.maxValue){
this.maxValue = this.values[x];
}
}
// Round up to next integer
this.maxValue = Math.ceil(this.maxValue);
}
}
var values = [];
function addValue(){
var input = document.getElementById("value");
var value = parseInt(input.value);
if(!isNaN(value)){
values.push(value);
chart.createChart('.chart',values);
}
input.value = "";
}
function clearChart(){
values = [];
chart.createChart('.chart',values);
}
chart.createChart('.chart',[5,10,15,30,1,3,5,20]);
$blue: #4183d7;
body {
font:400 16px roboto, helvetica, arial;
background:#f2f2f2;
color:$blue;
}
h1 {
margin-bottom:0;
}
#wrapper {
width:650px;
padding:1em;
margin:2em auto;
background:white;
box-shadow:0 5px 10px rgba(0,0,0,.1);
}
.explanation {
margin-bottom:3em;
display: inline-block;
}
.chart {
width:600px;
padding-left:50px;
height:300px;
margin:auto;
position: relative;
display:flex;
justify-content: space-between;
border-bottom:1px solid lighten($blue,35%);
.chartMeasurements {
position: absolute;
top: 0;
left: 0px;
width: 100%;
height: 100%;
display:flex;
justify-content: space-between;
flex-direction:column;
text-align:left;
z-index:1;
.chartMeasurement {
width:100%;
flex-grow:1;
border-top:1px solid lighten($blue,35%);
}
}
svg {
position: relative;
z-index:2;
polygon {
box-shadow:inset 2px 0 red;
fill:rgba($blue,.6);
}
}
}

SVG Line Graph

Exploring graphing using svg, dynamically create a graph based on a javascript array, no jQuery or any other library

A Pen by Alan on CodePen.

License.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment