How to remove paddings in Bar chart? (Chart.JS) - javascript

Is it possible to remove paddings inside bar chart?
<canvas id="weeksChartFallout" width="660" height="200"></canvas>
var falloutArray = [12, 24, 20, 15, 18, 20, 22, 10, 10, 12, 14, 10, 16, 16];
var dataWeeksFallouts = {
labels: ["16.02", "17.02", "18.02", "19.02", "20.02", "21.02", "22.02", "23.02", "24.02", "25.02", "26.02", "27.02", "28.02", "01.03"],
datasets: [
{
label: "Fallouts",
fillColor: "rgba(63,107,245,0.67)",
data: falloutArray
}
]
};
var fc = document.getElementById('weeksChartFallout').getContext('2d');
window.weeksChartFallout = new Chart(fc).Bar(dataWeeksFallouts,{
barShowStroke : false,
barValueSpacing : 4, //distance between bars
barValueWidth: 20,
scaleShowLabels: false,
scaleFontColor: "transparent",
tooltipEvents: []
});
I mean space between first bar and left line and, especially space between last Bar and end of the chart (screenshot).
Here is my Fiddle

The x scale left and right paddings are calculated in the calculateXLabelRotation. If you have only these kind of charts you could simply replace this function to return no padding, like below
var originalCalculateXLabelRotation = Chart.Scale.prototype.calculateXLabelRotation
Chart.Scale.prototype.calculateXLabelRotation = function () {
originalCalculateXLabelRotation.apply(this, arguments);
this.xScalePaddingRight = 0;
this.xScalePaddingLeft = 0;
}
Fiddle - http://jsfiddle.net/ov9p5qhz/
Note that there is still some spacing on the left and right - that comes from your barValueSpacing: 4 option.
If you have other charts on the page that you don't want to keep separate, use Chart.noConflict()

Related

plotly colorscale in scatter data plot

Using marker:{color:x} in javascript plotly (http://jsfiddle.net/d8bt1qof/), I can color-code my
data:
But how can I change the colorscale?
Different colorscales seems to be available (https://plotly.com/javascript/colorscales/), but the usage is only explained for heatmap plots. And adding colorscale: 'Portland' seems not to work.
scattergl trace markers can also have a colorschale. I found a reference for it in the documentation here:
colorscale
Parent: data[type=scattergl].marker
Type: colorscale
Sets the colorscale. Has an effect only if in marker.coloris set to a numerical array. The colorscale must be an array containing arrays mapping a normalized value to an rgb, rgba, hex, hsl, hsv, or named color string. At minimum, a mapping for the lowest (0) and highest (1) values are required. For example, [[0, 'rgb(0,0,255)'], [1, 'rgb(255,0,0)']]. To control the bounds of the colorscale in color space, usemarker.cmin and marker.cmax. Alternatively, colorscale may be a palette name string of the following list: Greys,YlGnBu,Greens,YlOrRd,Bluered,RdBu,Reds,Blues,Picnic,Rainbow,Portland,Jet,Hot,Blackbody,Earth,Electric,Viridis,Cividis.
So an example based on your fiddle you could look like this:
var x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var trace1 = {
x: x,
y: x,
mode: 'markers',
marker: {
size: 20,
color: x,
colorscale: 'Greens'
},
};
Plotly.newPlot('myDiv', [trace1], {});
Here is an implementation for a custom colorscale based on the viridis colour scale R users will be familiar with.
var x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
var y = vector_normalise(x);
var trace1 = {
x: x,
y: x,
mode: 'markers',
marker: {
colorscale: [
[0.000, "rgb(68, 1, 84)"],
[0.111, "rgb(72, 40, 120)"],
[0.222, "rgb(62, 74, 137)"],
[0.333, "rgb(49, 104, 142)"],
[0.444, "rgb(38, 130, 142)"],
[0.556, "rgb(31, 158, 137)"],
[0.667, "rgb(53, 183, 121)"],
[0.778, "rgb(109, 205, 89)"],
[0.889, "rgb(180, 222, 44)"],
[1.000, "rgb(253, 231, 37)"]
],
color: y,
size: 20,
},
};
Plotly.newPlot('myDiv', [trace1], {});
Below is my normalisation function, I have left it verbose to help with understanding. The input vec could be overwritten and returned to reduce local variables if desired.
function vector_normalise(vec) {
var vmin = Math.min(...vec);
var vmax = Math.max(...vec);
// calculate the delta to save time with big arrays
var vdelta = vmax - vmin;
// create an empty array to return
var vec_ret = [];
// push doesn't seem to like inline functions
var vnorm;
// iterate over the array/vector
vec.forEach(value => {
vnorm = (value - vmin) / vdelta;
vec_ret.push(vnorm);
})
return vec_ret
}
Edit: Turns out Viridis is one of the existing available palettes... 😉

append multiple y axis data in plotly JS

I want to draw a multiline chart with a dataSet(multiple lists append in 1 list) where I know which one I will as X-axis and Y-axis.
let dataSet = [[1, 2, 3, 4], [10, 15, 13, 17], [16, 5, 11, 9]];
/**
X-axis = dataSet[0]
The remaining will be used as Y-axis*/
The example is taken from here. Where I have seen for plotting each line(here 2 times) variable is calling to set the data. In my case, Y-axis will appear near about 30 times and for each X-axis value will be the same. But I haven't found a dynamic solution where I can append the Y-axis value using a for loop or something like that. That means I want to call this data variable only 1 time and want to append all information of multi-chart there at instant.
I have added my approach here.
let dataSet = [[1, 2, 3, 4], [10, 15, 13, 17], [16, 5, 11, 9]];
function get_val (data){
let x = [];
for(let j = 1;j<data.length;j++)
{
x.push(data[j]);
}
//console.log("x: ",x);
return x;
}
var trace1 = {
x: dataSet[0],
y: get_val(dataSet), /* if write here get_val(dataSet)[0] then works fine*/
type: 'scatter'
};
/**
if you uncomment the following lines, result will be as like as the example of plotly JS
*/
/*
var trace2 = {
x: dataSet[0],
y: get_val(dataSet)[1],
type: 'scatter'
};
*/
var data = [trace1/*, trace2*/];
Plotly.newPlot('myDiv', data);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>
So, I want to know is there any approach by following which I can add multiple time any axis within a single variable(here trace1).
I have understood(maybe) where was my lacking.
1/ At first I have realized that I have overlooked that the traces or datapoints of plotly is an array of objects.
2/ I have also tried to organize my data
I have given here the solution that I have done.
let dataSet = [[10, 20, 30, 40], [10, 15, -13, 17], [1-6, 5, 11, 20] ]
/** following function will take the data and return the dataTRace as per as plotly's requirements.*/
function make_trace({data, set_type = "scatter", set_mode = "lines"} = {}){
let dataPoint = [];
for(let i = 1; i<data.length; i++){
dataPoint.push({
x: data[0],
y: data[i],
mode: set_mode,
type: set_type,
name: 'y_' + i
});
}
return dataPoint;
}
/** following function will make the layout for the plot*/
function make_layout({given_title="the title is not provided",x_min=0,x_max=15,x_axis_title="x_axis", y_min=0,y_max=15, y_axis_title="y_axis"} = {})
{
let layout_object = {
title: {
text: given_title
},
showlegend: true,
xaxis: {
range: [x_min, x_max],
title: x_axis_title
},
yaxis: {
range: [y_min, y_max],
title: y_axis_title
},
};
return layout_object;
}
let fig_layout = make_layout({given_title:"x vs y1, y2 plot",
x_min: 10, x_max : 50, x_axis_title:"x",
y_min: -20, y_max: 20, y_axis_title : "y(1,2)"});
Plotly.newPlot('myDiv', make_trace({data : dataSet, set_type:"scatter", set_mode : "lines"}), fig_layout);
Plotly.newPlot('myDiv_1', make_trace({data : dataSet, set_type:"scatter", set_mode : "markers"}), fig_layout);
<head>
<!-- Load plotly.js into the DOM -->
<script src='https://cdn.plot.ly/plotly-latest.min.js'></script>
</head>
<body>
<div id='myDiv'><!-- Plotly chart will be drawn inside this DIV --></div>
<div id='myDiv_1'><!-- Plotly chart will be drawn inside this DIV --></div>
</body>

Amcharts place labels at certain x y position

I'm trying to place some label in certain x,y position inside an AmCharts xy chart.
Here's my code that add labels:
var firstChart = AmCharts.makeChart("chartdiv", config);
var i1x = firstChart.xAxes[0].getCoordinate(parseFloat(data[0].i1x));
var i1y = firstChart.yAxes[0].getCoordinate(parseFloat(data[0].i1y));
var i2x = firstChart.xAxes[0].getCoordinate(parseFloat(data[0].i2x));
var i2y = firstChart.yAxes[0].getCoordinate(parseFloat(data[0].i2y));
var iMainx = firstChart.xAxes[0].getCoordinate(parseFloat(data[0].iMainx));
var iMainy = firstChart.yAxes[0].getCoordinate(parseFloat(data[0].iMainy));
var i4x = firstChart.xAxes[0].getCoordinate(parseFloat(data[0].i4x));
var i4y = firstChart.yAxes[0].getCoordinate(parseFloat(data[0].i4y));
var i5x = firstChart.xAxes[0].getCoordinate(parseFloat(data[0].i5x));
var i5y = firstChart.yAxes[0].getCoordinate(parseFloat(data[0].i5y));
firstChart.addLabel(i1x, i1y, 'rpm', 'center', 16, 'black', 0, 1, true);
firstChart.addLabel(i2x, i2y, 'rpm', 'center', 16, 'black', 0, 1, true);
firstChart.addLabel(iMainx, iMainy, 'rpm', 'center', 16, 'black', 0, 1, true);
firstChart.addLabel(i4x, i4y, 'rpm', 'center', 16, 'black', 0, 1, true);
firstChart.addLabel(i5x, i5y, 'rpm', 'center', 16, 'black', 0, 1, true);
The problem is that i have all the Y points that are ok but the X axis is not, all the labels shouls stay on the left of the graph.
Here a screenshot
The issue involves the use of center, which doesn't quite work correctly. If you want to center-align text, try middle, which will also place the labels correctly to the left as desired.
I also highly recommend against using undocumented properties - xAxes and yAxes are internal properties that are managed by the library itself. If an update is released that changes how those properties are managed, your code may break. Use the valueAxes array instead, which is documented, and reference the desired axis by index from your config.
Demo using middle

Plotly - I want to color each X Axis value in different color based on condition

Language: JavaScript
Framework: Plotly
I have a requirement where i want x-Axis values to be colored individually instead of coloring all the values in x-Axis.
I tried below code, but it does the same thing to all the values on axis.
Here the color 'red' gets applied to all the values on x-Axis. I need each value to be colored based on the colors mentioned in the array 'col' in below code.
var data = [{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
type: 'bar'
}];
var col = ['red','black','yellow'];
var layout = {
xaxis : {
tickangle : -45,
tickfont : {
size : 16,
color : 'red'
}
}
};
Plotly.newPlot('myDiv', data,layout);
If you want to color the bars individually you would need to assign the colors to the color attribute of the marker object inside your data.
If you want to color the axis' ticks individually there is no way of doing it directly in plotly. tickfont color only takes a single color but this should not stop us. The tick text is inside a SVG element with the class name xtick. We can select it and override its fill aka color with our colors.
var col = ['red','black','yellow'];
var data = [{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
type: 'bar',
marker: {color: col}
}];
var layout = {
xaxis : {
tickangle : -45,
tickfont : {
size : 16,
color : 'red'
}
}
};
Plotly.newPlot('myDiv', data,layout);
var ticks = document.getElementsByClassName('xtick');
for (var i = 0; i < ticks.length; i += 1) {
ticks[i].getElementsByTagName('text')[0].style.fill = col[i % col.length];
}
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id='myDiv'></div>

Style specific bar column with Flot

I'm working with Flot to create a bar chart. However, I need to add special styling to certain columns. Is this possible at all?
My HTML looks like this:
<div id="monthly-usage" style="width: 100%; height: 400px;"></div>
And my JS like this:
somePlot = null;
$(function() {
//Data from this year and last year
var thisYear = [
[3, 231.01],
[4, 219.65],
[5, 222.47],
[6, 223.09],
[7, 248.43],
[8, 246.22]
];
var lastYear = [
[3, 171.7],
[4, 130.62],
[5, 163.03],
[6, 166.46],
[7, 176.16],
[8, 169.04]
];
var usageData = [{
//Usage this year
label: "2014",
data: thisYear,
bars: {
show: true,
barWidth: .3,
fill: true,
lineWidth: 0,
order: 1,
fillColor: 'rgba(194, 46, 52, .85)'
},
color: '#c22e34'
}, {
//Usage last year to compare with current usage
label: "2013",
data: lastYear,
bars: {
show: true,
barWidth: .3,
fill: true,
lineWidth: 0,
order: 2,
fillColor: 'rgba(73, 80, 94, .85)'
},
color: '#49505e'
}];
//X-axis labels
var months = [
[0, "Jan"],
[1, "Feb"],
[2, "Mar"],
[3, "Apr"],
[4, "Maj"],
[5, "Jun"],
[6, "Jul"],
[7, "Aug"],
[8, "Sep"],
[9, "Okt"],
[10, "Nov"],
[11, "Dec"]
];
//Draw the graph
somePlot = $.plot(('#monthly-usage'), usageData, {
grid: {
color: '#646464',
borderColor: 'transparent',
hoverable: true
},
xaxis: {
ticks: months,
color: '#d4d4d4'
},
yaxis: {
tickSize: 50,
tickFormatter: function(y, axis) {
return y + " kWh";
}
},
legend: {
show: false
}
});
var ctx = somePlot.getCanvas().getContext("2d"); // get the context from plot
var data = somePlot.getData()[0].data; // get your series data
var xaxis = somePlot.getXAxes()[0]; // xAxis
var yaxis = somePlot.getYAxes()[0]; // yAxis
var offset = somePlot.getPlotOffset(); // plots offset
var imageObj = new Image(); // create image
imageObj.onload = function() { // when finish loading image add to canvas
xPos = xaxis.p2c(data[4][0]) + offset.left;
yPos = yaxis.p2c(data[4][1]) + offset.top;
ctx.drawImage(this, xPos, yPos);
xPos = xaxis.p2c(data[5][0]) + offset.left;
yPos = yaxis.p2c(data[5][1]) + offset.top;
ctx.drawImage(this, xPos, yPos);
};
imageObj.src = 'path/to/file.png'; // set it's source to kick off load
});
});
Optimally, I would like to insert an icon in bar 5 and 6 that warns the user. Alternatively, I'd like to change the color of bars 5 and 6. Any ideas on how to fix this?
EDIT: I've updated my JS according to Mark's answer which works.
#Mark, how can I position the images correctly. They are a bit off. I need the image inside the red bar and not besides the bar. I'm trying to finetune this but it doesn't seem as if I can use for instance "0.5". I use side by side bars which is different from your version.
xPos = xaxis.p2c(data[4][0]) + offset.left;
yPos = yaxis.p2c(data[4][1]) + offset.top;
You can't do exactly what you ask with standard options, but there are a couple of possible approaches:
Write your own draw method and use the hooks to install it in place of the standard flot drawing code. This obviously entails a lot of work, but you'll have complete control over how to render your data. (That said, I wouldn't recommend it.)
Break your data into two different data sets. One data set would have dummy values (e.g. 0, or whatever your minimum is) for bars 5 and 6. The second data set would have dummy values for all bars except 5 and 6. You could then style the "two" data sets independently, giving each, for example a different color. Graph the two sets as a stacked bar chart with whatever additional styling tweaks are appropriate for your chart.
(As a FYI, there's a fair bit of information and examples at jsDataV.is. Look at the "Book" section; chapter 2 is dedicated to flot.)
flot gives you access to the HTML5 Canvas it's drawing on; so you just add your icon on there yourself. Borrowing from my own answer here.
var ctx = somePlot.getCanvas().getContext("2d"); // get the context from plot
var data = somePlot.getData()[0].data; // get your series data
var xaxis = somePlot.getXAxes()[0]; // xAxis
var yaxis = somePlot.getYAxes()[0]; // yAxis
var offset = somePlot.getPlotOffset(); // plots offset
$.get("someImage.txt", function(img) { // grad some image, I'm loading it from a base64 resource
var imageObj = new Image(); // create image
imageObj.onload = function() { // when finish loading image add to canvas
var xPos = xaxis.p2c(data[4][0]) + offset.left;
var yPos = yaxis.p2c(data[4][2]) + offset.top;
ctx.drawImage(this, xPos, yPos);
xPos = xaxis.p2c(data[5][0]) + offset.left;
yPos = yaxis.p2c(data[5][3]) + offset.top;
ctx.drawImage(this, xPos, yPos);
};
imageObj.src = img; // set it's source to kick off load
});
Example here.
Looks like:

Categories