【问题标题】:DC js charts, crossfilter not filtering on clickDC js图表,交叉过滤器不过滤点击
【发布时间】:2019-03-22 14:44:41
【问题描述】:

*更新了更多相关代码。 *再次更新:删除图表分组会导致此错误:“无法获取未定义或空引用 dc.js (5575,9) 的属性‘分类’”。我正在使用 dc 3.0.11。

我有一个问题,即我的 dc 图表在单击图表上的选择时没有相互过滤。如果我调用一个函数来明确地这样做,它确实有效,但我想避免这种情况。

这是我的一般做法:

  • 我确实包含了 dc.css(如果重要的话)
  • 我的 crossfilter ndx 和尺寸是正确的

我正在定义我的图表而不使用 .on renderlet(这是原因吗?)

        var masterData = [];





$(document).ready(function () { //UPDATED CODE START


var siteurl = 'site';
var ItemCount= GetItemCount(siteurl, 'list');
createRestUrl(siteurl,ItemCount,'list');

});  // UPDATED CODE END



function GetItemCount(siteurl, ListName){
var ItemCount='';
$.ajax({
    url: siteurl+"/_api/web/lists/GetByTitle('"+ListName+"')/ItemCount", 
    method: "GET",
    async: false,
    headers: { "Accept": "application/json; odata=verbose" },
    success: function (data) {
        ItemCount = data.d.ItemCount;
    },
    error: function (data) {
        console.log(data);
    }
});
return ItemCount;   

}   // GetItemCount END


function createRestUrl(siteurl, ItemCount, ListName) {


    var listServiceUrl = siteurl+ "/_api/web/lists/GetByTitle('" + ListName + "')/Items";


//Rest call to process each items of list
    $.when(processList(listServiceUrl,ItemCount)).done(function () { 

console.log("FINISHED");
console.log("--------");
console.log(masterData);

    var ndx = crossfilter(masterData),
        clientMgr = ndx.dimension(function(d) { return d.clientMgr}),                        
        otherTeammates = ndx.dimension(function(d) { return d.otherTeammates}),
        topic = ndx.dimension(function(d) { return d.topic}),
        status = ndx.dimension(function(d) { return d.status}),
        team = ndx.dimension(function(d) { return d.team}),
        requester = ndx.dimension(function(d) { return d.requester}),
        requesterBusiness = ndx.dimension(function(d) { return d.requesterBusiness}),
        submitted = ndx.dimension(function(d) { return d.submitted}),
        clientMgrGroup = clientMgr.group(),
        otherTeammatesGroup = otherTeammates.group(),
        topicGroup = topic.group(),
        statusGroup = status.group(),
        teamGroup = team.group(),
        requesterGroup = requester.group(),
        requesterBusinessGroup = requesterBusiness.group(),
        submittedGroup = submitted.group();

        var teamChart = dc.rowChart("#team_chart", "team");
        var clientMgrChart = dc.pieChart("#mgr_chart", "mgr");
        var statusChart = dc.pieChart("#status_chart", "status");
        var requesterChart = dc.rowChart("#requester_chart", "request");
        var requesterBusinessChart = dc.pieChart("#requesterBusiness_chart", "requestBusiness");
        var timeSelect = dc.lineChart("#time_chart", "time");
        var topicChart = dc.pieChart("#topic_chart", "topic");
        var teamNum = dc.numberDisplay("#teamNum", "teamNum");

        Date.prototype.addDays = function(days) {
        var dat = new Date(this.valueOf());
        dat.setDate(dat.getDate() + days);
        return dat;
        }

        var thisDay = new Date();
        var todayMinSix = thisDay.addDays(-30);
        var todayPlusSix = thisDay.addDays(30);

        teamChart
        .dimension(team)
        .group(teamGroup)
        .width(800)
        .height(200)
        .transitionDuration(3000)
        .ordering(function(d) { return -d.value })
            .elasticX(true)
            .x(d3.scaleLinear().domain([0, 100]))
        .colors('#58D3F7')

        //teamNum
        //.valueAccessor(function(d) { return d})
        //.formatNumber(d3.format())
        //.group(teamGroup)

        clientMgrChart
        .dimension(clientMgr)
        .group(clientMgrGroup)
        .width(300)
        .height(300)
        .transitionDuration(3000)

            statusChart
        .dimension(status)
        .group(statusGroup)
        .height(200)
        .width(500)
        .innerRadius(95)
        .transitionDuration(3000)
        .colors(d3.scaleOrdinal().domain(["02 - Work-In-Progress", "01 - Pending Initial Review"])
                       .range(['#58D3F7', '#2E9AFE']))

        requesterChart
            .dimension(requester)
            .group(requesterGroup)
            .height(200)
            .width(800)
            .gap(10)
        .transitionDuration(3000)
            .ordering(function(d) { return -d.value })
            .elasticX(true)
        .colors('#F78181')
            .x(d3.scaleLinear().domain([0, 100]));

        requesterBusinessChart
        .dimension(requesterBusiness)
        .group(requesterBusinessGroup)
        .height(300)
        .width(300)
        .innerRadius(117)
        .transitionDuration(3000)
        .colors('#F78181')

        topicChart
        .dimension(topic)
        .group(topicGroup)
        .height(200)
        .width(500)
        .innerRadius(95)
        .transitionDuration(3000)
        .colors(d3.scaleOrdinal().domain(["New Report / Interface", "General Support", "One-Time Data Set", "Recurring Data Set", "Modify Existing Report / Interface", "Production Issue"])
                       .range(['#F5A9A9', '#F78181', '#FA5858', '#F6CECE', '#F8E0E0', "#FBEFEF"]))

        timeSelect
        .width(1700)
            .height(150)
            .dimension(submitted)
            .group(submittedGroup)
            .transitionDuration(1000)
            .elasticY(true)
            .renderArea(true)
            .x(d3.scaleTime().domain([todayMinSix, thisDay]))
            .xUnits(d3.timeDays)
            .mouseZoomable(false)
            .xAxis();

        teamChart.render(); 
        statusChart.render();
        requesterChart.render();
        topicChart.render();


});
}

//Step 3: Rest call to process each items of list
function processList(nextUrl,ItemCount) {

    var dfd = new $.Deferred();

    if (nextUrl == undefined) {
        dfd.resolve();
        return;
    }

getJSONDataFromUrl(nextUrl).done(function (listItems) {

        TotalItemCount = TotalItemCount+listItems.d.results.length;
        console.log("getJSON called");
        var items = listItems.d.results;
            var next = listItems.d.__next;

            $.when(processList(next,ItemCount)).done(function (){
            dfd.resolve();
            });

    $.each(items, function(index, obj){
        items = {};
        items.clientMgr = obj.ClientMgr;                         //Assigned To - might not be the right field
        items.otherTeammates = obj.OtherTeammatesEngaged;        //Assigned To - might not be the right field
        items.topic = obj.Topic;
        items.status = obj.Status;
        items.team = obj.Team; 
        items.requester = obj.RequesterLOB;
        items.submitted = obj.Submitted;
        items.requesterBusiness = obj.RequesterBusinessGroup;
        console.log("looping through each");

        var convert = new Date(items.submitted);
        items.submittedConvert = moment(convert).format('L');
        items.submitted = convert;  

        var assignName = items.clientMgr;
        items.clientMgr = assignName;       

        masterData.push(items);
        console.log(items.requesterBusiness);
        console.log(items.status);
    });  //.each END



}); // getJSONDataFromUrl END

return dfd.promise();

}   // processList END

我很久以前就有这个工作,但随着项目变得越来越复杂,一路上出现了一些问题。

【问题讨论】:

  • 请使用 [dc.js] 标签来回答与图表库相关的问题。 [dc] 是一个古老的 Unix“桌面计算器”。 :-)
  • 我们需要更多代码(或者最好是运行示例)来诊断这个问题,而无需大量猜测。图表不会相互过滤的最常见原因是 1) 它们在不同的 chartGroups 中(图表构造函数的可选第二个参数)或 2) 它们在同一维度上或 3)(不太可能但可能)它们在不同的交叉过滤器实例上.不,普通操作不需要渲染组件。
  • 如果有帮助,我可以用所有代码更新帖子。这只是很多。图表未使用同一组定义,但我尝试将它们全部作为同一组的一部分并从这些声明中完全删除该组,但它仍然不起作用。图表也不在同一维度上。我将编辑上面的代码以提供更多详细信息。
  • 将所有图表放在不同的chartGroups 上是很不常见的。在图表上指定第二个参数非常罕见,除非您有多个交叉过滤器实例。图表只会在同一个图表组中过滤(这就是图表组所做的)。你想在那里做什么?
  • 我认为这是我困惑了一段时间的产物,比如试图捎带同事的代码:) 我不需要为此进行图表分组是有道理的。所以我删除了它们,但随后我收到错误“无法获取未定义或空引用 dc.js (5575,9) 的属性‘分类’”当我单击图表时发生这种情况,所以看起来过滤正在尝试。

标签: dc.js crossfilter


【解决方案1】:

我猜这个错误是指使用了.classed() 从 5575 开始的几行。以下是直到 5575 的行:

    if (d3.sum(_chart.data(), _chart.cappedValueAccessor)) {
        pieData = pie(_chart.data());
        _g.classed(_emptyCssClass, false);
    } else {
        // otherwise we'd be getting NaNs, so override
        // note: abuse others for its ignoring the value accessor
        pieData = pie([{key: _emptyTitle, value: 1, others: [_emptyTitle]}]);
        _g.classed(_emptyCssClass, true);
    }

if (_g) {

https://github.com/dc-js/dc.js/blob/3.0.11/dc.js#L5565-L5575

所以(除了行号有点偏离)_g 为空是一个很好的猜测。

正如我在上面的评论中所指出的,这可能表明图表在呈现之前已被重绘。如果您创建图表但不渲染它,就会发生这种情况。渲染初始化诸如比例和父元素之类的东西,例如保存图表的<g>

创建图表时,您可以指定图表组或为您选择默认图表组。图表在该组中注册,当该组中的任何图表被过滤时,所有图表都被重绘

在上面的代码中,您渲染了特定的图表(其中 4 个),但还有更多图表需要您初始化但不渲染(8 个)。特别是,除了clientMgrChart 之外,所有的饼图都被渲染了。当您稍后单击图表时,该图表可能会在尝试重绘时崩溃。

应该是nice if dc.js implemented a more helpful error for this case,因为您当前必须猜测“嗯,null,猜测某些内容没有正确设置”,并且知道必须在重绘之前进行渲染。

注意:初始化图表然后调用

更加健壮
dc.renderAll();

而不是手动渲染每一个。

【讨论】:

  • 完美!这成功了!十分感谢你的帮助。我从这次交流中学到了很多 :) 我现在还有一个问题 - 当我选择过滤器时 numberDisplay (teamNum) 没有重绘。我写的方式有问题吗(它不再在单独的图表组中)?
  • 使用上面的代码,我希望 numberDisplay 在过滤任何图表时会发生变化teamChart 除外。这是因为a group does not observe its own dimension's filters。如果您希望 teamGroup 观察现有 team 维度上的过滤器,则必须定义另一个团队维度。
  • 也就是说,将数字显示附加到 crossfilter.groupAll 而不是 dimension.group 通常更有意义 - 因为它只显示单个值,它将显示一组中的最大值,但它将显示 groupAll 的单个值。
  • 太棒了,非常感谢您的帮助!谢谢!
【解决方案2】:

其他人注意:使用 dc.js 3.1.2,我的个人 rowCharts 在单击时不会自行设置动画。交叉过滤器中的其他图表确实有动画效果。

很迷茫,一路追查dc.js调用栈,学到了很多。

最终,失败的根本原因是我页面的 HTML 中没有链接 dc.css。

另一个很好的“告诉”你没有正确链接 dc.css 是 rowChart 垂直线没有呈现。

截图

带有 CSS 的 rowChart - 单击任何条都会触发动画。

没有 CSS 的 rowChart - 单击任何条都不会触发动画。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多