我有角度表,我从JSON文件中获取值。一切正常,但我需要在我的千分表中画出具有所需值的刻度,我该怎么做?
大约应该看起来像这个例子:
http://jsfiddle.net/m1erickson/v2AaD/
但我只需要标记一个值。
this is my dial.js
'use strict';
(function(){
var gmd = {};
/**
* @constructor
*
* @param {Element} element
* @param {Number} initialValue 0-100
* @param {Number} innerRadius
* @param {Number} outerRadius
* @param {Number} startAngle
* @param {Number} endAngle
*/
var Knob = function(element, initialValue, targetValue, innerRadius, outerRadius, startAngle, endAngle) {
this.element = element;
this.value = initialValue;
this.target = targetValue;
this.radians = this.convertToRadians(initialValue);
this.innerRadius = innerRadius;
this.outerRadius = outerRadius;
this.startAngle = startAngle,
this.endAngle = endAngle,
this.offset = this.outerRadius + 20;
this.inDrag = false;
};
/**
* Create the arcs required for this interactive component.
*
* @return {void}
*/
Knob.prototype.createArcs = function() {
this.changeArc = createArc(
this.innerRadius, this.outerRadius, this.convertToRadians(this.startAngle, 360), this.convertToRadians(this.startAngle, 360)
);
this.valueArc = createArc(
this.innerRadius, this.outerRadius, this.convertToRadians(this.startAngle, 360), this.convertToRadians(this.startAngle, 360)
);
this.interactArc = createArc(
this.innerRadius, this.outerRadius, this.convertToRadians(this.startAngle, 360), this.convertToRadians(this.endAngle, 360)
);
function createArc(innerRadius, outerRadius, startAngle, endAngle) {
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius)
.startAngle(startAngle);
if (typeof endAngle !== "undefined") {
arc.endAngle(endAngle);
}
return arc;
};
};
/**
* Convert a value in [0,100] to radians
*
* @param {Number} value
* @param {Number} d
* @param {Number} e
* @param {Number} s
*
* @return {Number}
*/
Knob.prototype.convertToRadians = function(value, d, e, s) {
var r;
d = d || 100;
e = e || 360;
s = s || 0;
r = e - s;
return (s + ((r/d) * value)) * (Math.PI/180);
};
/**
* Convert from radians to a value in range [0,100]
*
* @param {Number} radians
* @param {Number} d
* @param {Number} e
* @param {Number} s
*
* @return {Number}
*/
Knob.prototype.convertFromRadians = function(radians, d, e, s) {
var r;
d = d || 100;
e = e || 360;
s = s || 0;
r = e - s;
return Math.round(((180/Math.PI) * Math.abs(radians)) * (d/r));
};
/**
* Append an SVG to the element and draw the dial component
*
* @param {Function} updateFn
* @param {Boolean} isAnimated
*
* @return {void}
*/
Knob.prototype.draw = function(updateFn, isAnimated) {
var that = this;
that.createArcs();
var svg = d3.select(that.element)
.append('svg');
var changeElem = drawArc(that.changeArc, 'changeArc')
var valueElem = drawArc(that.valueArc, 'valueArc')
//var dragBehavior = d3.behavior.drag()
//.on('drag', dragInteraction)
//.on('dragend', clickInteraction);
//drawArc(that.interactArc, 'interactArc', clickInteraction, dragBehavior);
drawArc(that.interactArc, 'interactArc');
if (isAnimated) {
animate(that.convertToRadians(that.startAngle, 360), that.convertToRadians(that.value, 100, that.endAngle, that.startAngle));
} else {
that.changeArc.endAngle(this.convertToRadians(this.value, 100, this.endAngle, this.startAngle));
changeElem.attr('d', that.changeArc);
that.valueArc.endAngle(this.convertToRadians(this.value, 100, this.endAngle, this.startAngle));
valueElem.attr('d', that.valueArc);
}
svg.append('text')
.attr('class', 'text')
.attr('id', 'text')
.text(that.value+'%')
.attr('transform', 'translate(' + (that.offset-12) + ', ' + (that.offset+2) + ')');
function drawArc(arc, label, click, drag) {
//console.log('that.value:['+that.value+'] that.target:['+that.target+']');
var elem = svg.append('path')
//.attr('class', label)
.attr('fill', that.value < that.target ? 'red' : 'green')
.attr('id', label)
.attr('d', arc)
.attr('transform', 'translate(' + (that.offset) + ', ' + (that.offset) + ')');
if (click) {
elem.on('click', click);
}
if (drag) {
elem.call(drag);
}
return elem;
}
function animate(start, end) {
valueElem
.transition()
.ease('bounce')
.duration(1000)
.tween('',function() {
var i = d3.interpolate(start,end);
return function(t) {
var val = i(t);
valueElem.attr('d', that.valueArc.endAngle(val));
changeElem.attr('d', that.changeArc.endAngle(val));
};
});
}
function dragInteraction() {
that.inDrag = true;
var x = d3.event.x - that.offset;
var y = d3.event.y - that.offset;
interaction(x,y, false);
}
function clickInteraction() {
that.inDrag = false;
var coords = d3.mouse(this.parentNode);
var x = coords[0] - that.offset;
var y = coords[1] - that.offset;
interaction(x,y, true);
}
function interaction(x,y, isFinal) {
var arc = Math.atan(y/x)/(Math.PI/180), radians, delta;
if ((x >= 0 && y <= 0) || (x >= 0 && y >= 0)) {
delta = 90;
} else {
delta = 270;
}
radians = ((delta-that.startAngle) + arc) * (Math.PI/180);
that.value = that.convertFromRadians(radians, 100, that.endAngle, that.startAngle);
if(that.value >= 0 && that.value <= 100) {
updateFn(that.value);
that.valueArc.endAngle(that.convertToRadians(that.value, 100, that.endAngle, that.startAngle));
d3.select(that.element).select('#valueArc').attr('d', that.valueArc);
if (isFinal) {
that.changeArc.endAngle(that.convertToRadians(that.value, 100, that.endAngle, that.startAngle));
d3.select(that.element).select('#changeArc').attr('d', that.changeArc);
}
d3.select(that.element).select('#text').text(that.value);
}
}
};
/**
* Set the value of the gauge to something new.
*
* @param {Number} newValue
*/
Knob.prototype.setValue = function(newValue) {
if ((!this.inDrag) && this.value >= 0 && this.value <= 100) {
var radians = this.convertToRadians(newValue, 100, this.endAngle, this.startAngle);
this.value = newValue;
this.changeArc.endAngle(radians);
d3.select(this.element).select('#changeArc').attr('d', this.changeArc);
this.valueArc.endAngle(radians);
d3.select(this.element).select('#valueArc').attr('d', this.valueArc);
d3.select(this.element).select('#text').text(newValue);
}
};
gmd.Knob = Knob;
gmd.dialDirective = function() {
return {
restrict: 'E',
scope: {
value: '='
},
link: function (scope, element, attrs) {
var innerRadius = parseInt(attrs.innerRadius, 10) || 60,
outerRadius = parseInt(attrs.outerRadius, 10) || 100,
startAngle = parseInt(attrs.startAngle, 10) || 0,
endAngle = parseInt(attrs.endAngle, 10) || 360,
knob = new gmd.Knob(element[0], scope.value, attrs.target, innerRadius, outerRadius, startAngle, endAngle);
function update(value) {
scope.$apply(function() {
scope.value = value;
});
}
scope.$watch('value', function(newValue, oldValue) {
if((newValue !== null || typeof newValue !== 'undefined') && typeof oldValue !== 'undefined' && newValue !== oldValue) {
knob.setValue(newValue);
}
});
knob.draw(update, attrs.animate === "true");
}
};
};
app.directive('gmdDial', gmd.dialDirective);
})();
答案 0 :(得分:1)
这是绘制勾号的部分,您可以调用勾选drawTick(your json value)
,这可以为勾选drawLabel(corresponding JSON Label)
下面的小片段,我将值100添加为刻度线和标签
function draw(value) {
tickValue = value;
tickColor = "green";
if (tickValue < minBound) {
tickColor = "blue";
}
if (tickValue > maxBound) {
tickColor = "red";
}
//
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawArc();
drawTick(minBound, "gray");
drawTick(maxBound, "gray");
drawTick(100, "gray");//this is my new tick
drawTick(maxBound, "gray");
drawTick(tickValue, tickColor, 10);
drawLabel(minBound, "gray", 20, 18);
drawLabel(maxBound, "gray", 20, 18);
drawLabel(100, "gray", 20, 18);//this is the label new tick
drawLabel(tickValue, tickColor, 55, 24);
}
希望这有帮助!