how to set background color in excel js, depending on the value? - node.js

How can I get the values of a column and paint the background color depending on the value.
I have the column: "Stock" and I need to know when the value is 0 to make the background red.
in this way I paint the first row of the header. Is it possible to implement the logic to obtain the mentioned values?
ws.eachRow((row, rowNumber) => {
row.eachCell((cell) => {
console.log(rowNumber);
if (rowNumber == 1) {
cell.fill = {
type: "pattern",
pattern: "solid",
fgColor: { argb: "2563EB" },
};
}
cell.font = {
color: { argb: "FFFFFF" },
bold: true,
};
cell.border = {
top: { style: "thin" },
left: { style: "thin" },
bottom: { style: "thin" },
right: { style: "thin" },
};
});
row.commit();
});
ws.addRows(arrProducts);
.......

Related

X-axis multiple colored label for bar chart using chart.js

I need x-axis labels in different colors, I am using "chart.js". I tried below code but it is not working, just showing single color-
scales: {
xAxes: [{
ticks: {
fontColor: [
'rgba(245,88,97,1)',
'rgba(245,88,97,1)',
'rgba(245,88,97,1)',
'rgba(145,151,163,1)',
'rgba(70,180,220,1)',
'rgba(70,180,220,1)',
'rgba(70,180,220,1)'
]
}
}]
}
Output:
Need:
You can make use of the Plugin Core API. It offers different hooks that may be used for executing custom code. In below code snippet, I use the afterDraw hook to draw text of the same color as the corresponding bar.
chart.data.labels.forEach((l, i) => {
var value = chart.data.datasets[0].data[i];
var x = xAxis.getPixelForValue(l);
ctx.fillStyle = chart.data.datasets[0].backgroundColor[i];
ctx.fillText(l, x, yAxis.bottom + 17);
});
When drawing your own tick labels, you need to instruct Chart.js not to display the default labels. This can be done through the following definition inside the chart options.
scales: {
xAxes: [{
ticks: {
display: false
}
}],
You also need to define some padding for the bottom of the chart, otherwise you won't see your custom tick labels.
layout: {
padding: {
bottom: 20
}
},
Please take a look at the following sample code that illustrates how to change the labels on the x-axis depending on the values.
new Chart('myChart', {
type: 'bar',
plugins: [{
afterDraw: chart => {
var ctx = chart.chart.ctx;
var xAxis = chart.scales['x-axis-0'];
var yAxis = chart.scales['y-axis-0'];
ctx.save();
ctx.textAlign = 'center';
ctx.font = '12px Arial';
chart.data.labels.forEach((l, i) => {
var value = chart.data.datasets[0].data[i];
var x = xAxis.getPixelForValue(l);
ctx.fillStyle = chart.data.datasets[0].backgroundColor[i];
ctx.fillText(l, x, yAxis.bottom + 17);
});
ctx.restore();
}
}],
data: {
labels: ["-3", "-2", "-1", "0", "+1", "+2", "+3"],
datasets: [{
label: "My First Dataset",
data: [60, 59, 80, 81, 60, 55, 40],
fill: false,
backgroundColor: ['rgba(245,88,97,1)', 'rgba(245,88,97,1)', 'rgba(245,88,97,1)', 'rgba(145,151,163,1)', 'rgba(70,180,220,1)', 'rgba(70,180,220,1)', 'rgba(70,180,220,1)'],
borderWidth: 1
}]
},
options: {
layout: {
padding: {
bottom: 20
}
},
scales: {
xAxes: [{
ticks: {
display: false
}
}],
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
canvas {
max-width: 300px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js"></script>
<canvas id="myChart" height="200"></canvas>

Highchart y axis need 2 category each having 3 sub category

I am using high chart version v4.0.4, i have worked bar chart like mentioned below i need output with there bar for every year details given below
I am working on below high chart code
var data_first_vd = 0;
var data_second_vd = 0;
var glb_data_ary = [];
var dynamicval1 = 5.85572581;
var dynamicval2 = 0.16091656;
if((dynamicval1>1) || (dynamicval2>1)){
var data_tit = 'Value';
var data_val = '${value}';
var prdelvalaxis = 1000000;
}else{
prdelvalaxis = 1000;
data_tit = "Value";
data_val = "${value}";
}
data_first_vd=5.86;
data_second_vd =0.16;
var data_first_ud =1397.128;
var data_second_ud = 28.145;
data_first_ud_lbl = '1.40M';
data_second_ud_lbl = '28K';
data_first_vd_lbl = '5.86M';
data_second_vd_lbl = '161K';
data_first_vd_lbl_xaxis = '$5.86M';
data_second_vd_lbl_xaxis = '$161K';
var ud1 = 1397;
var ud2 = 28;
var vd1 = 6;
var vd2 = 0;
$('#id').highcharts({
credits: { enabled: false },
chart: {
type: 'bar',
height: 200,
marginLeft: 120,
marginBottom:50,
marginTop: 47,
marginRight:30,
plotBorderWidth: 0,
},
title: {
text: null
},
xAxis: {
drawHorizontalBorders: false,
labels: {
groupedOptions: [{
rotation: 270,
}],
rotation: 0,
align:'center',
x: -30,
y: 5,
formatter: function () {
if (curYear === this.value) {
return '<span style="color:#6C9CCC;">' + this.value + '</span>';
}
else if (prevYear === this.value) {
return '<span style="color: #ED7D31;">' + this.value + '</span>';
}
else if ('VALUE' === this.value) {
return '<span style="color:#942EE1;">' + this.value + '</span>';
}
else{
return '<span style="color: #E124D2;">' + this.value + '</span>';
}
},
useHTML:true
},
categories: [{
name: "UNITS",
categories: [2017, 2016]
},{
name: "VALUE",
categories: [2017, 2016]
}
],
},
yAxis: [{ // Primary yAxis
labels: {
format: data_val,
formatter: function () {
if(this.value!=0){
return '$'+valueConverter_crt(this.value*prdelvalaxis);
}else{
return this.value;
}
},
style: {
color: '#942EE1'
}
},
title: {
text: "<span style='font-size: 12px;'>"+data_tit+"</span>",
style: {
color: '#942EE1'
},
useHTML:true
}
}, { // Secondary yAxis
title: {
text: "<span style='font-size: 12px;'>Units</span>",
style: {
color: '#E124D2'
},
useHTML:true
},
labels: {
format: '{value}',
formatter: function () {
if(this.value!=0){
return cal_pro_del_xaxis(this.value);
}else{
return this.value;
}
},
style: {
color: '#E124D2'
}
},
opposite: true
}],
tooltip: { enabled: false },
exporting: { enabled: false },
legend: { enabled: false },
plotOptions: {
series: {
dataLabels: {
inside: true,
align: 'left',
enabled: true,
formatter: function () {
return this.point.name;
},
color: '#000000',
},
stacking: false,
pointWidth: 15,
groupPadding: 0.5
},
},
series: [{
yAxis: 1,
data: [{y:1397.128,name:data_first_ud_lbl,color:'#6C9CCC'},{y:28.145,name:data_second_ud_lbl,color:'#ED7D31'}],
}, {
data: [null,null,{y:5.86,name:data_first_vd_lbl_xaxis,color:'#6C9CCC'},{y:0.16,name:data_second_vd_lbl_xaxis,color:'#ED7D31'}],
}]
});
I need out put like below chart This chart i draw in paint.
Here 3 bar added in every year
Please help me to achieve this

Passing arrays to Flot

At the end of a functioning JS I have three arrays of x- and y-coordinates, return [theta_plot, omega_plot, e_plot];, that I would like to send to Flot for plotting:
function myPlot(theta_plot, omega_plot, e_plot) {
"use strict";
function doPlot(position) {
$.plot("#placeholder", [
{
data: theta_plot,
label: "Angle (rad)",
yaxis: 1,
color: "red"
},
{
data: omega_plot,
label: "Angular Velocity (rad/sec)",
yaxis: 2,
color: "green"
},
{
data: e_plot,
label: "Energy (J)",
yaxis: 3,
color: "blue"
}
],
{
yaxes: [
{
font: { color: "red" }
},
{
font: { color: "green" }
},
{
font: { color: "blue" }
},
{ alignTicksWithAxis: position === "left" ? 1 : null }
],
legend: { position: "nw" }
}
);
}
doPlot("left");
}
The outer function is my latest attempt to pass these arrays to Flot, without success. The inner function is obviously Flot. Placing doPlot in my JS produces the desired result, though JSLint complains that they are not defined, as it should. However, for purposes of organization I would like doPlot in my HTML. Question: How do I make doPlot aware of my arrays?
Just replace
function doPlot(position) {
with
function doPlot(theta_plot, omega_plot, e_plot, position) {
and call the new function directly without using the myPlot() function.

JointJs Top Bottom Ports

I'm trying to use JointJS with ports feature:
(...)
var model = joint.shapes.devs.Model({
size: { width: width, height: height },
label: node.label,
inPorts: node.inputPorts,
outPorts: node.outputPorts,
attrs: {
'.label': { text: node.label, 'ref-x': .4, 'ref-y': .2 },
rect: { fill: '#2ECC71' },
'.inPorts circle': { fill: '#16A085' },
'.outPorts circle': { fill: '#E74C3C' }
}
(...)
But input ports appears on the left and output ports on the right.
I want input ports on the top and output on the bottom.
Which is the best way to change the port position to Top-Bottom using joint.shapes.devs.Model ?
Thanks in advance.
The positions of ports are calculated in devs.Model.prototype.getPortAttrs. What you can do is just swap x and y port coordinates like in the example below.
joint.shapes.devs.Model = joint.shapes.basic.Generic.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
markup: '<g class="rotatable"><g class="scalable"><rect class="body"/></g><text class="label"/><g class="inPorts"/><g class="outPorts"/></g>',
portMarkup: '<g class="port port<%= id %>"><circle class="port-body"/><text class="port-label"/></g>',
defaults: joint.util.deepSupplement({
type: 'devs.Model',
size: { width: 1, height: 1 },
inPorts: [],
outPorts: [],
attrs: {
'.': { magnet: false },
'.body': {
width: 150, height: 250,
stroke: 'black'
},
'.port-body': {
r: 10,
magnet: true,
stroke: 'black'
},
text: {
fill: 'black',
'pointer-events': 'none'
},
'.label': { text: 'Model', 'ref-x': 10, 'ref-y': .2, 'ref': '.body' },
// CHANGED: find better positions for port labels
'.inPorts .port-label': { dy:-30, x: 4 },
'.outPorts .port-label':{ dy: 15, x: 4 }
//
}
}, joint.shapes.basic.Generic.prototype.defaults),
getPortAttrs: function(portName, index, total, selector, type) {
var attrs = {};
var portClass = 'port' + index;
var portSelector = selector + '>.' + portClass;
var portLabelSelector = portSelector + '>.port-label';
var portBodySelector = portSelector + '>.port-body';
attrs[portLabelSelector] = { text: portName };
attrs[portBodySelector] = { port: { id: portName || _.uniqueId(type) , type: type } };
// CHANGED: swap x and y ports coordinates ('ref-y' => 'ref-x')
attrs[portSelector] = { ref: '.body', 'ref-x': (index + 0.5) * (1 / total) };
// ('ref-dx' => 'ref-dy')
if (selector === '.outPorts') { attrs[portSelector]['ref-dy'] = 0; }
//
return attrs;
}
}));
JS Fiddle: http://jsfiddle.net/kumilingus/L2f73cbf/
Update:
Here is an example how to achieve the same with JointJS v1.0.1+.
There is no need for extending the class with PortsModelInterface anymore. The ports API is now implemented by joint.dia.Element i.e. arbitrary element can be enriched with ports easily.
var shape = new joint.shapes.devs.Model({
inPorts: ['in1', 'in2'],
outPorts: ['out1', 'out2'],
ports: {
groups: {
'in': { position: 'top'},
'out': { position: 'bottom' }
}
}
});
JSFiddle: http://jsfiddle.net/kumilingus/trk63agg/
For more information please see the docs:
ports API
port layouts
Just change position name in your joint.shapes.devs.Model creation as follow:
new joint.shapes.devs.Model({
position: { x: x, y: y },
size: { width: 90, height: 90 },
inPorts: ['in1'],
outPorts:['out1'],
attrs: {
rect: { fill: '#2ECC71' },
'.inPorts circle': {r:10, fill: '#16A085' },
'.outPorts circle': { fill: '#E74C3C' }
},
ports: {
groups: {
'in': {
position: {
name: 'top'
},
attrs: {
'.port-body': {
r: 1
}
}
},
'out': {
position: {
name: 'bottom'
},
attrs: {
'.port-body': {
r: 1
}
}
}
}
}
});
Consider the position name changed to top and bottom

Highcharts change crosshairs color by number of visible series

What we are trying to do is to:
display crosshairs only if number of visible series > 1 (color: black)
otherwise disable crosshairs or alternatively set color transparent
Here are our problems:
independent of the number of visible series the crosshairs is not shown for the first hover (but for all subsequent hovers)
our main problem is that the color is not changing although the console.log displays that the color is correctly set due to the number of visible series
Please see the fiddle: example
Thanks for your suggestions!
$(function () {
var chart = new Highcharts.Chart({
chart: {
type: 'area',
renderTo: 'container'
},
title: {
text: 'Historic and Estimated Worldwide Population Growth by Region'
},
subtitle: {
text: 'Source: Wikipedia.org'
},
xAxis: {
categories: ['1750', '1800', '1850', '1900', '1950', '1999', '2050'],
tickmarkPlacement: 'on',
title: {
enabled: false
}
},
yAxis: {
title: {
text: 'Billions'
},
labels: {
formatter: function () {
return this.value / 1000;
}
}
},
tooltip: {
formatter: function () {
// show crosshairs only if visible series >1, else transparent
var nVisible = 0;
for (var i = 0; i < chart.series.length; i++) {
if (chart.series[i].visible) {
nVisible++;
};
if (nVisible > 1) {
break;
};
};
if (nVisible > 1) {
chart.options.tooltip.crosshairs = {
width: 1.5,
dashStyle: 'solid',
color: 'black'
};
} else {
chart.options.tooltip.crosshairs = {
color: 'transparent'
};
};
console.log(chart.options.tooltip.crosshairs.color);
return this.y + ' Billions';
},
backgroundColor: 'rgba(255,255,255,0.95)'
},
plotOptions: {
area: {
stacking: 'normal',
lineColor: '#666666',
lineWidth: 1,
marker: {
lineWidth: 1,
lineColor: '#666666'
}
}
},
series: [{
name: 'Asia',
data: [502, 635, 809, 947, 1402, 3634, 5268]
}, {
name: 'Africa',
data: [106, 107, 111, 133, 221, 767, 1766]
}, {
name: 'Europe',
data: [163, 203, 276, 408, 547, 729, 628]
}, {
name: 'America',
data: [18, 31, 54, 156, 339, 818, 1201]
}, {
name: 'Oceania',
data: [2, 2, 2, 6, 13, 30, 46]
}]
});
});
Don't add crosshair in real time, instead when chart is initialized, enable crosshair and then manage color by attr() updating. For example: http://jsfiddle.net/D5DME/3/
Code:
tooltip: {
crosshairs: [{
width: 1.5,
dashStyle: 'solid',
color: 'black'
}, false],
formatter: function () {
// show crosshairs only if visible series >1, else transparent
var nVisible = 0;
for (var i = 0; i < this.series.chart.series.length; i++) {
if (this.series.chart.series[i].visible) {
nVisible++;
};
};
if(this.series.chart.tooltip.crosshairs[0]) {
if (nVisible > 1) {
this.series.chart.tooltip.crosshairs[0].attr({
stroke: 'black'
});
} else {
this.series.chart.tooltip.crosshairs[0].attr({
stroke: 'rgba(0,0,0,0)'
});
}
}
return this.y + ' Billions';
},
backgroundColor: 'rgba(255,255,255,0.95)'
},
It looks to me that the tooltip code is the wrong place to be trying this. I would use the series hide and show event handlers to detect how many series were showing (a simple counter which increments in show and decrements in hide would work).
http://api.highcharts.com/highstock#plotOptions.series.events.hide
You could try the chart setting options depending on the count.
However, I'm not sure that simply settting chart.options.tootlip. will work dynamically the way you want.

Resources