DC js图表,crossfilter不过滤点击
DC js charts, crossfilter not filtering on click
*更新了更多相关代码。
*再次更新:删除图表分组导致此错误:"Unable to get property 'classed' of undefined or null reference 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
我很久以前就有过这个工作,但随着项目变得越来越复杂,过程中出现了一些问题。
我猜这个错误是指使用了从 5575 开始的 .classed()
几行。以下是通往 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,因为您目前必须猜测 "hmm, null, guess something hasn't been set up right" 并且知道渲染必须在重绘之前发生。
注意:初始化图表然后调用
更健壮
dc.renderAll();
而不是手动渲染每一个。
其他人请注意:使用 dc.js 3.1.2,我的个人 rowCharts 在单击时不会自行动画。交叉过滤器中的其他图表确实具有动画效果。
很迷茫,一路追查dc.js调用栈,学到了很多。
最终,失败的根本原因是没有 dc.css 链接到我页面的 HTML。
您没有 dc.css 正确链接的另一个好处 'tell' 是 rowChart 垂直线不呈现。
截图
rowChart With CSS - 单击任何条形图都会触发动画。
没有 CSS 的行图 - 单击任何条形图都不会触发动画。
*更新了更多相关代码。 *再次更新:删除图表分组导致此错误:"Unable to get property 'classed' of undefined or null reference 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
我很久以前就有过这个工作,但随着项目变得越来越复杂,过程中出现了一些问题。
我猜这个错误是指使用了从 5575 开始的 .classed()
几行。以下是通往 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,因为您目前必须猜测 "hmm, null, guess something hasn't been set up right" 并且知道渲染必须在重绘之前发生。
注意:初始化图表然后调用
更健壮dc.renderAll();
而不是手动渲染每一个。
其他人请注意:使用 dc.js 3.1.2,我的个人 rowCharts 在单击时不会自行动画。交叉过滤器中的其他图表确实具有动画效果。
很迷茫,一路追查dc.js调用栈,学到了很多。
最终,失败的根本原因是没有 dc.css 链接到我页面的 HTML。
您没有 dc.css 正确链接的另一个好处 'tell' 是 rowChart 垂直线不呈现。
截图
rowChart With CSS - 单击任何条形图都会触发动画。
没有 CSS 的行图 - 单击任何条形图都不会触发动画。