3

我在 D3.js 中编写了一个简化的柱形图脚本。

这是一个小提琴:http: //jsfiddle.net/rolfsf/F36Vw/

目的是比较一些比焦点项目更小和更大的项目。

像这样:

在此处输入图像描述

如何选择并突出显示价值 75 万美元的 x 轴标签,以及如何添加标识焦点项目(Ace Widgets)的附加标签?

我正在寻找比瞄准中间更精确的东西;-)

我的数据目前看起来像这样(可以轻松更改):

var data = {

    "sales": [
            [600, 1],
            [650, 2],
            [700, 3],
            [750, 2],
            [800, 1],
            [850, 2],
            [900, 3]
    ]
};

列脚本在这里:

function miniColumnChart(){

    var barWidth = 20;
    var margin = {
        top: 64,
        right: 32,
        bottom: 64,
        left: 32,
        labels: 32
    };
    var height = 300; //overridden by width in call
    var width = 500; //overridden by width in call    
    var chartTitle = ["test"];
    var yAxisLabel = "y axis label";
    var xAxisLabel = "x axis label";
    var xformat = function(d){return d;};
    var focus;

    function chart(selection) {
        var maxBarHeight = height - (margin.top + margin.bottom);
        var chartWidth = width - margin.right - margin.left;

        d3.select('svg').remove();//remove old charts

        selection.each(function(data) {

            var xValue = function(d) { return d[0]; };
            var yValue = function(d) { return d[1]; };

            var x = d3.scale.ordinal()
                .domain(data.map(function(d) { return d[0]; }))
                .rangeRoundBands([margin.labels, chartWidth], 0);

            var y = d3.scale.linear()
                .domain([0, d3.max(data, function(d) { return d[1]; })])
                .range([maxBarHeight, 0])
                .nice();

            var xAxis = d3.svg.axis().scale(x).orient("bottom").tickFormat(xformat);

            //var yAxis = d3.svg.axis().scale(y).orient("left");

            var svgContainer = d3.select(this).append("svg")
                .attr("class", "chart mini-column-chart")
                .attr("width", width)
                .attr("height", height).append("g")
                .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

            svgContainer.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate( 0," + (height - margin.top - margin.bottom) + ")")
                .call(xAxis)

                .append("text")
                .attr("class", "axis-label")
                .attr("x", width/2)
                .attr("text-anchor", "middle")
                .attr("dy", 48)
                .text(xAxisLabel);

            var header = svgContainer.append("text")
                .attr("class", "chart-title")
                .attr("x", width/2)
                .attr("text-anchor", "middle")
                .attr("dy", -32)
                .text(chartTitle);

            var barValues = svgContainer.append("g")
                .attr("class", "bar-values");

            barValues.selectAll("text")
                .data(data)
                    .enter().append("text")
                .attr("x", function(d, i) {
                    return ((i+1) * x.rangeBand());
                })
                .attr("y", function(d) { return y(d[1]);})
                .attr("dy", -5)
                .attr("text-anchor", "middle")
                .text(function(d) {return d[1];});

            svgContainer.append("g")
                .attr("class", "y axis")//.call(yAxis)
                .append("text")
                .attr("class", "axis-label")
                .attr("transform", "rotate(-90)")
                .attr("y", 8)
                .attr("x", -(height-margin.top-margin.bottom))
                //.attr("dy", ".71em")
                .style("text-anchor", "start")
                .text(yAxisLabel);

            var bars = svgContainer.append("g")
                .attr("class", "bars");

            bars.selectAll(".bar")
                .data(data)
                    .enter().append("rect")
                .attr("class", "bar")
                .attr("x", function(d, i) {
                    return ((i+1) * x.rangeBand())-(barWidth/2);
                })
                .attr("y", function(d) { return y(d[1]);})
                .attr("width", barWidth)
                .attr("height", function(d) {
                    return (maxBarHeight -y(d[1]));
                });
        });
    }


    chart.title = function(_) {
        if (!arguments.length) return chartTitle;
        chartTitle = _;
        return chart;
    };

    chart.x = function(_) {
        if (!arguments.length) return xValue;
        xValue = _;
        return chart;
    };

    chart.y = function(_) {
        if (!arguments.length) return yValue;
        yValue = _;
        return chart;
    };

    chart.width = function(_) {
        if (!arguments.length) return width;
        width = _;
        return chart;
    };

    chart.height = function(_) {
        if (!arguments.length) return height;
        height = _;
        return chart;
    };

    chart.barWidth = function(_) {
        if (!arguments.length) return barWidth;
        barWidth = _;
        return chart;
    };

    chart.xformat = function(_) {
        if (!arguments.length) return xformat;
        xformat = _;
        return chart;
    };

    chart.yAxisLabel = function(_) {
        if (!arguments.length) return yAxisLabel;
        yAxisLabel = _;
        return chart;
    };

    chart.xAxisLabel = function(_) {
        if (!arguments.length) return xAxisLabel;
        xAxisLabel = _;
        return chart;
    };

    return chart;
}

d3.select('#chart')
  .datum(data.sales)
  .call(miniColumnChart()
     .title("Similar Companies")
     .xformat(function(d){return '$' + d + 'K';})
     .yAxisLabel("# of Similar Companies")
     .xAxisLabel("Company Size")
);
4

1 回答 1

5

首先,存储对要在g其中绘制轴的选择器的引用:

var xAxisG = svgContainer.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate( 0," + (height - margin.top - margin.bottom) + ")")
  .call(xAxis)

然后,您可以选择其中的所有刻度:

xAxisG.selectAll('.tick')

刻度是g包含text和的元素line,它d3.axis为您创建。然后迭代此选择中的刻度:

.each(function(d, i) {
    // In here, d is the ordinal value associated with each tick
    // and 'this' is the dom element
})

在循环内,您可以“选择”您有兴趣更新的刻度,您可以为其文本着色等:

.each(function(d, i) {
    if(d == 750) {
        d3.select(this)
            .append('text')
            .text("Ace Widgets")
            .attr({
                "text-anchor": "middle",
                dy: 33,
                "font-size": ".8em"
            })
        d3.select(this)
            .selectAll('text')
                .style("fill", "red")
    }

这是更新的jsfiddle

于 2013-10-29T01:23:30.410 回答