I am trying to change the border/background of an AnnotationChart from Google's Chart library. If I use the standard backgroundColor options, the chart fails to render. Per this discussion, it seems that the backgroundColor options available on other chart types aren't directly accessible on the AnnotationChart, but are available through undocumented options. When I try this, though, the chart is unchanged. Below is the code and resulting chart; any ideas?
Without chart option
var chart = new google.visualization.AnnotationChart(document.getElementById('chart_div'));
var options = {
thickness: 1.5,
displayAnnotations: true,
colors: dataColors,
displayZoomButtons: false,
displayExactValues: false,
displayDateBarSeparator: true,
};
chart.draw(data, options);
With:
var chart = new google.visualization.AnnotationChart(document.getElementById('chart_div'));
var options = {
thickness: 1.5,
displayAnnotations: true,
colors: dataColors,
displayZoomButtons: false,
displayExactValues: false,
displayDateBarSeparator: true,
chart: {
backgroundColor: {
fill:'black',
stroke: 'white',
strokeSize: 1
},
chartArea: {
backgroundColor: {
fill: 'blue',
stroke: 'red',
strokeSize: 1
}
}
}
};
chart.draw(data, options);
Either way, graph looks like this:
The background color can be set using it like this. Read the documentation here
Edit your code like this
var options = {
displayAnnotations: true,
displayZoomButtons: false,
displayExactValues: false,
displayDateBarSeparator: true,
chart: {
backgroundColor: 'blue',
chartArea: {
backgroundColor: '#FFF000',
},
},
fill: 50,
};
I tried using strokeWidth and stroke but I think it is not being supported yet or I am using it incorrectly.
Working JSFIDDLE
I've had my own issues with the lack of customization options for Google Charts and one workaround is to use Javascript to modify the SVG after it is generated in order to produce the look you want.
I've put together a quick fiddle based on the template Annotation Chart in the Google Charts Reference, but the applicable lines of code are below. It's not pretty (especially if you're using interactive charts, because this requires a MutationObserver to monitor the SVG for changes) but it works and you might be able to clean it up a lot more.
Note: I've noticed interactions with Google Charts (e.g. zooming and panning) tend to bog down a lot in JSFiddle and Codepen etc for some reason, but they're much smoother when used in the wild!
Annotation Chart Fiddle
My Related SO Question
/* One time recoloring of background after SVG creation - for static charts */
var rects = container.getElementsByTagName("rect")
for(var i=0; i<rects.length; ++i) {
if (rects[i].getAttribute('fill') === '#ffffff') {
rects[i].setAttribute('fill', '#99f');
}
}
/* MutationObserver to monitor any changes to SVG and recolor background - for interactive charts */
var observer = new MutationObserver(function(mutations) {
var rects = container.getElementsByTagName("rect")
for(var i=0; i<rects.length; ++i) {
if (rects[i].getAttribute('fill') === '#ffffff') {
rects[i].setAttribute('fill', '#99f');
}
}
});
Related
I need to set a different border color for the legend than the actual chart; whenever I add border color to the chart data, it gets applied to both legend and chart. And I couldn't find any options for setting different border colors for the legend in documentation
Here's a screenshot of what I'm trying to achieve, any idea?:
The only way I have found to do this and some other customisation on the legend is to implement the legend item interface.
The accepted answer here in combination with the legend item interface should be a good start.
Here's a jsfiddle that I made from that answer, but updated for chartjs 3.7.1. The main part to focus on is this:
options: {
plugins: {
legend: {
labels: {
usePointStyle: true,
generateLabels: function(chart) {
var data = chart.data;
if (data.labels.length && data.datasets.length) {
return data.labels.map(function(label, i) {
var meta = chart.getDatasetMeta(0);
var ds = data.datasets[0];
return {
text: label,
fillStyle: ds.backgroundColor[i],
strokeStyle: ds.legendOutline[i],
lineWidth: ds.borderWidth,
hidden: isNaN(ds.data[i]) || meta.data[i].hidden,
index: i
};
});
} else {
return [];
}
}
}
}
}
strokeStyle is the outline property, and I've made a field in the dataset called legendOutline. legendOutline and the data from the dataset are both referenced with i, so the legendOutline[i] points to the label representing data[i]
I am trying to change the color of the Right Y-Axis text from Apps Script. I have a chart template which is called by multiple functions with varying numbers of series. If I need to add a right Y-Axis, the calling routing selects the chart and changes the designated series to Y-Axis 1. this works fine. The issue I have is that, for presentation purposes the background is black and so is the secondary Y axis text. I have been unable to find how to code to change the color.
The following code executes without error but does not achieve the desired result. I believe it only applies to the primary Y-axis
var i = 0;
/** Loop through the charts */
for (var i = 0; i < charts.length; i++) {
/** Select each chart */
var cht = (charts[i]);
sh.getCharts().forEach(cht => {
const container = cht.getContainerInfo();
if (container.getAnchorRow() == row && container.getAnchorColumn() == col) {
/** We now have the chart */
var title = cht.getOptions().get('title')
cht = cht.modify()
// .textStyle().setColor('white').setFontSize(12)
/** The following works but we cannot use variables in setOption */
//.setOption('series', { 12: { textStyle: { color: 'yellow', fontName: 'Calibri', fontSize: 14, visibleInLegend: true }, lineWidth: 4, targetAxisIndex: 1 } })
// .setYAxisTextStyle().setColor('white').setFontSize(12)
.setOption('YAxis', { 1:{TextStyle: {color: 'white',fontName: 'Calibri', fontSize: 14}}})
.build();
sh.updateChart(cht);
}
})
break;
}
12.4 to generate a pdf,charts are drawn by chartist,because chartist is svg based. I can see the chart in browser by html(test-chartist.html right chart).But When I user the command wkhtmltopdf --dpi 300 --page-size A4 test-chartist.html test3.pdf, chart is blank in the test3.pdf. And then I add the flowing js , the result is weirdsize is not right and direction is not right too
Function.prototype.bind = Function.prototype.bind || function (thisp) {
var fn = this;
return function () {
return fn.apply(thisp, arguments);
};
};
can anybody help me? thank you very much
OK,I suddenly found out the answer.
If I add width and height to the chart's options, everything is fine, as below:
var options = {
width: 800,
height: 150,
donut: true,
donutWidth: 30,
startAngle: 240,
total: 30,
showLabel: true,
animation:false
};
new Chartist.Pie('#mainImg', {
series: [10,10]
},options);
I hope it can help others.
I am using Primefaces 6 for my companys charting needs, which relies on jQplot.
For a project, I am trying to overlay a line chart on a stacked bar chart with negative values, to obtain something like this:
The problem is that when I try to add a linechartseries to the same model as the two barchartseries , the linechart becomes a part of the stack when setting setStacked(true); on the model, because Primefaces seems to not allow individual disabling of stacking on series, only per model. So I end up with this when rendering the chart with
<p:chart type="bar" model="#{backingBean.cartesianChartModel}"/>
After some investigation I have notoced that jQplot is capable of disabling Stacking on individual series by passing disableStack : true in the JS options, so the question is if it's posssible to override this in some way on the rendered page,either via PF or via some JS hack? I feel that using the extender only apples to the entire model?
Related issues: Disable individual stacking
By pouring through the documentation I found a solution to the problem, if not the question:
It seems that Primefaces allows for individual series to be excempt from the stack in the series creation in this version, by passing
LineChartSeries.setDisableStack(true);
Simple as that.
I guess it may be possible. I used the extender functionality for some jqPlot hacks in the past.
In my case, for example, I had a Donut Chart defined with an extender function as follows:
private void createDonutModel() {
donutModel = new DonutChartModel();
donutModel.setLegendPosition("s");
donutModel.setLegendPlacement(LegendPlacement.OUTSIDE);
donutModel.setSliceMargin(4);
donutModel.setDataFormat("value");
donutModel.setShadow(false);
donutModel.setExtender("donutExtender");
donutModel.setSeriesColors("B81C40, FFA600, 79B54A");
}
The corresponding javascript was doing some changes to the jqPlot:
/**
* Customized jqPlot JQuery layout of the Donut Chart for Status Dashboard.
*/
function donutExtender() {
this.cfg.seriesDefaults = {
// make this a donut chart.
renderer:$.jqplot.DonutRenderer,
rendererOptions:{
thickness: 26,
ringMargin: 0,
fill: true,
padding: 0,
sliceMargin: 4,
// Pies and donuts can start at any arbitrary angle.
startAngle: -90,
showDataLabels: false,
// By default, data labels show the percentage of the donut/pie.
// You can show the data 'value' or data 'label' instead, or 'percent'
dataLabels: 'value',
shadow: false
}
}
this.cfg.gridPadding = {
top: 0, right: 0, bottom: 0, left: 0
}
this.cfg.legend = {
show: false
}
this.cfg.grid = { drawBorder: false,
shadow: false,
background: "transparent"
};
}
So you may try something like this in your case ?
Leave the extension configuration of your series empty, except for the one you are interested in...
function chartExtender() {
this.cfg.series = [
{ //...
},
{ // ...
},
{
disableStack: true
}
]
}
Worth having a shot ...
I use a google maps ColumnChart to reprensent the elevation in a map.
I also use a mouseover to print info and show the correspondent position.
When a column in the chart is clicked, it popups an info balloon, like here:
http://4.bp.blogspot.com/-4I8oi3WqY5o/UIZnzbXql_I/AAAAAAAAAcE/GO4wl6I2-lM/s1600/Charts.png
This balloon is ok for desktops, but a pain for mobile (very hard to close, etc).
How can I completely disable it? It has to do with the second data column passed to the chart.
No balloons!
Thanks!
L.
EDIT
Code added by request:
var option = {
legend: 'none',
backgroundColor: 'transparent',
colors: ["#C9CFF5"],
titleColor: '#C9CFF5',
focusBorderColor: '#00AA00',
titleY: 'Elevation (m)',
tooltip: { trigger: 'none' },
bar: { groupWidth: '100%' }
}
// Build data
var data = new google.visualization.DataTable();
data.addColumn('string', 'Sample');
data.addColumn('number', 'Elevation (m):');
for (var i = 0; i < trackmarks.length; i++) {
data.addRow(['', trackaltis[i]]);
}
// Draw the chart using the data within its DIV.
chart = new google.visualization.ColumnChart(document.getElementById('elevation_chart'));
chart.draw(data, option);