javascript - d3.js 中的主要刻度

标签 javascript jquery d3.js

我绘制了一个 d3 图表,其中有许多日期,并且这些日期每天都在增加,所以我的 x 轴看起来被这么多的 daes 捕获,所以我想在我的图表 n x 轴中设置主要刻度。我尝试过但无法得到它,所以请建议。 这是我的代码:

<div id="chart"></div>
    </div>
    <script>
    var jsonURL = 'avb.json';

    var myData = [];
    var fliterdata = [];
    var tempdata = [];
    var selectop = "";
    var selectDate = false;
    var chartType = chartType || 'bar';

    function filterJSON(json, key, value) {
        var result = [];
        for (var foo in json) {
         var extractstr = json[foo][key] ;
          extractstr=String(extractstr);

            if (extractstr.slice(3)== value) {

                result.push(json[foo]);
            }
        }
        return result;
    }

    function selectValue(d) {
        switch (selectop) { //d object select particular value for Y axis 
            case "01":
                return d.val001;
                break;
            case "02":
                return d.val002;
                break;
            default:
                //console.log("default");
                return d.val001;
        }
    }

    var margin = {
        top: 20,
        right: 0,
        bottom: 80,
        left: 40
    };
    var width = 700 - margin.left - margin.right;
    var height = 500 - margin.top - margin.bottom;



    var xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1);
    var xAxis = d3.svg.axis()
     .scale(xScale)
      .tickValues(xScale.domain().filter(function(d, i) { return !(i % 2);                       }))
   .orient("bottom");

    var yScale = d3.scale.linear().range([height, 0]);
    var hAxis = d3.svg.axis().scale(xScale).orient('bottom').tickFormat(d3.time.format("%Y-%m-%d"));
    var vAxis = d3.svg.axis().scale(yScale).orient('left');
    var tooltip = d3.select('body').append('div')
        .style('position', 'absolute')
        .style('background', '#f4f4f4')
        .style('padding', '5 15px')
        .style('border', '1px #333 solid')
        .style('border-radius', '5px')
        .style('opacity', 'o');

    var line = d3.svg.line()
        .x(function(d) {
            return xScale(d.date);
        })
        .y(function(d) {
            return yScale(selectValue(d));
        })
        .interpolate("monotone")
        .tension(0.9);


    function render(filterByDates) {


        d3.select('svg').remove();

        if (filterByDates) {
            selectDate = true;
            tempData = fliterdata;
            console.log("before date fliter data", tempData);
            var date1 = new Date(document.getElementById('field1').value);
            var date2 = new Date(document.getElementById('field2').value);

            tempData = tempData.filter(function(d) {
                console.log(date1, date2);
                //  alert(date1);
                return d.date >= date1 && d.date <= date2;
            });
        }


        xScale.domain(tempData.map(function(d) {
            return d.date;
        }).sort(function(a, b) {
            return a > b;
        }));

        yScale.domain([0, d3.max(tempData, function(d) {
            return +selectValue(d);
        })]);

        var svg = d3.select('#chart').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 + ")");

        svg

            .append('g')
            .attr("class", "x axis")
            .attr("transform", "translate(0," + height + ")")
            .call(hAxis)
            .selectAll("text")
            .style("text-anchor", "end")
            .attr("dx", "-.8em")
            .attr("dy", "-.55em")
            .attr("transform", "rotate(-90)");

        svg
            .append('g')
            .attr("class", "yaxis")
            .call(vAxis)

        if (chartType == 'bar') {
            svg
                .selectAll(".bar") //makes bar
                .data(tempData)
                .enter().append("rect")
                .attr("class", "bar")
                .style("fill", "red")
                .attr("x", function(d) {
                    return xScale(d.date);
                }).attr("width", xScale.rangeBand())
                .attr("y", function(d) {


                    return yScale(selectValue(d));
                }).attr("height", function(d) {

                    console.log("as", d.value);
                    return height - yScale(selectValue(d));
                }).on('mouseover', function(d) {
                    tooltip.transition()
                        .style('opacity', 1)

                    tooltip.html(d.value)
                        .style('left', (d3.event.pageX) + 'px')
                        .style('top', (d3.event.pagey) + 'px')
                    d3.select(this).style('opacity', 0.5)
                }).on('mouseout', function(d) {
                    tooltip.transition()
                        .style('opacity', 0)
                    d3.select(this).style('opacity', 1)
                });
        }

        if (chartType == 'line') {
            svg.append("path") // Add the line path.
                .data(tempData)
                .attr("class", "line")
                .attr("d", line(tempData));
        }

    }

    d3.json(jsonURL, function(data) {

        myData = data; //data from json in mydata
        myData.forEach(function(d) {

            d.date = new Date(d.date);
        });

        $("#listbox").on("click", function() {

            var key = $(this).val();
            console.log("key:", key);
            var value = $('#listbox option:selected').text();
            //value = "int" + value;
            console.log("vaue:", value);

            selectop = String(key);

            selectop = selectop.slice(-2);
            console.log("mydata: ", myData);
            console.log("selectops:", selectop);

            fliterdata = filterJSON(myData, key, value); //selected value from user and picks the whole element that contains that attribute
            tempData = fliterdata; //graph made by temp data
            if (selectDate)
                render(true);
        });
    });

    function selectChartType(type) {
        chartType = type;
        render(true);
    }
    </script>
</body>
</html>

{
"name": "ABC",
 "date": 1461176704000,
 "attr001": "intSIGN1",
 "val001": "200", 
"attr002": "intSIGN2", 
"val002": "70", 
"attr003": "dt1SIGN3", 
"val003": "57.5",
 "attr004": "intSIGN4",
 "val004": "670",
 "attr005": "strSIGN5", 
"val005": "Traceinvalid"
 }, 

{ "name": "ABC",
 "date": 1459125900000,
 "attr001": "intSIGN1",
 "val001": "500", 
"attr002": "intSIGN2", 
"val002": "70", 
"attr003": "intSIGN3", 
"val003": "100.00",
 "attr004": "intSIGN4",
 "val004": "670",
 "attr005": "strSIGN5", 
"val005": "Traceinvalid"
 },




 { "name": "XYZ", 
"date": 145877400000, 
"attr001": "intVISSE1",
 "val001": "100", 
"attr002": "intVISSE2",
 "val002": "7",
 "attr003": "dt1VISSE3",
 "val003": "39.67",
 "attr004": "intVISSE4",
 "val004": "160",
 "attr005": "strSIGN5", 
"val005": "not found"
 },

 { "name": "XYZ",
 "date": 1461535200000,
 "attr001": "intVISSE1", 
"val001": "50", 
"attr002": "intVISSE2",
 "val002": "70",
 "attr003": "dt1VISSE3",
 "val003": "300.00",
 "attr004": "intVISSE4",
 "val004": "230",
  "attr005": "strSIGN5", 
"val005": "found"
 },

{ "name": "XYZ", 
"date": 1461384717000, 
"attr001": "intVISSE1",
"val001": "300", 
"attr002": "intVISSE2",
 "val002": "10", 
"attr003": "dt1VISSE3", 
"val003": "500.00",
 "attr004": "intVISSE4",
 "val004": "350",
 "attr005": "strSIGN5", 
"val005": "not found" },

{ "name": "ABC", 
"date": 1459051873000, 
"attr001": "intSIGN1",
"val001": "300", 
"attr002": "intVISSE2",
 "val002": "10", 
"attr003": "dt1VISSE3", 
"val003": "500.00",
 "attr004": "intVISSE4",
 "val004": "350",
 "attr005": "strSIGN5", 
"val005": "not found" } ]

最佳答案

据我了解

var xScale = d3.scale.ordinal().rangeRoundBands([0, width], .1);

将为您提供域内每个唯一值(在本例中为日期)的比例,这就是 d3 无法减少图表中的刻度数的原因。尝试使用

var xScale = d3.time.scale()

这将帮助您更好地控制刻度和您想要实现的格式。

您可以找到有关 d3 时间刻度如何工作的更多信息 here你可以找到一个真正的问题 nice explained answer为什么某些比例更适合您的数据。

更新:

如果您想要使用序数标尺减少刻度数,一个不错的选择是使用

var xAxis = d3.svg.axis()
.scale(xScale)
.tickValues(xScale.domain().filter(function(d, i) { return !(i % 2); }))
.orient("bottom");

其中过滤函数将帮助确定轴的刻度值。

关于javascript - d3.js 中的主要刻度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37169319/

相关文章:

javascript - Angular JS (Ionic) 数据数组到 $scope 元素

javascript - jQuery UI Accordion + Cookies - 默认关闭?

javascript - 使用jquery隐藏带有动画的div

javascript - D3 饼图更新后未计算新路径值

javascript - 如何仅增加 C3 饼图图例的宽度。不适用于整个图表

javascript - 在 Nodejs 中加载 HTML 文件

javascript - 如何从一组元素中删除除创建的元素之外的所有边框?

JQuery验证: errorPlacement doesn't get called

javascript - BootStrap : Uncaught TypeError: $(. ..).datetimepicker 不是函数

d3.js - d3js (v4) Canvas 强制布局在节点上带有文本