[英]How to place a text on morris.js bar graph
I have a morris.js bar graph.我有一个 morris.js 条形图。 I want to place
count
on top of this graph.我想把
count
放在这个图表的顶部。 I looked into morris.js bar doc , could not find any.我查看了morris.js bar doc ,找不到任何内容。
On hover it should display value
but on top of bar it should display count
.在悬停时它应该显示
value
但在 bar 顶部它应该显示count
。 Is there a way to do that?有没有办法做到这一点? something like the given image
类似于给定图像的东西
Here is my code这是我的代码
Morris.Bar ({
element: 'bar-example',
data: [
{mapname: 's1', value: 10, count: 3},
{mapname: 's2', value: 4, count: 4},
{mapname: 's3', value: 12, count: 13}
],
xkey: 'mapname',
ykeys: ['value'],
labels: ['No. of days'],
barRatio: 0.4,
xLabelAngle: 35,
hideHover: 'auto',
barColors: function (row, series, type) {
console.log("--> "+row.label, series, type);
if(row.label == "s1") return "#AD1D28";
else if(row.label == "s2") return "#DEBB27";
else if(row.label == "s3") return "#fec04c";
}
});
Here is a link where you can test it.这是一个链接,您可以在其中进行测试。
I just found this question whilst looking for the same solution.我刚刚在寻找相同的解决方案时发现了这个问题。 This is done in javascript / jquery.
这是在 javascript/jquery 中完成的。
I can share with you the code I am using which I discovered by trial, error and research.我可以与您分享我通过反复试验和研究发现的我正在使用的代码。
function parseSVG(s) {
var div= document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+s+'</svg>';
var frag= document.createDocumentFragment();
while (div.firstChild.firstChild)
frag.appendChild(div.firstChild.firstChild);
return frag;
}
var theData = [
{mapname: 's1', value: 10, count: 3},
{mapname: 's2', value: 4, count: 4},
{mapname: 's3', value: 12, count: 13}
]
Morris.Bar ({
element: 'bar-example',
data: theData,
xkey: 'mapname',
ykeys: ['value'],
labels: ['No. of days'],
barRatio: 0.4,
xLabelAngle: 35,
hideHover: 'auto',
barColors: function (row, series, type) {
console.log("--> "+row.label, series, type);
if(row.label == "s1") return "#AD1D28";
else if(row.label == "s2") return "#DEBB27";
else if(row.label == "s3") return "#fec04c";
}
});
var items = $("#bar-example").find( "svg" ).find("rect");
$.each(items,function(index,v){
var value = theData[index].count;
var newY = parseFloat( $(this).attr('y') - 20 );
var halfWidth = parseFloat( $(this).attr('width') / 2 );
var newX = parseFloat( $(this).attr('x') ) + halfWidth;
var output = '<text style="text-anchor: middle; font: 12px sans-serif;" x="'+newX+'" y="'+newY+'" text-anchor="middle" font="10px "Arial"" stroke="none" fill="#000000" font-size="12px" font-family="sans-serif" font-weight="normal" transform="matrix(1,0,0,1,0,6.875)"><tspan dy="3.75">'+value+'</tspan></text>';
$("#bar-example").find( "svg" ).append(parseSVG(output));
});
The output looks like this.输出看起来像这样。
But what you can try, is change the values here但是你可以尝试的是改变这里的值
var newY = parseFloat( $(this).attr('y') - 20 );
to something like像
var halfHeight = parseFloat( $(this).attr('height') / 2 );
var newY = parseFloat( $(this).attr('y') - halfHeight );
This change is untested, but will act as a good starting point.此更改未经测试,但将作为一个很好的起点。
Regards :)问候 :)
You can extend Morris to achieve this.您可以扩展 Morris 来实现此目的。 Please refer to this answer to see a full working snippet.
请参阅此答案以查看完整的工作片段。
Add a property:添加属性:
Bar.prototype.defaults["labelTop"] = false;
Add a prototype to draw the label:添加原型来绘制标签:
Bar.prototype.drawLabelTop = function(xPos, yPos, text) {
var label;
return label = this.raphael.text(xPos, yPos, text)
.attr('font-size', this.options.gridTextSize)
.attr('font-family', this.options.gridTextFamily)
.attr('font-weight', this.options.gridTextWeight)
.attr('fill', this.options.gridTextColor);
};
Modify the Bar.prototype.drawSeries
protoype, adding these lines (before the last else):修改
Bar.prototype.drawSeries
原型,添加这些行(在最后一行之前):
if (this.options.labelTop && !this.options.stacked) {
label = this.drawLabelTop((left + (barWidth / 2)), top - 10, row.y[sidx]);
textBox = label.getBBox();
_results.push(textBox);
}
Then set the labelTop
property to true in your Morris Bar config:然后在您的 Morris Bar 配置中将
labelTop
属性设置为 true:
labelTop: true
I find better to pass via jQuery to an empty p我发现通过 jQuery 传递给空 p 更好
This is the final result: Final Result这是最终结果:最终结果
This is my code:这是我的代码:
HTML HTML
<div class="row">
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-6 ">
<p class="numero num1"></p>
</div>
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-6 ">
<p class="numero num2"></p>
</div>
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-6 ">
<p class="numero num3"></p>
</div>
<div class="col-lg-3 col-md-3 col-sm-6 col-xs-6 ">
<p class="numero num4"></p>
</div>
</div>
JS Below the chart code. JS下面的图表代码。 Remember to change theData variable to the one you're using in your code.
请记住将theData变量更改为您在代码中使用的变量。
var b=1;
jQuery('rect').each(function (i) {
$('p.num'+b).text(theData[i].value);
b++;
});
CSS CSS
.numero{
text-align: center;
font-size: 18px !important;
font-weight: 600 !important;
}
I also have added a class to each color.我还为每种颜色添加了一个类。
Hope this helps anybody :) Happy coding!希望这可以帮助任何人:) 快乐编码!
尝试将此代码放在CSS 中
.morris-hover{position:absolute;z-index:1000;}
Here is a start, its a bit hacky, but it gets the job done:这是一个开始,它有点hacky,但它完成了工作:
JS JS
var graphData= [
{mapname: 's1', value: 10, count: 3},
{mapname: 's2', value: 4, count: 4},
{mapname: 's3', value: 12, count: 13}
]; //store this to its own var so we can access the counts later
var bar=Morris.Bar ({
element: 'bar-example',
data:graphData,
xkey: 'mapname',
ykeys: ['value'],
labels: ['No. of days'],
barSizeRatio:0.4, //I think you meant barSizeRatio, not barSize
xLabelAngle: 35,
hideHover: 'auto',
barColors: function (row, series, type) {
//console.log("--> "+row.label, series, type);
if(row.label == "s1") return "#AD1D28";
else if(row.label == "s2") return "#DEBB27";
else if(row.label == "s3") return "#fec04c";
}
});
//first, find the width of a bar
//this is bar-example width, divided by three, times barSizeRatio
var barWidth=($('#bar-example').width()/3)*(0.4);
//now each thru each bar (rect)
jQuery('rect').each(function (i) {
var pos=$(this).offset();
var top=pos.top;
top-=20; //originate at the top of the bar
//get the height of the bar
var barHeight=bar.bars[i];
top+=barHeight/2; //so we can now stick the number in the vertical-center of the bar as desired
var left=pos.left;
//move it over a bit
left+=barWidth/2;
//-size of element...
left-=10;//should approximately be horizontal center
$div=jQuery('<div class="count" style="top:'+top+'px;left:'+left+'px;" />');
$div.text(graphData[i].count); //get the count
jQuery('body').append($div); //stick it into the dom
console.log($div);
});
and some CSS to style the divs和一些 CSS 来设置 div 的样式
CSS CSS
.count{
position:absolute;
width:10px;
height:20px;
line-height:20px;
color:white;
font-weight:bold;
}
hopefully you can run with that to create the exact effect you are looking for希望您可以使用它来创建您正在寻找的确切效果
enter link description here在此处输入链接描述
barColors:function(e){
if(e.label=="2014"){
return "#EA7756";
}else if(e.label=="2015"){
return "#91D180";
}else{
return "#FDAA4C";
}
}
@chiliNUT @abi1964 I placed multiple charts but I am having a problem w/the CSS. @chiliNUT @abi1964 我放置了多个图表,但我在使用 CSS 时遇到了问题。 The data, bar height etc. all works fine but the #s are being stacked on top.
数据、条形高度等一切正常,但#s 被堆叠在顶部。 I've tried every iteration of position in the CSS.
我已经尝试了 CSS 中位置的每次迭代。 Ideas or a Fiddle how to fix this?
想法或小提琴如何解决这个问题?
image of multiple graphs w/#'s stacking带有#'s stacking 的多个图形的图像
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.