javascript – 当范围为0-1或0-2时,仅显示d3.js中y轴上的整体值

前端之家收集整理的这篇文章主要介绍了javascript – 当范围为0-1或0-2时,仅显示d3.js中y轴上的整体值前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用d3js来显示网站视图的实时表示.为此,我使用堆栈布局,我现在更新我的数据集 JSON.

当在y轴上仅显示1或2个视图时,与图中的视图量相关,动态相关,轴标签为:1 => 0,0.2,0.4,0.6,0.8,1,轴标号是:2 => 0,0.5,1.5,2这对我的数据集是没有意义的,因为它显示页面的视图,你不能有一半的视图.

我在d3js中有一个线性刻度我基于我的y轴

var y_inverted = d3.scale.linear().domain([0,1]).rangeRound([0,height]);

根据the documentation of rangeRound(),我只能从这个规模中获得整体价值.为了绘制我的轴我使用:

var y_axis = svg.append("g")
    .attr("class","y axis")
    .attr("transform","translate(0,0)")
    .call(y_inverted.axis = d3.svg.axis()
        .scale(y_inverted)
        .orient("left")
        .ticks(5));

因为它是一个实时应用程序,我每秒通过调用更新:

function update(){
    y_inverted.domain([yStackMax,0]);
    y_axis.transition()
        .duration(interval)
        .ease("linear")
        .call(y_inverted.axis);
}

yStackMax是从stacklayout计算出来的,只要我知道用于y值的数据只包含整数.

var yStackMax = d3.max(layers,function(layer) {
    return d3.max(layer,function(d) {
        return d.y0 + d.y;
    });
});

我已经尝试了几件事来为我的y轴获得正确的值.

d3.svg.axis()
    .scale(y_inverted)
    .orient("left")
    .ticks(5).tickFormat(d3.format(",.0f"))

得到我最近的沙发,但它仍然显示0,1

基本上我想要的是,当yStackMax为1时,只有1个tick,当它为2时有2个tick,但是如果yStackMax是12或1,000,它也应该有效

解决方法

简短的答案:您可以动态设置滴答数.将其设置为1,仅显示两个刻度标签
var maxTicks = 5,minTicks = 1;
if (yStackMax < maxTicks) {
    y_axis.ticks(minTicks)
}
else {
    y_axis.ticks(maxTicks)
}

长回答(稍微偏离主题):
在使用你的例子时,我想出了一个相当“完整的解决方案”的所有格式化问题.随意使用它:)

var svg = d3.select("#svg")
var width = svg.attr("width")
var height = svg.attr("height")
var yStackMax = 100000
var interval = 500
var maxTicks = 5
var minTicks = 1

var y_inverted = d3.scale.linear().domain([0,height])
var defaultFormat = d3.format(",.0f")

var format = defaultFormat

var y_axis = d3.svg.axis()
    .scale(y_inverted)
    .orient("left")
    .ticks(minTicks)
    .tickFormat(doFormat)

var y_axis_root;
var decimals = 0;

function countDecimals(v){
    var test = v,count = 0;
    while(test > 10) {
        test /= 10
        count++;
    }
    return count;
}

function doFormat(d,i){
    return format(d,i)
}

function init(){
    y_axis_root = svg.append("g")
        .attr("class","y axis")
        // I modified your example to move the axis to a visible part of the screen
        .attr("transform","translate(150,0)")
        .call(y_axis)
}

// custom formatting functions:
function toTerra(d) { return (Math.round(d/10000000000)/100) + "T" }
function toGiga(d)  { return (Math.round(d/10000000)/100) + "G" }
function toMega(d)  { return (Math.round(d/10000)/100) + "M" }
function toKilo(d)  { return (Math.round(d/10)/100) + "k" }

// the factor is just for testing and not needed if based on real world data
function update(factor){
    factor = (factor) || 0.1;
    yStackMax*=factor
    decimals = countDecimals(yStackMax)
    console.log("yStackMax decimals:",decimals,factor)
    if     (yStackMax < maxTicks) {
        format = defaultFormat
        y_axis.ticks(minTicks)
    }
    else {
        y_axis.ticks(maxTicks)
        if     (decimals < 3 ) format = defaultFormat
        else if(decimals < 6 ) format = toKilo
        else if(decimals < 9 ) format = toMega
        else if(decimals < 12) format = toGiga
        else                   format = toTerra
    }

    y_inverted.domain([yStackMax,0]);
    y_axis_root.transition()
        .duration(interval)
        .ease("linear")
        .call(y_axis);
}

init()
setTimeout(update,200)
setTimeout(update,400)
setTimeout(update,600)

您可以与此HTML代码片段一起尝试:

<!DOCTYPE html>
<html>
    <head>
        <Meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <script type="text/javascript" src="http://mbostock.github.com/d3/d3.v2.js"></script>
    </head>

    <body>
        <div><svg id="svg" width="200" height="300"></svg></div>
        <script src="axis.js"></script>
        <button id="button1" onclick="update(10)">+</button>
        <button id="button2" onclick="update(0.1)">-</button>
    </body>
</html>

我知道这是一个有点偏离的话题,但我通常喜欢提供运行的例子/解决方案.注意附加格式化的东西作为实际问题的奖金.

猜你在找的JavaScript相关文章