Skip to content

Instantly share code, notes, and snippets.

@allyraza
Last active July 3, 2018 10:04
Show Gist options
  • Save allyraza/417e4fad5cbec29b9c3a64a7a1cc1445 to your computer and use it in GitHub Desktop.
Save allyraza/417e4fad5cbec29b9c3a64a7a1cc1445 to your computer and use it in GitHub Desktop.
real time gauge
license: mit
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css">
<link rel="stylesheet" href="style.css">
<style>
body { margin:0; padding: 30px; position:fixed;top:0;right:0;bottom:0;left:0; }
</style>
</head>
<body>
<div class="col-md-6">
<div class="gauge">
<div class="guage-info">
<h3 class="gauge-title"><span class="guage-title-em">Clicks</span> this year</h3>
<small class="gauge-text gauge-text-sm">Compared to last year</small>
<h1 class="gauge-stats">
<span class="gauge-stats-value">120</span>
</h1>
<p class="gauge-delta">
<i class="gauge-delta-icon"></i>
<span class="gauge-delta-value">1.420 (+12%)</span>
</p>
</div>
<div class="gauge-chart js-sparkline"></div>
</div>
</div>
<script>
var data = [
{x: 10, y: 10, z: 10},
{x: 10, y: 10, z: 10},
{x: 10, y: 10, z: 10},
{x: 10, y: 10, z: 10},
{x: 10, y: 10, z: 10},
{x: 10, y: 10, z: 10},
];
var width = 200;
var height = 100;
var globalX = 0;
var duration = 500;
var step = 10;
var chart = d3.select('.js-sparkline')
.append('svg')
.attr('width', width + 10)
.attr('height', height + 10);
var x = d3.scaleLinear().domain([0, width]).range([0, width]);
var y = d3.scaleLinear().domain([0, height]).range([height, 0]);
var defs = chart.append('defs');
var gradient = defs.append("linearGradient")
.attr("id", "areaGradient")
.attr("x1", "100%")
.attr("x2", "100%")
.attr("y1", "0%")
.attr("y2", "100%");
gradient.append("stop")
.attr('class', 'start')
.attr("offset", "0%")
.attr("stop-color", "#5b85c9")
.attr("stop-opacity", 1);
gradient.append("stop")
.attr('class', 'end')
.attr("offset", "100%")
.attr("stop-color", "#5b85c9")
.attr("stop-opacity", 0);
var line = d3.line()
.x(d => x(d.x))
.y(d => y(d.y))
.curve(d3.curveCatmullRom.alpha(0.5));
var targetLine = d3.line()
.x(d => x(d.x))
.y(d => y(d.z))
.curve(d3.curveCatmullRom.alpha(0.5));
var areaLine = d3.area()
.x(d => x(d.x))
.y0(height)
.y1(d => y(d.y));
// Append the holder for line chart and fill area
var path = chart.append('path');
var targetPath = chart.append('path');
var areaPath = chart.append('path');
var rand = (min, max) => Math.random() * (max - min) + min;
// Draw
function draw(value, target) {
var point = {
x: globalX,
y: value,
z: target,
};
data.push(point);
globalX += step;
// Draw new line
path.datum(data)
.attr('class', 'line')
.attr('d', line);
targetPath.datum(data)
.attr('class', 'line-default')
.attr('d', targetLine);
areaPath.datum(data)
.attr('class', 'area')
.attr('fill', 'url(#areaGradient)')
.attr('d', areaLine);
// Shift the chart left
if (globalX > width) {
x.domain([globalX - (width - step), globalX]);
}
path.attr('transform', null)
.transition()
.duration(duration)
.attr('transform', 'translate(' + x(globalX - max) + ')');
targetPath.attr('transform', null)
.transition()
.duration(duration)
.attr('transform', 'translate(' + x(globalX - max) + ')');
areaPath.attr('transform', null)
.transition()
.duration(duration)
.attr('transform', 'translate(' + x(globalX - max) + ')');
if (data.length > 50) data.shift();
}
setInterval(function() {
console.log('adding new value');
draw(rand(50, 100), rand(40, 80));
}, 1000);
// (function() {
// var data = document.getElementById("fileData");
// var conn = new WebSocket("ws://{{.Host}}/ws");
// conn.onclose = function(evt) {
// console.log('Connection closed');
// }
// conn.onmessage = function(evt) {
// draw(JSON.parse(evt.data).value)
// }
// })();
</script>
</body>
* {
box-sizing: border-box;
}
body {
font-family: 'Roboto', sans-serf;
font-size: 13px;
color: #333333;
background-color: #efefef;
margin: 30px; }
/* Chart */
.chart {
display: flex;
justify-content: center;
/* Chart label */
/* Chart tooltip */ }
.chart-label {
font-family: Roboto, sans-serif;
fill: #333333;
font-size: 13px; }
.chart-label-lg {
font-size: 24px; }
.chart-label-md {
font-size: 18px; }
.chart-label-xs {
font-size: 11px; }
.chart-label-default {
font-weight: 500; }
.chart-label-light {
fill: #999999;
font-weight: 500; }
.chart-label-success {
fill: #7bbc59;
font-weight: 500; }
.chart-label-primary {
font-weight: 900;
font-size: 18px; }
.chart-label-secondary {
font-weight: 900;
font-size: 18px;
fill: #999999; }
.chart-tooltip {
background-color: rgba(0, 0, 0, 0.5);
border-radius: 3px;
position: absolute;
z-index: 1001;
padding: 15px;
color: white;
pointer-events: none;
text-align: left;
box-sizing: border-box;
line-height: 1.5; }
.chart-tooltip::before {
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
border-right: 10px solid rgba(0, 0, 0, 0.5);
content: "";
display: inline-block;
position: absolute;
top: 50%;
left: -10px;
margin-top: -10px; }
.chart-tooltip-table {
margin-bottom: 0;
color: white; }
/* Chart gauge */
.chart-gauge .chart-label-light {
font-weight: 300; }
.chart-bar {
width: 100%;
height: 300px; }
.chart-bar .chart-label {
font-weight: 500; }
.chart-bar .tick line {
stroke: #fff; }
.chart-multiple {
width: 100%;
height: 700px; }
.chart-multiple .chart-svg {
width: 100%; }
.chart-multiple .chart-line {
fill: none;
stroke-width: 2; }
.chart-multiple .chart-label-heading {
font-weight: 700; }
.chart-multiple .chart-axis .tick:first-child text {
text-anchor: start; }
.chart-donut {
width: 100%;
height: 230px; }
/* Chart axis */
.axis {
font-size: 13px; }
.axis .domain {
display: none; }
.axis .tick line {
stroke: #ddd; }
.axis path {
display: none; }
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges; }
.axis-bordered .domain {
stroke: #ddd; }
/*
* Gauge
*/
.gauge {
font-weight: 400;
padding: 15px;
border-radius: 4px;
background-color: #ffffff;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
border: solid 1px #dddddd;
display: flex;
justify-content: space-between;
flex-direction: row; }
.gauge-title {
font-size: 12px;
font-weight: 400;
margin: 0; }
.guage-title-em {
font-size: 16px;
color: #5287cc; }
.gauge-text {
color: #a8b3b9;
margin-bottom: 7.5px;
display: block; }
.gauge-text-sm {
font-size: 12px; }
.gauge-stats {
margin-top: 0;
margin-bottom: 7.5px;
height: 40px;
overflow: hidden;
font-size: 36px;
font-weight: bold; }
.gauge-stats-value {
animation: 0.5s slideup; }
.gauge-delta {
margin: 0;
font-size: 15px;
font-weight: 500;
max-height: 20px;
overflow: hidden;
display: flex; }
.gauge-delta-value {
animation: 0.5s slideup; }
.gauge-delta-icon {
width: 18px;
height: 18px;
margin-right: 3px;
display: inline-block;
background-repeat: no-repeat;
background-position: center center;
opacity: 0.75;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5IiBoZWlnaHQ9IjE4IiB2aWV3Qm94PSIwIDAgOSAxOCI+ICAgIDxwYXRoIGZpbGw9IiMwMDAwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTAgMGw5IDktOSA5eiIvPjwvc3ZnPg==); }
.gauge-delta-success {
color: #7bbc59; }
.gauge-delta-success .gauge-delta-value {
animation: 0.5s slideup; }
.gauge-delta-success .gauge-delta-icon {
opacity: 1;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSI5IiB2aWV3Qm94PSIwIDAgMTggOSI+ICAgIDxwYXRoIGZpbGw9IiM3QkJDNTkiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTAgOWw5LTkgOSA5eiIvPjwvc3ZnPg==); }
.gauge-delta-danger {
color: #fc0d1b; }
.gauge-delta-danger .gauge-delta-icon {
opacity: 1;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxOCIgaGVpZ2h0PSI5IiB2aWV3Qm94PSIwIDAgMTggOSI+ICAgIDxwYXRoIGZpbGw9IiNGQzBEMUIiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTE4IDBMOSA5IDAgMHoiLz48L3N2Zz4=); }
.gauge-chart {
width: 180px;
height: 110px;
display: flex;
justify-content: center; }
@keyframes rotate {
from {
transform: rotate(10) scale(1.0, 1.0);
backface-visibility: hidden;
}
to {
transform: rotate(0) scale(1.0, 1.0);
}
}
@keyframes slideup {
from {
transform: translate(0, 20px) scale(1.0, 1.0);
backface-visibility: hidden;
}
to {
transform: translate(0, 0);
}
}
.line {
fill: none;
stroke: #5b85c9;
stroke-width: 1.5px;
}
.line-default {
fill: none;
stroke: #5b85c9;
stroke-dasharray: 3, 3;
stroke-width: 1.5px;
}
.area {
/*fill: #efefef;*/
opacity: 0.3;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment