问题
I am using Wasil C3 angularjs directives (http://wasil.org/angularjs-directive-for-c3-js-tutorial) and there is also a sample plunker through compilation (http://plnkr.co/edit/wiiUMk2KoHHrK4D1HdNu?p=preview). As need to set the back ground color of the sub chart, I am trying to create a custom attribute directive (subChartBgColor), so that on which ever chart I want to set back ground color of the sub chart I can simple put the attribute sub-chart-bg-color on Html tag, but some how it is not working. Can any one help me to fix my subChartBgColor directive :
(function() {
angularDemo.directive('subChartBgColor', [function() {
return {
restrict: 'A',
scope: false,
link: function(scope, element, attrs) {
d3.selectAll("svg > g:nth-child(3)").insert("rect", ":first-child").attr("width", "100%").attr("height", "100%").attr("fill", "yellow");
}
}
}]);
回答1:
Firstly, I'm not familiar with angular. Basically, after the chart is created, you insert the rectangle, and then style the background colour of the rectangle.
Since I don't know angular very well, and I don't know how the timing of events / binding works, I have used setTimeout
to wait for the chart to be created, before inserting the rectangle. You will need to move this code into the appropriate directive.
It's the exact same code as the other answer:
setTimeout(function(){
d3.selectAll("svg > g:nth-child(3)").insert("rect", ":first-child").attr("width", "100%").attr("height", "100%").attr("fill", "yellow");
}, 1000);
See: http://plnkr.co/edit/CBcIsW9QnHaeXicmwZk2?p=preview
回答2:
I'm not sure if I understand correctly what do you mean by "subchart" and I'm not an expert in C3/D3 charts, but I'm not sure if you can change background color for a specific series, if that's what you meant.
But...
If you'd like to change background for whole chart, you can do this in (at least) two ways.
First way
Using your method, but with few small changes. This will alter background of whole chart, including legend, etc.:
d3.selectAll("svg > .bgRect").remove();d3.selectAll("svg").insert("rect", ":first-child").attr("class", "bgRect").attr("width", "100%").attr("height", "100%").attr("fill", "yellow");
Please notice the .bgRect class I added. It is meant to identify rectangle you are adding in order to be able to remove() it and re-add again. I did it, because if you just call insert() multiple time, you'll always see first rectangle inserted, because every added after it will be under/before it in HTML (prepended), i.e.
<!-- third one inserted --> <rect class="bgRect" width="100%" height="100%" fill="red"></rect> <!-- second one inserted --> <rect class="bgRect" width="100%" height="100%" fill="green"></rect> <!-- first one inserted --> <rect class="bgRect" width="100%" height="100%" fill="yellow"></rect> <!-- some other code -->
I've changed CSS selector, because yours was inserting rectangle element in place, where it wouldn't ever be visible.
Second way
(It is probably closer to what you need and in my opinion more proper way of doing this.)
By accessing charting area directly and simply changing it's CSS with d3.style() method:
d3.selectAll("svg .c3-zoom-rect").style("fill", "yellow").style("opacity", 1);
You can call it as many times as you want and it won't alter HTML markup while color will be adjusted.
Another way of achieving this would be adding/changing CSS class to this element with classed() and defining it's colors in regular CSS, i.e. bg-red, bg-blue etc.
One final thought
Consider changing d3.selectAll() to d3.select() with more specific selector. It might be helpful when using more then one chart on a page.
Hope it helps.
来源:https://stackoverflow.com/questions/30665391/custom-attribute-type-directive-to-set-the-background-color-of-c3-chart