var planeStringImage = "M 439.48098,95.969555 L 393.34268,142.46481 L 305.91233,133.41187 L 324.72376,114.58551 L 308.61525,98.464215 L 276.15845,130.94677 L 185.25346,123.08136 L 201.15145,107.27643 L 186.46085,92.574165 L 158.32,120.73735 L 45.386032,112.12042 L 15.000017,131.66667 L 221.20641,192.48691 L 298.26133,237.01135 L 191.91028,345.62828 L 152.82697,408.6082 L 41.549634,393.05411 L 21.037984,413.58203 L 109.25334,470.93369 L 166.38515,558.95725 L 186.8968,538.42933 L 171.35503,427.06371 L 234.28504,387.94939 L 342.81586,281.51396 L 387.305,358.63003 L 448.07703,565.00001 L 467.60778,534.58989 L 458.99769,421.56633 L 487.16033,393.38134 L 473.14247,379.35235 L 456.6139,395.97492 L 448.79636,303.63439 L 481.25315,271.15184 L 465.14464,255.03055 L 446.33321,273.8569 L 436.04766,185.1164 L 482.35108,138.7864 C 501.1942,119.92833 560.62425,61.834815 564.99998,14.999985 C 515.28999,23.707295 476.1521,61.495405 439.48098,95.969555 z ";
var planeStyleElement = "opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible";
var tickDataLabel = ['S', '210', '240', 'W', '300', '330', 'N', '030', '060', 'E', '120', '150', 'S'];
var drag = d3.drag().on("drag", function() {
var width = 115;
var height = 115;
var rect = d3.select(this);
var theta = Math.atan2(d3.event.y - height/2, d3.event.x - width/2) * 180 / Math.PI;
console.log('what is the angle?');
console.log(theta);
theta = Math.round(theta / 10) * 10;
if (theta === 0 ||
theta === 30 ||
theta === 60 ||
theta === 90 ||
theta === 120 ||
theta === 150 ||
theta === 180 ||
theta === -30 ||
theta === -60 ||
theta === -90 ||
theta === -120 ||
theta === -150 ||
theta === 330) {
document.getElementById('output').innerHTML = 'You have an airport facing at ' + theta + ' degrees';
rect
.attr("x", d3.event.x)
.attr("y", d3.event.y)
.attr('transform', `rotate(${theta}, 350, 240)`)
}
// rect
// .attr("x", d3.event.x)
// .attr("y", d3.event.y)
// .attr('transform', `rotate(${theta}, 350, 240)`)
// .attr('transform', `rotate(${theta}, ${d3.event.x}, ${d3.event.y})`)
});
function gauge(container, configuration, config) {
var that = {};
var range = undefined;
var r = undefined;
var pointerHeadLength = undefined;
var minAngle = 0;
var maxAngle = 0;
var counter = 0;
var svg = undefined;
var arc = undefined;
// a linear scale that maps domain values to a percent from 0..1
var scale = d3.scaleLinear()
.range([0, 1])
.domain([config.minValue, config.maxValue]);
var ticks = undefined;
var tickData = undefined;
var pointer = undefined;
var plane = undefined;
function deg2rad(deg) {
return deg * Math.PI / 180;
}
function testDraw(arcs, lowestGustAngle, highestGustAngle) {
range = config.maxAngle - config.minAngle;
r = config.size / 2;
pointerHeadLength = Math.round(r * config.pointerHeadLengthPercent);
ticks = scale.ticks(config.majorTicks);
tickData = d3.range(config.majorTicks).map(function() {
return 1 / config.majorTicks;
});
var newArc = d3.arc()
.innerRadius(r - config.ringWidth - config.ringInset)
.outerRadius(r - config.ringInset)
.startAngle(deg2rad(lowestGustAngle))
.endAngle(deg2rad(highestGustAngle));
var width = 600;
var height = 400;
// stop duplication
if (document.getElementsByClassName('newarc').length > 0) {
arcs.selectAll('g')
//animation
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.transition()
.duration(4000);
}
d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.attr('class', 'newarc')
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.transition()
.duration(4000);
arcs.selectAll('d')
.data(tickData)
.enter()
.append('g')
.append('path')
.attr('fill', 'green')
.transition()
.duration(4000)
.attr('d', newArc);
}
function configure(configuration) {
for (var prop in configuration) {
config[prop] = configuration[prop];
}
range = config.maxAngle - config.minAngle;
r = config.size / 2;
pointerHeadLength = Math.round(r * config.pointerHeadLengthPercent);
ticks = scale.ticks(config.majorTicks);
tickData = d3.range(config.majorTicks).map(function() {
return 1 / config.majorTicks;
});
arc = d3.arc()
.innerRadius(r - config.ringWidth - config.ringInset)
.outerRadius(r - config.ringInset)
.startAngle(function(d, i) {
var ratio = d * i;
return deg2rad(config.minAngle + (ratio * range));
})
.endAngle(function(d, i) {
var ratio = d * (i + 1);
return deg2rad(config.minAngle + (ratio * range));
});
var width = 600;
var height = 400;
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
}
that.configure = configure;
function centerTranslation() {
return 'translate(' + r + ',' + r + ')';
}
function isRendered() {
return (svg !== undefined);
}
that.isRendered = isRendered;
var arcs = undefined;
function render(newValue) {
svg = d3.select(container)
.append('svg:svg')
.attr('id', 'gauge')
.attr('width', config.clipWidth)
.attr('height', config.clipHeight);
var centerTx = centerTranslation();
arcs = svg.append('g')
.attr('class', 'arc')
.attr('transform', centerTx);
arcs.selectAll('path')
.data(tickData)
.enter().append('path')
.attr('fill', function(d, i) {
return config.arcColorFn(d * i);
})
.attr('d', arc);
var lg = svg.append('g')
.attr('class', 'label')
.attr('transform', centerTx);
lg.selectAll('text')
.data(ticks)
.enter().append('text')
.text('hi')
.attr('transform', function(d) {
var ratio = scale(d);
var newAngle = config.minAngle + (ratio * range);
console.log('index is');
console.log(ticks);
return 'rotate(' + newAngle + ') translate(0,' + (config.labelInset - r) + ')';
})
.text(function(d) {
return tickDataLabel[d];
});
var planeData = [[config.pointerWidth / 2, 0],
[4, -pointerHeadLength],
[-(config.pointerWidth * 4), 0],
[0, config.pointerTailLength],
[config.pointerWidth / 2, 0]];
var lineData = [[config.pointerWidth / 2, 0],
[0, -pointerHeadLength],
[-(config.pointerWidth / 2), 0],
[0, config.pointerTailLength],
[config.pointerWidth / 2, 0]];
var pointerLine = d3.line().curve(d3.curveMonotoneX);
var pgplane = svg.append('g').data([planeData])
.attr('id', 'svgplane')
.attr('transform', ' rotate(-45 100 100)');
var pg = svg.append('g').data([lineData])
.attr('class', 'pointer')
.attr('id', 'pointer')
.attr('transform', centerTx);
plane = pgplane.append('path')
.attr('d', planeStringImage)
.attr('style', planeStyleElement)
.attr('transform', 'rotate(' + config.minAngle + ')');
pointer = pg.append('path')
.attr('d', pointerLine)
.attr('transform', 'rotate(' + config.minAngle + ')');
update(newValue === undefined ? 0 : newValue);
}
that.render = render;
function update(newValue, newConfiguration) {
counter++;
var randomAngle = Math.random() * 90;
testDraw(arcs, randomAngle - 50, randomAngle);
if (newConfiguration !== undefined) {
configure(newConfiguration);
}
var ratio = scale(newValue);
var newAngle = config.minAngle + (ratio * range);
pointer.transition()
.duration(config.transitionMs)
.ease(d3.easeElastic)
.attr('transform', 'rotate(' + newAngle + ')');
if (minAngle >= newAngle) {
minAngle = newAngle;
}
if (maxAngle <= newAngle) {
maxAngle = newAngle;
}
if (counter === 5) {
maxAngle = newAngle + 5;
minAngle = newAngle - 5;
counter = 1;
}
}
that.update = update;
configure(configuration);
return that;
}
function onDocumentReady() {
var config = {
size: 200,
clipWidth: 200,
clipHeight: 110,
ringInset: 20,
ringWidth: 20,
pointerWidth: 10,
pointerTailLength: 5,
pointerHeadLengthPercent: 0.9,
minValue: 0,
maxValue: 12,
minAngle: -90 - 45 - 45,
maxAngle: 90 + 45 + 45,
transitionMs: 750,
majorTicks: 10,
labelFormat: d3.format(',g'),
labelInset: 10,
arcColorFn: d3.interpolateHsl(d3.rgb('#ffffff'), d3.rgb('#ffffff'))
};
var powerGauge = gauge('#power-gauge', {
size: 300,
clipWidth: 300,
clipHeight: 300,
ringWidth: 60,
maxValue: 10,
transitionMs: 4000
}, config);
powerGauge.render();
function updateReadings() {
var randomValue = Math.random() * 10;
config.minAngle = randomValue * 10;
powerGauge.update(randomValue);
}
updateReadings();
setInterval(function() {
updateReadings();
}, 5 * 1000);
}
if (!window.isLoaded) {
window.addEventListener("load", function() {
onDocumentReady();
d3.select("#planepath").call(drag);
// Very dodge way of doing this!
document.getElementById('pointer').append(document.getElementById('plane'));
// .call(drag)
}, false);
} else {
onDocumentReady();
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=320" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<title>Gauge</title>
<!--<script type="text/javascript" src="http://d3js.org/d3.v2.min.js"></script>-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.js"></script>
<script src="http://bernii.github.io/gauge.js/dist/gauge.min.js"></script>
<style>
body {
font-family: Helvetica, Arial, sans-serif;
margin: 32px;
}
#power-gauge g.arc {
fill: steelblue;
}
#power-gauge g.pointer {
fill: #3ed850;
stroke: #32ad40;
}
#power-gauge g.minpointer {
fill: #4593f9;
stroke: steelblue;
}
#power-gauge g.maxpointer {
fill: #e85116;
stroke: #b64011;
}
#power-gauge g.label text {
text-anchor: middle;
font-size: 14px;
font-weight: bold;
fill: #666;
}
</style>
</head>
<body >
<h3 id="output">You have an airport facing at 0 degrees</h3>
<div id="power-gauge"></div>
<br>
<svg width="1200" height="600" viewBox="0 0 900 350">
<g id="plane" style="" transform="translate(-55) scale(0.15, 0.15) rotate(-45 100 100)">
<defs id="defs0"></defs>
<path id="planepath" d="M 439.48098,95.969555 L 393.34268,142.46481 L 305.91233,133.41187 L 324.72376,114.58551 L 308.61525,98.464215 L 276.15845,130.94677 L 185.25346,123.08136 L 201.15145,107.27643 L 186.46085,92.574165 L 158.32,120.73735 L 45.386032,112.12042 L 15.000017,131.66667 L 221.20641,192.48691 L 298.26133,237.01135 L 191.91028,345.62828 L 152.82697,408.6082 L 41.549634,393.05411 L 21.037984,413.58203 L 109.25334,470.93369 L 166.38515,558.95725 L 186.8968,538.42933 L 171.35503,427.06371 L 234.28504,387.94939 L 342.81586,281.51396 L 387.305,358.63003 L 448.07703,565.00001 L 467.60778,534.58989 L 458.99769,421.56633 L 487.16033,393.38134 L 473.14247,379.35235 L 456.6139,395.97492 L 448.79636,303.63439 L 481.25315,271.15184 L 465.14464,255.03055 L 446.33321,273.8569 L 436.04766,185.1164 L 482.35108,138.7864 C 501.1942,119.92833 560.62425,61.834815 564.99998,14.999985 C 515.28999,23.707295 476.1521,61.495405 439.48098,95.969555 z " style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible" id="path1"></path>
</g>
</svg>
<br>
<svg id="test" width="1200" height="600" viewBox="0 0 900 350">
<g style="" transform="translate(-55) scale(0.15, 0.15) rotate(-45 100 100)">
<defs id="defs0"></defs>
<path d="M 439.48098,95.969555 L 393.34268,142.46481 L 305.91233,133.41187 L 324.72376,114.58551 L 308.61525,98.464215 L 276.15845,130.94677 L 185.25346,123.08136 L 201.15145,107.27643 L 186.46085,92.574165 L 158.32,120.73735 L 45.386032,112.12042 L 15.000017,131.66667 L 221.20641,192.48691 L 298.26133,237.01135 L 191.91028,345.62828 L 152.82697,408.6082 L 41.549634,393.05411 L 21.037984,413.58203 L 109.25334,470.93369 L 166.38515,558.95725 L 186.8968,538.42933 L 171.35503,427.06371 L 234.28504,387.94939 L 342.81586,281.51396 L 387.305,358.63003 L 448.07703,565.00001 L 467.60778,534.58989 L 458.99769,421.56633 L 487.16033,393.38134 L 473.14247,379.35235 L 456.6139,395.97492 L 448.79636,303.63439 L 481.25315,271.15184 L 465.14464,255.03055 L 446.33321,273.8569 L 436.04766,185.1164 L 482.35108,138.7864 C 501.1942,119.92833 560.62425,61.834815 564.99998,14.999985 C 515.28999,23.707295 476.1521,61.495405 439.48098,95.969555 z " style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;marker:none;visibility:visible;display:inline;overflow:visible" id="path1"></path>
</g>
</svg>
<br>
<svg width='650' height='600' viewBox='0 0 650 600' id="drag">
<desc>
You may click and drag the ellipse.
Make the ellipse rotate by grabbing the small circle and dragging.
</desc>
<defs>
<pattern id="trama" patternUnits="objectBoundingBox" width="2.5%" height="2.5%" patternTransform="rotate(25)" >
<line id="linea" y2="1%" />
</pattern>
</defs>
<!--<polygon id="box" points ="" stroke-width='1' stroke-dasharray='5,5' fill="none"></polygon>
<path id='ellipse'
d=''
fill='url(#trama)'
stroke-width='3' />
<circle cx ="" cy ="" r ="6" id="LT" />-->
</svg>
<div id="foo"></div>
<script src="app.js">
</script>
<!--<script src="test.js">-->
<!--</script>-->
</body>
</html>