如何使用geoChoroplethChart和dc.js在Mapchart的路径上添加标签或自定义值?

时间:2018-08-06 05:41:24

标签: dc.js crossfilter

enter image description here

var IndChart = dc.geoChoroplethChart("#india-chart");

var states = data.dimension(function (d) {
            return d["state_name"];
        });

var stateRaisedSum = states.group().reduceSum(function (d) {
            return d["popolation"];
        });

     IndChart
                        .width(700)
                        .height(500)
                        .dimension(states)
                        .group(stateRaisedSum)
                        .colors(d3.scale.ordinal().domain().range(["#27AE60", "#F1C40F", "#F39C12","#CB4335"]))
                        .overlayGeoJson(statesJson.features, "state", function (d) { //console.log(d.properties.name);
                            return d.id;
                        })
                        .projection(d3.geo.mercator().center([95, 22]).scale(940))
                        .renderLabel(true)
                         .title(function (d) { console.log(d); return d.key + " : " + d.value ;
                        })
                        .label(function (d) { console.log(d);}) ;

希望使用dc.js在地图中为每个路径添加标签或自定义值(25%,在地图图表屏幕快照中添加)。

1 个答案:

答案 0 :(得分:1)

在上面的评论中,您找到或创建了一个working example来回答您的原始问题。然后,您问如何使它适用于同一页面上的两个图表。

这只是正确选择选择器,还需要了解dc.js如何呈现和重新绘制工作。

首先,该示例完成

var labelG = d3.select("svg")

,它将始终选择页面上的第一个svg元素。您可以通过使选择器更具体,例如#us-chart svg#us-chart2 svg来解决此问题,但是我更喜欢使用chart.select()函数,该函数在特定图表的DOM树中进行选择。

接下来,请务必记住,渲染图表时,它将删除所有内容并从头开始。本示例两次调用dc.renderAll(),因此对第一个图表所做的任何修改都会在第二个渲染中丢失。

相反,更改任何过滤器都会发生重绘,并且它会逐渐更改图表,并保留先前的内容。

我更喜欢听dc.js chart events并进行修改。这样,每次绘制或重绘图表时,都可以进行修改。

尤其是,我尝试尽可能使用pretransition事件来修改图表。这是在绘制后立即发生的,因此您有机会进行更改而不会出现任何故障或暂停。

始终在呈现图表之前添加事件侦听器。

为两个图表添加(相同)处理程序然后进行渲染,如下所示:

    usChart.on('pretransition', function(chart) {
        var project = d3.geo.albersUsa();

        var labelG = chart.select("svg")
            .selectAll('g.Title')
              .data([0])
            .enter()
            .append("svg:g")
            .attr("id", "labelG")
            .attr("class", "Title");

        labelG.selectAll("text")
            .data(labels.features)
            .enter().append("svg:text")
            .text(function(d){return d.properties.name;})
            .attr("x", function(d){return project(d.geometry.coordinates)[0];})
            .attr("y", function(d){return project(d.geometry.coordinates)[1];})
            .attr("dx", "-1em");
    });

    usChart2.on('pretransition', function(chart) {
        var project = d3.geo.albersUsa();

        var labelG = chart.select("svg")
            .selectAll('g.Title')
              .data([0])
            .enter()
            .append("svg:g")
            .attr("id", "labelG")
            .attr("class", "Title");

        labelG.selectAll("text")
            .data(labels.features)
            .enter().append("svg:text")
            .text(function(d){return d.properties.name;})
            .attr("x", function(d){return project(d.geometry.coordinates)[0];})
            .attr("y", function(d){return project(d.geometry.coordinates)[1];})
            .attr("dx", "-1em");
    });
    dc.renderAll();

我在那里使用了另外一个技巧:由于pretransition在渲染和重绘时都会发生,但是我们只想添加一次这些标签,所以我使用这种模式:

        .selectAll('g.Title')
          .data([0])
        .enter()
        .append("svg:g")
        .attr("class", "Title");

这是最简单的data binding:它表示我们要一个g.Title,其数据只是值0。由于我们为g元素提供了Title类,因此可以确保只添加一次该元素。

最后,此表达式的结果是回车选择,因此,我们仅在text层是新的时才添加Title元素。

Fork of your fiddle