create filled linear chart with chartjs for specific datasets - javascript

I'm trying to create a linear chart like a curve for different datasets but with start and end range for the x and y.
I want the start and end point of each dataset start from x y, how can convert the y line as values but takes labels? I tried to do something similar on the codepen but still need more to be similar to the image.
var data = {
labels: ["Group A", "Group B", "Group C", "Group D", "Group E"],
datasets: [
{
label: "Group A",
backgroundColor: gradient,
pointBackgroundColor: "white",
borderWidth: 1,
borderColor: "#911215",
data: [
{ x: 0, y: 0 },
{ x: 5, y: 5 }
]
},
{
label: "Group B",
backgroundColor: "green",
pointBackgroundColor: "white",
borderWidth: 1,
borderColor: "green",
data: [
{ x: 0, y: 0 },
{ x: 5, y: 5 },
{ x: 10, y: 10 }
]
},
{
label: "Group C",
backgroundColor: gradient,
pointBackgroundColor: "white",
borderWidth: 1,
borderColor: "#911215",
data: [
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{ x: 10, y: 10 },
{ x: 60, y: 60 },
{ x: 60, y: 10 }
]
},
{
label: "Group D",
backgroundColor: "blue",
pointBackgroundColor: "white",
borderWidth: 1,
borderColor: "blue",
data: [
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{ x: 60, y: 10 },
{ x: 0, y: 5 }
]
},
{
label: "Group E",
backgroundColor: "pink",
pointBackgroundColor: "white",
borderWidth: 1,
borderColor: "pink",
data: [
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{ x: 0, y: 0 },
{ x: 0, y: 10 },
{ x: 0, y: 0 },
{ x: 0, y: 0 }
]
}
]
};
codepen

Related

Sorting coordinates

Im coding a Paint version for Minecraft with the CC Tweaked Mod
The Problem is i give my program an array and the program follows the order of the array one after the other.
That means if i draw something in the top left and then bottom right and then i fill everything else it will follow this order (which isnt very efficient)
I have an array called output
Here is how the array could look like
[
{ x: 0, y: 0, color: 12 },
{ x: 1, y: 0, color: 3 },
{ x: 2, y: 0, color: 5 },
{ x: 0, y: 1, color: 8 },
{ x: 1, y: 1, color: 10 },
{ x: 2, y: 1, color: 11 },
{ x: 0, y: 2, color: 12 },
{ x: 2, y: 2, color: 3 },
{ x: 1, y: 2, color: 14 }
]
The array comes from this "drawing"(ignore the arrows for now)
Now the question
How can i get from the first array to an array that looks like this
[
{ x: 0, y: 0, color: 12 },
{ x: 1, y: 0, color: 3 },
{ x: 2, y: 0, color: 5 },
{ x: 2, y: 1, color: 11 },
{ x: 1, y: 1, color: 10 },
{ x: 0, y: 1, color: 8 },
{ x: 0, y: 2, color: 12 },
{ x: 1, y: 2, color: 14 }
{ x: 2, y: 2, color: 3 },
]
(See how it follows the arrows?)
This would be much faster.
It is possibles that some squares are not filled with any color. Idk how important that might be
If important these are the colorcodes
const LISTOFCOLORS = {
white: 1,
orange: 2,
magenta: 3,
dodgerblue: 4,
yellow: 5,
lime: 6,
pink: 7,
gray: 8,
lightgray: 9,
cyan: 10,
purple: 11,
blue: 12,
SaddleBrown: 13,
green: 14,
red: 15,
black: 16
}
If you are only reversing the 3 - 6 entries, you could create a new array from slices of the old array using slice() and reverse the specified entries using reverse().
const rowByRow = [
{ x: 0, y: 0, color: 12 },
{ x: 1, y: 0, color: 3 },
{ x: 2, y: 0, color: 5 },
{ x: 0, y: 1, color: 8 },
{ x: 1, y: 1, color: 10 },
{ x: 2, y: 1, color: 11 },
{ x: 0, y: 2, color: 12 },
{ x: 2, y: 2, color: 3 },
{ x: 1, y: 2, color: 14 }
];
const result = [
...rowByRow.slice(0, 3),
...rowByRow.slice(3, 6).reverse(), // reverse 3 - 6 entries
...rowByRow.slice(6, 9)
];
console.log(result);
#axtck Thank you very much. I ended up not using slice but the "slicing the array in multiple arrays and work from there" part i got from your post
i ended up with this
const arr = [
{ x: 1, y: 4, color: 12 },
{ x: 2, y: 4, color: 12 },
{ x: 2, y: 3, color: 12 },
{ x: 2, y: 2, color: 12 },
{ x: 2, y: 1, color: 12 },
{ x: 0, y: 0, color: 12 },
{ x: 1, y: 0, color: 12 },
{ x: 1, y: 1, color: 12 },
{ x: 4, y: 1, color: 12 },
{ x: 3, y: 2, color: 12 },
{ x: 1, y: 3, color: 12 },
{ x: 0, y: 3, color: 12 },
{ x: 0, y: 1, color: 12 },
{ x: 0, y: 2, color: 12 },
{ x: 1, y: 2, color: 12 },
{ x: 3, y: 4, color: 12 },
{ x: 4, y: 4, color: 12 },
{ x: 4, y: 0, color: 12 },
{ x: 3, y: 0, color: 12 },
{ x: 2, y: 0, color: 12 },
{ x: 3, y: 1, color: 12 },
{ x: 4, y: 2, color: 12 },
{ x: 4, y: 3, color: 12 },
{ x: 0, y: 4, color: 12 },
{ x: 3, y: 3, color: 12 }
]
const ArrayOfArrays = []
const dimension = 5
for (let i = 0; i < dimension; i++) {
let array = []
for (let j = 0; j < arr.length; j++) {
if (i == arr[j].y) {
array.push(arr[j])
}
}
ArrayOfArrays.push(i % 2 === 0 ?
array.sort(function (a, b) {
return a.x - b.x;
}) : array.sort(function (a, b) {
return b.x - a.x;
}))
}
console.log(ArrayOfArrays)
The output would be
[
[
{ x: 0, y: 0, color: 12 },
{ x: 1, y: 0, color: 12 },
{ x: 2, y: 0, color: 12 },
{ x: 3, y: 0, color: 12 },
{ x: 4, y: 0, color: 12 }
],
[
{ x: 4, y: 1, color: 12 },
{ x: 3, y: 1, color: 12 },
{ x: 2, y: 1, color: 12 },
{ x: 1, y: 1, color: 12 },
{ x: 0, y: 1, color: 12 }
],
[
{ x: 0, y: 2, color: 12 },
{ x: 1, y: 2, color: 12 },
{ x: 2, y: 2, color: 12 },
{ x: 3, y: 2, color: 12 },
{ x: 4, y: 2, color: 12 }
],
[
{ x: 4, y: 3, color: 12 },
{ x: 3, y: 3, color: 12 },
{ x: 2, y: 3, color: 12 },
{ x: 1, y: 3, color: 12 },
{ x: 0, y: 3, color: 12 }
],
[
{ x: 0, y: 4, color: 12 },
{ x: 1, y: 4, color: 12 },
{ x: 2, y: 4, color: 12 },
{ x: 3, y: 4, color: 12 },
{ x: 4, y: 4, color: 12 }
]
]
notice how the x value goes up and down

Change dot size individually Scatter Chart -- ChartJS

How can I change the size of each different dot in my scatter chart ?
var scatterChart = new Chart(ctx, {
type: 'scatter',
data: {
datasets: [{
label: 'Scatter Dataset',
data: [{
x: -10,
y: 0
}, {
x: 0,
y: 15
}, {
x: 10,
y: 5,
}],
pointRadius: 15,
fill: false,
pointHoverRadius: 20
}]
},
options: {
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
}]
}
}
});
After this I want to change each dot size in matter of my ajax response data.
I tried to do this without the star ofc:
data: [{
x: -10,
y: 0
}, {
x: 0,
y: 15
}, {
x: 10,
y: 5,
pointRadius: 15,
*
}],
but with no success.
You should use a bubble chart that accepts the bubble radius in pixels (property r) for each data point.
Please take a look at this sample chart.
you can put each point in a separate series.
this will allow you to assign a separate radius.
datasets: [{
label: 'Scatter Dataset',
data: [{
x: -10,
y: 0
}],
pointRadius: 10,
fill: false,
pointHoverRadius: 20
}, {
label: 'hidden',
data: [{
x: 0,
y: 15,
}],
pointRadius: 20,
fill: false,
pointHoverRadius: 20
}, {
label: 'hidden',
data: [{
x: 10,
y: 5,
}],
pointRadius: 30,
fill: false,
pointHoverRadius: 20
}]
and to prevent multiple legend entries from being displayed,
we can filter out all but one series label.
legend: {
labels: {
filter: function(item, chart) {
return (item.text !== 'hidden');
}
}
},
see following working snippet...
$(document).ready(function() {
var scatterChart = new Chart(document.getElementById('chart').getContext('2d'), {
type: 'scatter',
data: {
datasets: [{
label: 'Scatter Dataset',
data: [{
x: -10,
y: 0
}],
pointRadius: 10,
fill: false,
pointHoverRadius: 20
}, {
label: 'hidden',
data: [{
x: 0,
y: 15,
}],
pointRadius: 20,
fill: false,
pointHoverRadius: 20
}, {
label: 'hidden',
data: [{
x: 10,
y: 5,
}],
pointRadius: 30,
fill: false,
pointHoverRadius: 20
}]
},
options: {
legend: {
labels: {
filter: function(item, chart) {
return (item.text !== 'hidden');
}
}
},
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
}]
}
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<canvas id="chart"></canvas>
I figured out you can specify an array of values for pointRadius & pointStyle properties :
datasets: [
{
label: "Plan",
data: [10, 15, 5],
pointRadius: [10, 5, 15],
pointStyle: ["rect", "rect", "circle"],
},
],
This way you can specify a size of each dot individually

highcharts: Add marker to a x-range chart

I want to create a dumbbell chart using highcharts.
I used x-range chart for this
here is the link: https://jsfiddle.net/thushara07/nLkxa0wr/15/
series: [{
// name: 'Project 3',
// pointPadding: 0,
// groupPadding: 0,
//borderColor: 'gray',
pointWidth: 5,
data: [{
x: 32,
x2: 33,
y: 0,
// partialFill: 0.25
}, {
x: 44,
x2:45,
y: 1
}, {
x:30,
x2: 32,
y: 2
}],
dataLabels: {
align: 'left',
enabled: true
}
}]
expected output: I want to show markers for each line created as shown
(https://images.app.goo.gl/LAKQBdsaKBH2hjS59
)
It can be done by adding additional scatter series that is linked to x-range:
Code:
Highcharts.chart('container', {
yAxis: {
title: {
text: ''
},
categories: ['Prototyping', 'Development', 'Testing'],
reversed: true
},
series: [{
type: 'xrange',
pointWidth: 5,
id: 'main',
data: [{
x: 32,
x2: 33,
y: 0
}, {
x: 44,
x2: 45,
y: 1
}, {
x: 30,
x2: 32,
y: 2
}],
dataLabels: {
align: 'center',
enabled: true
}
}, {
type: 'scatter',
linkedTo: 'main',
marker: {
radius: 5
},
data: [{
x: 32,
y: 0,
color: 'red'
}, {
x: 33,
y: 0,
color: 'grey'
}, {
x: 44,
y: 1,
color: 'red'
}, {
x: 45,
y: 1,
color: 'grey'
}, {
x: 30,
y: 2,
color: 'red'
}, {
x: 32,
y: 2,
color: 'grey'
}]
}]
});
Demo:
https://jsfiddle.net/BlackLabel/4qj89cog/
API reference:
https://api.highcharts.com/highcharts/series.scatter
https://api.highcharts.com/highcharts/series.scatter.linkedTo

How to show only first and last labels in CanvasJS

I need to show first and last labels only in CanvasJS. It's always showing all the labels but my requirement is to show only first and last. Is there any way out to do so?
You can use axisY labelFormatter to do so.
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Chart showing only First and Last Axis Labels",
},
axisY: {
tickColor: "transparent",
labelFormatter: function(e){
if(e.chart.axisY[0].minimum === e.value || e.chart.axisY[0].maximum === e.value)
return e.value;
return "";
}
},
data: [{
type: "column",
dataPoints: [
{ x: 10, y: 71 },
{ x: 20, y: 55 },
{ x: 30, y: 50 },
{ x: 40, y: 65 },
{ x: 50, y: 95 },
{ x: 60, y: 68 },
{ x: 70, y: 28 },
{ x: 80, y: 34 },
{ x: 90, y: 14 }
]
}]
});
chart.render();
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 260px; width: 100%;"></div>
You can also try hiding all axis-labels and add stripLines at the minimum and maximum.
var chart = new CanvasJS.Chart("chartContainer", {
title: {
text: "Chart showing only First and Last Axis Labels",
},
axisX: {
valueFormatString: "####"
},
axisY:[{
tickColor: "transparent",
labelFontColor: "transparent"
}],
axisY2:[{
tickColor: "transparent",
labelFontColor: "transparent"
}],
data: [
{
type: "column",
showInLegend: true,
name: "Axis Y-1",
xValueFormatString: "####",
dataPoints: [
{ x: 2006, y: 6 },
{ x: 2007, y: 2 },
{ x: 2008, y: 5 },
{ x: 2009, y: 7 },
{ x: 2010, y: 1 },
{ x: 2011, y: 5 },
{ x: 2012, y: 5 },
{ x: 2013, y: 2 },
{ x: 2014, y: 2 }
]
},
{
type: "column",
showInLegend: true,
axisYType: "secondary",
//axisYIndex: 0, //Defaults to Zero
name: "Axis Y2-1",
xValueFormatString: "####",
dataPoints: [
{ x: 2006, y: 12 },
{ x: 2007, y: 20 },
{ x: 2008, y: 28 },
{ x: 2009, y: 34 },
{ x: 2010, y: 24 },
{ x: 2011, y: 45 },
{ x: 2012, y: 15 },
{ x: 2013, y: 34 },
{ x: 2014, y: 22 }
]
}
]
});
chart.render();
addStripLine(chart);
function addStripLine(chart){
for(var i = 0; i < chart.axisY.length; i++){
min = chart.axisY[i].get("minimum");
max = chart.axisY[i].get("maximum");
chart.axisY[i].addTo("stripLines", {value: min, color: "black", label: min, labelFontColor: "black", labelBackgroundColor: "transparent", labelPlacement: "outside"});
chart.axisY[i].addTo("stripLines", {value: max, color: "black", label: max, labelFontColor: "black", labelBackgroundColor: "transparent", labelPlacement: "outside"});
}
for(var i = 0; i < chart.axisY2.length; i++){
min = chart.axisY2[i].get("minimum");
max = chart.axisY2[i].get("maximum");
chart.axisY2[i].addTo("stripLines", {value: min, color: "black", label: min, labelFontColor: "black", labelBackgroundColor: "transparent", labelPlacement: "outside"});
chart.axisY2[i].addTo("stripLines", {value: max, color: "black", label: max, labelFontColor: "black", labelBackgroundColor: "transparent", labelPlacement: "outside"});
}
}
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="height: 260px; width: 100%;"></div>

Changing the x-label in HTML Canvas charts

Hi I am using HTML Canvas charts. In one of the charts can I change the label of x-axis?
The source code for the chart is :
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<div id="chartContainer" style="height: 300px; width: 100%;"></div>
<script type="text/javascript" src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded",function () {
var chart = new CanvasJS.Chart("chartContainer",
{
animationEnabled: true,
theme: "theme2",
title:{
text: "Multi Series Spline Chart - Hide / Unhide via Legend"
},
axisY:[{
lineColor: "#4F81BC",
tickColor: "#4F81BC",
labelFontColor: "#4F81BC",
titleFontColor: "#4F81BC",
lineThickness: 2,
},
{
lineColor: "#C0504E",
tickColor: "#C0504E",
labelFontColor: "#C0504E",
titleFontColor: "#C0504E",
lineThickness: 2,
}],
data: [
{
type: "spline", //change type to bar, line, area, pie, etc
showInLegend: true,
dataPoints: [
{ x: 10, y: 51 },
{ x: 20, y: 45},
{ x: 30, y: 50 },
{ x: 40, y: 62 },
{ x: 50, y: 95 },
{ x: 60, y: 66 },
{ x: 70, y: 24 },
{ x: 80, y: 32 },
{ x: 90, y: 16}
]
},
{
type: "spline",
axisYIndex: 1,
showInLegend: true,
dataPoints: [
{ x: 10, y: 201 },
{ x: 20, y: 404},
{ x: 30, y: 305 },
{ x: 40, y: 405 },
{ x: 50, y: 905 },
{ x: 60, y: 508 },
{ x: 70, y: 108 },
{ x: 80, y: 300 },
{ x: 90, y: 101}
]
}
],
legend: {
cursor: "pointer",
itemclick: function (e) {
if (typeof(e.dataSeries.visible) === "undefined" || e.dataSeries.visible) {
e.dataSeries.visible = false;
} else {
e.dataSeries.visible = true;
}
chart.render();
}
}
});
chart.render();
});
</script>
</body>
</html>
Now here we can see that x-values is 10,20,30... My question is can we change them to other format like 10am or 10pm?
You can add a suffix (or a prefix) to the x-axis with chart.options.axisX
chart.options.axisX = { suffix: "AM" };
Or you can add both like this:
chart.options.axisX = { prefix: "/", suffix: "AM" };

Categories

Resources