Javascript D3制图工具:如何在柱状图目标线(附加水平线)右侧添加标签
我用D3制图工具v4绘制了以下图表。我在这篇文章的底部附上了完整的代码 红线是要实现的目标。以下代码块正在绘制这条线:Javascript D3制图工具:如何在柱状图目标线(附加水平线)右侧添加标签,javascript,d3.js,Javascript,D3.js,我用D3制图工具v4绘制了以下图表。我在这篇文章的底部附上了完整的代码 红线是要实现的目标。以下代码块正在绘制这条线: var targetGoalArr = [7]; svg.selectAll(".targetgoal") .data(targetGoalArr) .enter().append("line") .attr("class", "targetgoal") .attr("x1", 0) .attr("x2", width) .attr("y1", y)
var targetGoalArr = [7];
svg.selectAll(".targetgoal")
.data(targetGoalArr)
.enter().append("line")
.attr("class", "targetgoal")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", y)
.attr("y2", y)
.style("stroke", "#cc0000");
现在,我需要在这一行的右侧和两行中添加文本Growth Target(7)。标签也必须分成两行
下面的屏幕截图显示了所需的输出
我怎样才能实现上述目标
还有一件事我不能画,那就是Y轴的基线。在我的图表(带红线)中,我使用自定义记号数组创建水平线。代码如下:
function draw_yAxis_gridlines() {
return d3.axisLeft(y)
.tickValues(yTicks);
}
svg.append("g")
.attr("class", "grid axis")
.call(draw_yAxis_gridlines()
.tickSize(-width)
);
但是,如果不对Y轴使用自定义记号,则会显示基线,但缺少水平轴网线。我必须同时显示两者
这是我的全部代码:
public function evd_unitary_growth_plan_chart( $data_str ){
ob_start(); ?>
<style> /* set the CSS */
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
.grid line {
stroke: lightgrey;
stroke-opacity: 0.5;
shape-rendering: crispEdges;
}
.grid path {
stroke-width: 0;
}
.axis {
font-size: 13px;
font-family: 'Roboto';
color: #808888;
}
</style>
<script type="text/javascript">
var h = 300;
var w = 750;
var barPadding = 2;
function barColor(data_month, current_month) {
if( parseInt(data_month) >= current_month)
return "#008600";
else
return "#c4c4c4";
}
// set the dimensions and margins of the graph
var margin = {top: 30, right: 20, bottom: 30, left: 40},
width = w - margin.left - margin.right,
height = h - margin.top - margin.bottom;
var data = <?php echo $data_str ?>;
// set the ranges
var x = d3.scaleBand().range([0, width]).padding(0.2);
var y = d3.scaleLinear().range([height, 0]);
var svg = d3.select("#ecbg_unitary").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Scale the range of the data in the domains
x.domain(data.map(function(d) { return d.month; }));
var y_domain_upperBound = d3.max(data, function(d) { return d.points; });
y_domain_upperBound = Math.round(y_domain_upperBound / 10) * 10 + 10;
y.domain([0, y_domain_upperBound]);
// Create Y-Axis tick array to draw grid lines
var yTicks = [];
var tickInterval = 5;
for(var i = 0; i <= y_domain_upperBound; i = i + tickInterval) {
yTicks.push(i);
}
console.log(yTicks);
// gridlines in y axis function
function draw_yAxis_gridlines() {
return d3.axisLeft(y)
.tickValues(yTicks);
}
// Reference line - The red line
var targetGoalArr = [7];
svg.selectAll(".targetgoal")
.data(targetGoalArr)
.enter().append("line")
.attr("class", "targetgoal")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", y)
.attr("y2", y)
.style("stroke", "#cc0000");
// append the rectangles for the bar chart
svg.selectAll("rect")
.data(data)
.enter().append("rect")
.attr("x", function(d) {
return x(d.month);
})
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.points); })
.attr("height", function(d) { return height - y(d.points); })
.attr("fill", function(d){return barColor(d.data_month_number, d.current_month_number)});
// column labels
svg.selectAll("text")
.data(data)
.enter()
.append("text")
.text(function(d) {
return d.points;
})
.attr("text-anchor", "middle")
.attr("x", function(d, i) {
return x(d.month) + x.bandwidth() / 2;
})
.attr("y", function(d) {
return y(d.points) - 10;
})
.attr("font-family", "Roboto")
.attr("font-size", "13px")
.attr("font-weight", "bold")
.attr("fill", "#606668");
// add the x Axis
svg.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// add the Y gridlines
svg.append("g")
.attr("class", "grid axis")
.call(draw_yAxis_gridlines()
.tickSize(-width)
);
</script>
<?php return ob_get_clean();
}
公共职能部门evd统一增长计划图表($data\u str){
ob_start();?>
/*设置CSS*/
.线路{
填充:无;
笔画:钢蓝;
笔画宽度:2px;
}
.网格线{
笔画:浅灰色;
笔划不透明度:0.5;
形状渲染:边缘清晰;
}
.网格路径{
笔画宽度:0;
}
.安讯士{
字体大小:13px;
字体系列:“Roboto”;
颜色:#808888;
}
var h=300;
var w=750;
var=2;
功能条颜色(数据月、当前月){
if(parseInt(数据月)>=当前月)
返回“#008600”;
其他的
返回“#c4c4”;
}
//设置图形的尺寸和边距
var margin={顶部:30,右侧:20,底部:30,左侧:40},
宽度=w-边距。左侧-边距。右侧,
高度=h-边距.顶部-边距.底部;
var数据=;
//设定范围
var x=d3.scaleBand().range([0,width])。padding(0.2);
变量y=d3.scaleLinear().range([height,0]);
var svg=d3.选择(“#ecbg_酉”).追加(“svg”)
.attr(“宽度”,宽度+边距。左侧+边距。右侧)
.attr(“高度”,高度+边距。顶部+边距。底部)
.附加(“g”)
.attr(“转换”、“平移”(+margin.left+)、“+margin.top+”);
//缩放域中数据的范围
x、 域(data.map(函数(d){returnd.month;}));
var y_domain_upperBound=d3.max(数据,函数(d){返回d.points;});
y_domain_upperBound=Math.round(y_domain_upperBound/10)*10+10;
y、 域([0,y_域_上界]);
//创建Y轴记号阵列以绘制网格线
var yTicks=[];
var间隔=5;
对于(var i=0;i要向目标行添加标签,最好创建group(g
)元素,然后向其添加line
和text
元素。可以将g元素转换为正确的y位置,以便可以相对于g定位行和文本
var targetGoalArr = [7];
var target = g.selectAll(".targetgoal")
.data(targetGoalArr)
.enter()
.append("g")
.attr("transform", function(d){
return "translate(0, " + y(d) +")"
})
target.append("line")
.attr("class", "targetgoal")
.attr("x1", 0)
.attr("x2", width)
.attr("y1", 0) //these can be omitted
.attr("y2", 0)
.style("stroke", "#cc0000");
target.append("text")
.text(function(d){ return "Target growth: " + d })
.attr("x", width)
.attr("y", "0.35em")
我想知道为什么你认为D3是一个图表工具…(提示:它不是)如果我误解了,很抱歉。我对这一点完全陌生,希望我的初学者知识能被考虑。如果您能指导我如何完成上述任务,那将是非常好的!完美的解决方案!非常感谢@Tom Shanley!!但是,我需要更改var target=g.selectAll(.targetgoal”)
到var target=svg。selectAll(.targetgoal”)
。为了将标签分成两行,我引用了(两个独立的文本
元素)并对它们进行了相应的定位。@tom shaley,请您建议我如何完成我在这里发布的内容:?