dc.js - 在一组中渲染两个 objects(一个图表 - 渲染,一个形状 - 不渲染)?
dc.js - Rendering two objects (one chart - renders, one shape - doesn't) together in one group?
我有两个需要渲染的元素和我想要实现的全局背景(一个完整的仪表板)。
一个是渲染良好的图表。
$scope.riskChart = new dc.pieChart('#risk-chart');
$scope.riskChart
.width(width)
.height(height)
.radius(Math.round(height/2.0))
.innerRadius(Math.round(height/4.0))
.dimension($scope.quarter)
.group($scope.quarterGroup)
.transitionDuration(250);
另一个是三角形,用于更复杂的形状
$scope.openChart = d3.select("#risk-chart svg g")
.enter()
.attr("width", 55)
.attr("height", 55)
.append('path')
.attr("d", d3.symbol('triangle-up'))
.attr("transform", function(d) { return "translate(" + 100 + "," + 100 + ")"; })
.style("fill", fill);
在调用渲染函数时,dc.js 渲染函数被识别并且可以看到图表,但是 d3.js 渲染 () 函数未被识别。
如何将此形状添加到我的 dc.js canvas(一个 svg 元素)。
$scope.riskChart.render(); <--------------Works!
$scope.openChart.render(); <--------------Doesn't work (d3.js)!
我该如何进行这项工作?
编辑:
我修改了 dc.js 以包含我的自定义图表,这是一项正在进行的工作。
dc.starChart = function(parent, fill) {
var _chart = {};
var _count = null, _category = null;
var _width, _height;
var _root = null, _svg = null, _g = null;
var _region;
var _minHeight = 20;
var _dispatch = d3.dispatch('jump');
_chart.count = function(count) {
if(!arguments.length)
return _count;
_count = count;
return _chart;
};
_chart.category = function(category) {
if(!arguments.length)
return _category
_category = category;
return _chart;
};
function count() {
return _count;
}
function category() {
return _category;
}
function y(height) {
return isNaN(height) ? 3 : _y(0) - _y(height);
}
_chart.redraw = function(fill) {
var color = fill;
var triangle = d3.symbol('triangle-up');
this._g.attr("width", 55)
.attr("height", 55)
.append('path')
.attr("d", triangle)
.attr("transform", function(d) { return "translate(" + 25 + "," + 25 + ")"; })
.style("fill", fill);
return _chart;
};
_chart.render = function() {
_g = _svg
.append('g');
_svg.on('click', function() {
if(_x)
_dispatch.jump(_x.invert(d3.mouse(this)[0]));
});
if (_root.select('svg'))
_chart.redraw();
else{
resetSvg();
generateSvg();
}
return _chart;
};
_chart.on = function(event, callback) {
_dispatch.on(event, callback);
return _chart;
};
_chart.width = function(w) {
if(!arguments.length)
return this._width;
this._width = w;
return _chart;
};
_chart.height = function(h) {
if(!arguments.length)
return this._height;
this._height = h;
return _chart;
};
_chart.select = function(s) {
return this._root.select(s);
};
_chart.selectAll = function(s) {
return this._root.selectAll(s);
};
function resetSvg() {
if (_root.select('svg'))
_chart.select('svg').remove();
generateSvg();
}
function generateSvg() {
this._svg = _root.append('svg')
.attr({width: _chart.width(),
height: _chart.height()});
}
_root = d3.select(parent);
return _chart;
}
因为三角形不是bound to any data array,所以不应该调用.enter()
。
试试这个方法:
$scope.openChart = d3.select("#risk-chart svg g")
.attr("width", 55)
.attr("height", 55)
.append('path')
.attr("d", d3.symbol('triangle-up'))
.attr("transform", function(d) { return "translate(" + 100 + "," + 100 + ")"; })
.style("fill", fill);
我想我在谈论如何创建新图表时把事情弄糊涂了,而实际上您只是想向现有图表添加一个交易品种。
为了向现有图表添加内容,最简单的做法是在其 pretransition
或 renderlet
事件上放置一个事件处理程序。 pretransition
事件在图表渲染或重绘后立即触发; renderlet
事件在其动画转换完成后触发。
将您的代码调整为 D3v4/5 并将其粘贴到 pretransition
处理程序中可能如下所示:
yearRingChart.on('pretransition', chart => {
let tri = chart.select('svg g') // 1
.selectAll('path.triangle') // 2
.data([0]); // 1
tri = tri.enter()
.append('path')
.attr('class', 'triangle')
.merge(tri);
tri
.attr("d", d3.symbol().type(d3.symbolTriangle).size(200))
.style("fill", 'darkgreen'); // 5
})
一些注意事项:
- 在图表中使用
chart.select
到 select 个项目。和直接用D3没什么区别,只是安全一点。我们 select 包含 <g>
在这里,这是我们要添加三角形的地方。
- 无论三角形是否已经存在,select它。
.data([0])
是添加一个元素一次的技巧,只有当它不存在时 - 任何大小为 1 的数组都可以
- 如果没有三角形,追加一个并合并到selection中。现在
tri
将恰好包含一个旧三角形或新三角形。
- 定义三角形的任意属性,这里使用d3.symbol定义面积为200的三角形。
我有两个需要渲染的元素和我想要实现的全局背景(一个完整的仪表板)。
一个是渲染良好的图表。
$scope.riskChart = new dc.pieChart('#risk-chart');
$scope.riskChart
.width(width)
.height(height)
.radius(Math.round(height/2.0))
.innerRadius(Math.round(height/4.0))
.dimension($scope.quarter)
.group($scope.quarterGroup)
.transitionDuration(250);
另一个是三角形,用于更复杂的形状
$scope.openChart = d3.select("#risk-chart svg g")
.enter()
.attr("width", 55)
.attr("height", 55)
.append('path')
.attr("d", d3.symbol('triangle-up'))
.attr("transform", function(d) { return "translate(" + 100 + "," + 100 + ")"; })
.style("fill", fill);
在调用渲染函数时,dc.js 渲染函数被识别并且可以看到图表,但是 d3.js 渲染 () 函数未被识别。
如何将此形状添加到我的 dc.js canvas(一个 svg 元素)。
$scope.riskChart.render(); <--------------Works!
$scope.openChart.render(); <--------------Doesn't work (d3.js)!
我该如何进行这项工作?
编辑:
我修改了 dc.js 以包含我的自定义图表,这是一项正在进行的工作。
dc.starChart = function(parent, fill) {
var _chart = {};
var _count = null, _category = null;
var _width, _height;
var _root = null, _svg = null, _g = null;
var _region;
var _minHeight = 20;
var _dispatch = d3.dispatch('jump');
_chart.count = function(count) {
if(!arguments.length)
return _count;
_count = count;
return _chart;
};
_chart.category = function(category) {
if(!arguments.length)
return _category
_category = category;
return _chart;
};
function count() {
return _count;
}
function category() {
return _category;
}
function y(height) {
return isNaN(height) ? 3 : _y(0) - _y(height);
}
_chart.redraw = function(fill) {
var color = fill;
var triangle = d3.symbol('triangle-up');
this._g.attr("width", 55)
.attr("height", 55)
.append('path')
.attr("d", triangle)
.attr("transform", function(d) { return "translate(" + 25 + "," + 25 + ")"; })
.style("fill", fill);
return _chart;
};
_chart.render = function() {
_g = _svg
.append('g');
_svg.on('click', function() {
if(_x)
_dispatch.jump(_x.invert(d3.mouse(this)[0]));
});
if (_root.select('svg'))
_chart.redraw();
else{
resetSvg();
generateSvg();
}
return _chart;
};
_chart.on = function(event, callback) {
_dispatch.on(event, callback);
return _chart;
};
_chart.width = function(w) {
if(!arguments.length)
return this._width;
this._width = w;
return _chart;
};
_chart.height = function(h) {
if(!arguments.length)
return this._height;
this._height = h;
return _chart;
};
_chart.select = function(s) {
return this._root.select(s);
};
_chart.selectAll = function(s) {
return this._root.selectAll(s);
};
function resetSvg() {
if (_root.select('svg'))
_chart.select('svg').remove();
generateSvg();
}
function generateSvg() {
this._svg = _root.append('svg')
.attr({width: _chart.width(),
height: _chart.height()});
}
_root = d3.select(parent);
return _chart;
}
因为三角形不是bound to any data array,所以不应该调用.enter()
。
试试这个方法:
$scope.openChart = d3.select("#risk-chart svg g")
.attr("width", 55)
.attr("height", 55)
.append('path')
.attr("d", d3.symbol('triangle-up'))
.attr("transform", function(d) { return "translate(" + 100 + "," + 100 + ")"; })
.style("fill", fill);
我想我在谈论如何创建新图表时把事情弄糊涂了,而实际上您只是想向现有图表添加一个交易品种。
为了向现有图表添加内容,最简单的做法是在其 pretransition
或 renderlet
事件上放置一个事件处理程序。 pretransition
事件在图表渲染或重绘后立即触发; renderlet
事件在其动画转换完成后触发。
将您的代码调整为 D3v4/5 并将其粘贴到 pretransition
处理程序中可能如下所示:
yearRingChart.on('pretransition', chart => {
let tri = chart.select('svg g') // 1
.selectAll('path.triangle') // 2
.data([0]); // 1
tri = tri.enter()
.append('path')
.attr('class', 'triangle')
.merge(tri);
tri
.attr("d", d3.symbol().type(d3.symbolTriangle).size(200))
.style("fill", 'darkgreen'); // 5
})
一些注意事项:
- 在图表中使用
chart.select
到 select 个项目。和直接用D3没什么区别,只是安全一点。我们 select 包含<g>
在这里,这是我们要添加三角形的地方。 - 无论三角形是否已经存在,select它。
.data([0])
是添加一个元素一次的技巧,只有当它不存在时 - 任何大小为 1 的数组都可以- 如果没有三角形,追加一个并合并到selection中。现在
tri
将恰好包含一个旧三角形或新三角形。 - 定义三角形的任意属性,这里使用d3.symbol定义面积为200的三角形。