Google column chart bars width - angularjs

I've got angular2 and google charts.
My component code is:
playstoreRatingChart(data) {
let dateTitle: any = 'Date';
let ratingTitle: any = 'Rating';
let dataTable = [[dateTitle, ratingTitle, { "role": 'annotation' }, { role: 'style' }]];
data.playstore_rating.forEach(function (obj) {
let newDate = new Date(obj.year, obj.month-1, obj.day)
let rating = obj.rating;
let rowRating = Number(rating.toFixed(2));
let test = parseFloat(rating.toFixed(2));
let row = [newDate, test, test, 'width:22; stroke-color: #871B47; stroke-opacity: 0.6; stroke-width: 12; fill-color: #BC5679; fill-opacity: 0.2'];
dataTable.push(row)
});
this.testPlayStore = {
chartType: 'ColumnChart',
dataTable: dataTable,
bar: { groupWidth: '100%' }
}
}
I don't know, why, but exactly this chart (i have few charts more on this page) have columns with 1px width and I cannot change its width.

Related

custom legend hide() does not remove data labels

I am building a project using React with a doughnut and bar chart. Working with Chart.js 3.xx.
I am trying to make my custom legend functional. I want to make data fractions disappear when the user clicks my legend items - like in the native legend, and optimally also remove the data and make the chart present it's updated data after removal.
I also use data labels to present percentage of the data on the fractions.
import ChartDataLabels from 'chartjs-plugin-datalabels';
I came across this topic: ChartJS - Show/hide data individually instead of entire dataset on bar/line charts
and used this suggested code there:
function chartOnClick(evt) {
let chart = evt.chart
const points = chart.getElementsAtEventForMode(evt, 'nearest', {}, true);
if (points.length) {
const firstPoint = points[0];
//var label = myChart.data.labels[firstPoint.index];
//var value = myChart.data.datasets[firstPoint.datasetIndex].data[firstPoint.index];
let datasetIndex = firstPoint.datasetIndex, index = firstPoint.index;
if (firstPoint.element.hidden != true) {
chart.hide(datasetIndex, index);
} else {
chart.show(datasetIndex, index);
}
}
}
options: { // chart options
onClick: chartOnClick
}
It almost works, but the hide() method doesn't remove the fraction's percentage data label when activated, whereas when clicking the native legend it does remove it entirely.
I tried looking in the plugin's docs but didn't manage to find how to remove a single label.
How can I achieve what I am looking for?
EDIT:
Options Object:
export const doughnutOptsObj = {
onClick: chartOnClick,
responsive: true,
maintainAspectRatio: false,
layout: { padding: { top: 16, bottom: 16 } },
hoverOffset: 32,
plugins: {
legend: {
display: true,
position: 'bottom',
},
datalabels: {
formatter: (value, dnct1) => {
let sum = 0;
let dataArr = dnct1.chart.data.datasets[0].data;
dataArr.map((data) => {
sum += Number(data);
});
let percentage = ((value * 100) / sum).toFixed() + '%';
return percentage;
},
color: ['#fbfcfd'],
font: { weight: 'bold' },
// display: false, <-- this works and makes all of the data labels disappear
},
},
};
It seems that the onClick function is working properly.
I have tried the attached code, leveraging on toggleDataVisibility API, and it's working as requested (codepen: https://codepen.io/stockinail/pen/abKNJqJ):
function chartOnClick(evt) {
let chart = evt.chart
const points = chart.getElementsAtEventForMode(evt, 'nearest', {}, true);
if (points.length) {
const firstPoint = points[0];
chart.toggleDataVisibility(firstPoint.index);
chart.update();
}
}

How to change React chartjs-2 legend click functionality to hide all except the one clicked?

React Chartjs-2 : How can I implement the functionality where when a legend is clicked, instead of hiding the clicked legend, all other legends/datasets get hidden?
By modifying the legend onClick function:
Options:
options: {
plugins: {
legend: {
onClick: newLegendClickHandler
}
}
}
OnClick:
var newLegendClickHandler = function (e, legendItem, legend) {
let datasetIndex = legendItem.datasetIndex;
let ci = legend.chart, metaSets = [];
for (let i = 0; i < legend.chart.data.datasets.length; i++) {
metaSets.push(ci.getDatasetMeta(i));
}
metaSets.forEach(function(meta) {
meta.hidden = meta.index === datasetIndex ? false : true;
});
ci.update();
};
For more on this topic: Legend
A fiddle to see this in effect: JSFiddle
Edit:
Chartjs 2 does it almost the same way.
Options:
options: {
legend: {
onClick: newLegendClickHandler
}
}
OnClick:
var newLegendClickHandler = function (e, legendItem) {
let datasetIndex = legendItem.datasetIndex;
let ci = this.chart, metaSets = [];
for (let i = 0; i < ci.data.datasets.length; i++) {
metaSets.push(ci.getDatasetMeta(i));
}
metaSets.forEach(function(meta) {
meta.hidden = meta.index === datasetIndex ? false : true;
});
ci.update();
};
Another Fiddle: 2.9.4 Fiddle
Edit 2:
If you are using chartjs 2.6.0 you need to change meta.index to meta.controller.index

How to align the header of the PDF to the center in jspdf-autotable?

I have to place the heading of the pdf in the center. I have tried many ways but could not find a possible way that worked.
I am using the jspdf and jspdf-autotable package to form the pdf using reactjs.
var options = {
didDrawPage: function (data) {
// Header
doc.text(heading, 20, 10,{
halign: 'center',
valign: 'middle'
});
}
};
doc.autoTable(columns, rows, options);
doc.save('table.pdf');
The above code is not working for me.
To align specific header column:
you must add column name in head definition
add function to hook didParseCell
const head = [
{
code: 'Code',// <- here
qty: 'Qty',
}
];
const doc = new jsPDF();
autoTable(doc, {
head: head,
body: someData,
didParseCell: (hookData) => {
if (hookData.section === 'head') {
if (hookData.column.dataKey === 'qty') {
hookData.cell.styles.halign = 'right';
}
}
}
});
doc.save('fileName.pdf');
Try this.
var columns = [...];
var rows = [...];
var options = {
headStyles:{
valign: 'middle',
halign : 'center'
}
};
doc.autoTable(columns, rows, options);
doc.save('table.pdf');

How to highlight cell in Anychart table when I click on that cell

Is there any way to highlight a cell in an Anychart table when I click on the cell?
I tried the following code, but it doesn't work.
table.listen("click",function(e){e.cellBorder(" #ff0000")});
Unfortunately, the current version of AnyChart 8.2.1 tables does not support events. But you can implement this functionality with some extra code. For details, please, check the sample below.
anychart.onDocumentReady(function () {
// set stage
var stage = anychart.graphics.create("container");
// create table
var table = anychart.standalones.table();
// set table content
table.contents([
[
null,
"2003 Sales",
"2004 Sales"
],[
"January",
"$10000",
"$12000"
],[
"February",
"$12000",
"$15000"
],[
"March",
"$18000",
"$16000"
],[
"April",
"$11000",
"$15000"
],
[
"May",
"$9000",
"$14000"
]
]);
var contents = table.contents();
// Set rows height.
table.rowsHeight(70);
table.getRow(0).fontWeight(900);
table.getCol(0).width(70).fontWeight(900); // Set first column width 70 px and bold the text
table.getCol(1).width(300);
table.getCol(2).width(300);
table.cellFill("#E1E1E1"); // Set table background color
// adjust table border and position text in each cell into center
table.cellBorder("#B8B8B8").vAlign("middle").hAlign("center");
// set table container and initiate draw
table.container(stage).draw();
var colsCount = table.colsCount();
var widths = [];
for(var i = 0; i<colsCount;i++) {
var width = table.getCol(i).width();
widths.push(width);
}
var rowHeight = table.rowsHeight();
// buffer cell
var buffer = 0;
var cont = document.getElementById('container');
cont.addEventListener('click', function(e) {
var x = e.clientX;
var y = e.clientY;
var indX = null;
var indY = null;
if(x < widths[0]) {
indX = 0;
}
if(x> widths[0] && x<widths[0] + widths[1]) {
indX = 1;
}
if(x > widths[0] + widths[1]) {
indX = 2;
}
indY = Math.floor(y / rowHeight);
// color selected cell
if (contents[indY]) {
table.getCell(indY,indX).fill("#0000ff", 0.2);
}
// color back
if (buffer !=0) {
buffer.fill("#e1e1e1")
}
// save selected cell to buffer
if (contents[indY]) {
buffer = table.getCell(indY,indX);
}
});
});
html, body, #container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
<link href="https://cdn.anychart.com/releases/8.2.1/css/anychart-ui.min.css" rel="stylesheet"/>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-base.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-table.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.2.1/js/anychart-ui.min.js"></script>
<div id="container"></div>

jqplot - set custom color for bar charts based on label name

I have a backbone app that dynamically renders multiple bar charts with different data sets and I have no way of knowing which label name will show up. For example, if given a set of labels: "strawberry", "vanilla", "chocolate", I would like to set the color for "strawberry" to pink every time that category shows up in a graph.
Is there a way to set a specific color on a bar based upon its label value?
Here is my current code:
collectCategories: function(aggregates) {
var categories = {};
_.each(aggregates, function(aggregate) {
for (var category in aggregate) {
categories[category] = true;
}
});
categories = _.keys(categories);
categories.sort();
return categories;
},
render: function() {
var container = this.$el;
container.empty();
var aggregates = this.collection.map(function(purchase) {
return purchase.aggregates();
});
var categories = this.collectCategories(aggregates);
var datasets = _.map(categories, function(category) {
var row = _.map(aggregates, function(aggregate) {
var qtyInCategory = aggregate[category];
return qtyInCategory ? qtyInCategory : 0;
});
return row;
});
var labels = this.collection.map(function(purchase) {
return purchase.get('purchase_date').substr(0, 10);
});
if (datasets.length > 0) {
this.renderPlot(datasets, labels, categories);
}
return this;
},
renderPlot: function(datasets, labels, categories) {
var seriesLabels = _.map(categories, function(category) {
return { label: category};
});
var customSeriesColors =
var plot = $.jqplot('bar-charts-container', datasets, {
stackSeries: true,
captureRightClick: true,
seriesDefaults:{
renderer:$.jqplot.BarRenderer,
rendererOptions: {
barMargin: 30,
varyBarColor: true
},
pointLabels: {
show: false
}
},
series: seriesLabels,
seriesColors:
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
ticks: labels
},
yaxis: {
padMin: 0
}
},
legend: {
show: true,
location: 'e',
placement: 'outside'
}
});
Since you have access to your labels when you plot, why not just define the colours there too?
seriesColors: colorsForLabels(seriesLabels)
Elsewhere in the object:
colorsForLabels: function(labels) {
return _.map(labels, function(labelObj) {
switch (labelObj.label) {
case 'strawberry':
return 'pink';
case: 'vanilla':
return 'white';
default:
# return a random colour from a list
}
});
}
The default is an open question; if you could have labels that don’t match the predefined list, you’ll have to choose from a list of alternates.

Resources