ChartJS: Mapping Non numeric Y and X - charts

I'm trying to map non numeric y and x and for some reason it does not work.
E.g.
xLabels: ["January", "February", "March", "April", "May", "June", "July"],
yLabels: ['Request Added', 'Request Viewed', 'Request Accepted', 'Request Solved', 'Solving Confirmed'],
And when i try to change:
data: ['Request Added', 'Request Viewed']
with
data: [{x: "January", y: 'Request Added'}, ...]
Graph does not show a thing
Also i tried to use scales.yAxis.ticks.callback to modify and map against an array but that didnt work out either.
[0: 'Request Added', 1: 'Request Viewed']
EDIT: Essentially I need something like this
Request Added x x
Request Viewed x
Request Accepted x x
January, Feb, March
Basically a copy of this: https://answers.splunk.com/answers/85938/scatter-plot-with-non-numeric-y-values.html
Which also suggests to map against an array, but the callback in Y-ticks makes no freaking sense.. ? As i add labelY : [1,2,3,4,5,6] The Third argument of callback "values" is equal to [-2-1 0 1 2].

In order to use a category scale for both the X and Y axis, you must use the traditional data format of an array of values. Per the chart.js api docs...
Scatter line charts can be created by changing the X axis to a linear axis. To use a scatter chart, data must be passed as objects containing X and Y properties
This implies that you can only use the data format {x: ' ', y: ' '} when at least the X axis is a linear scale (but I'm betting it only works if both the X and Y axis are linear).
Since you are limited to only using an array of values for your data, you must use at least 2 datasets in order to plot multiple values on the X axis (like what you are trying to do).
Here is a chart configuration that gives what you are looking for.
var ctx = document.getElementById("canvas").getContext("2d");
var myLine = new Chart(ctx, {
type: 'line',
data: {
xLabels: ["January", "February", "March", "April", "May", "June", "July"],
yLabels: ['Request Added', 'Request Viewed', 'Request Accepted', 'Request Solved', 'Solving Confirmed'],
datasets: [{
label: "My First dataset",
data: ['Request Added', 'Request Viewed', 'Request Added'],
fill: false,
showLine: false,
borderColor: chartColors.red,
backgroundColor: chartColors.red
}, {
label: "My First dataset",
data: [null, 'Request Accepted', 'Request Accepted'],
fill: false,
showLine: false,
borderColor: chartColors.red,
backgroundColor: chartColors.red
}]
},
options: {
responsive: true,
title:{
display: true,
text: 'Chart.js - Non Numeric X and Y Axis'
},
legend: {
display: false
},
scales: {
xAxes: [{
display: true,
scaleLabel: {
display: true,
labelString: 'Month'
}
}],
yAxes: [{
type: 'category',
position: 'left',
display: true,
scaleLabel: {
display: true,
labelString: 'Request State'
},
ticks: {
reverse: true
},
}]
}
}
});
You can see what it looks like from this codepen.
If you are for whatever reason tied to using the {x: ' ', y: ' '} dataformat, then you will have to change both your scales to linear, map your data to numerical values, then use the ticks.callback property to map your numerical ticks back to string values.
Here is an example that demonstrates this approach.
var xMap = ["January", "February", "March", "April", "May", "June", "July"];
var yMap = ['Request Added', 'Request Viewed', 'Request Accepted', 'Request Solved', 'Solving Confirmed'];
var mapDataPoint = function(xValue, yValue) {
return {
x: xMap.indexOf(xValue),
y: yMap.indexOf(yValue)
};
};
var ctx2 = document.getElementById("canvas2").getContext("2d");
var myLine2 = new Chart(ctx2, {
type: 'line',
data: {
datasets: [{
label: "My First dataset",
data: [
mapDataPoint("January", "Request Added"),
mapDataPoint("February", "Request Viewed"),
mapDataPoint("February", "Request Accepted"),
mapDataPoint("March", "Request Added"),
mapDataPoint("March", "Request Accepted"),
],
fill: false,
showLine: false,
borderColor: chartColors.red,
backgroundColor: chartColors.red
}]
},
options: {
responsive: true,
title: {
display: true,
text: 'Chart.js - Scatter Chart Mapping X and Y to Non Numeric'
},
legend: {
display: false
},
scales: {
xAxes: [{
type: 'linear',
position: 'bottom',
scaleLabel: {
display: true,
labelString: 'Month'
},
ticks: {
min: 0,
max: xMap.length - 1,
callback: function(value) {
return xMap[value];
},
},
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Request State'
},
ticks: {
reverse: true,
min: 0,
max: yMap.length - 1,
callback: function(value) {
return yMap[value];
},
},
}]
}
}
});
You can see this in action at the same codepen.

Related

echarts: bar chart start at value?

echarts: bar chart bars are located left and right of the value on the category axis:
How to tell echarts to start the bar with the value on the category axis? Like this:
To clarify the problem, here ist another example. This is a chart of the hourly sum of precipitation. Every bar should show the sum from the bottom to the top of the hour, the data values are conencted to every bottom of the hour.
as you can see, the bars are not starting at 8:00, they are starting at 7:30.
Data: (timestamps are shown in CET)
series: [
{
name: "Niederschlag",
type: "bar",
data: [[1608534000000, 3], [1608537600000, 5], [1608541200000, 2], [1608544800000, 0], [1608548400000, 1] ],
barWidth: '100%'
}
]
It should look like this:
Start point of bar here doesn't matter, you need align labels to left: https://echarts.apache.org/en/option.html#series-bar.label.align
you need a hidden xAxis like below:
option = {
xAxis: [{
type: 'category',
data: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23],
show: false
}, {
type: 'category',
data: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24],
boundaryGap: false,
axisTick: { alignWithLabel: true },
position: 'bottom'
}],
yAxis: {
type: 'value'
},
series: [{
data: [120, 200, 150, 80, 70, 110, 130,120,210,110,210],
type: 'bar',
barCategoryGap:'20%',
itemStyle: {
},
xAxisIndex: 0,
backgroundStyle: {
color: 'rgba(220, 220, 220, 0.8)'
}
}]
};
You have not provided the complete chart config, so I recommend using this one. Also pay attention on method useUTC and you need to know that "By default, echarts uses local timezone to formate time labels"
So I see this state of Chart by you data with offset -180:
var myChart = echarts.init(document.getElementById('chart'));
var chartData = [
[1608534000000, 3],
[1608537600000, 5],
[1608541200000, 2],
[1608544800000, 0],
[1608548400000, 1],
];
var option = {
tooltip: {},
xAxis: {
type: 'time',
data: ['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00'],
splitNumber: 24,
},
yAxis: {
type: 'value'
},
series: [{
name: "Niederschlag",
type: "bar",
data: chartData,
barWidth: '100%',
}],
useUTC: false,
};
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.9.0/dist/echarts.min.js"></script>
<div id="chart" style="width: 1024px;height:400px;"></div>

Is there a way to specify the y-axis crossing point?

In the example below the y-axis crosses at 1, rather than 0. Is there a way to achieve this in echarts?
It seems to me, literally, you can't do this with basic bar chart because it will break the coordinate system and result will be anything but not a bar chart.
If you need only visual like on attached picture then you can hide xAxis and draw its surrogate with markLine but you will have the troubles with bar positioning (that will fix with stack and transparent bars, see below).
If you need real chart with responsive, zoomable and other opts then in the Echarts you can use custom series for build own chart type (see example).
Example how to make picture like attached:
var myChart = echarts.init(document.getElementById('main'));
var option = {
tooltip: {},
xAxis: {
data: ['Category-1', 'Category-2', 'Category-3', 'Category-4'],
show: true,
axisLine: {
show: true,
lineStyle: {
opacity: 0
}
},
axisTick: {
show: false,
}
},
yAxis: {
max: 4,
min: -1
},
series: [{
name: 'Series-1',
type: 'bar',
stack: 'group',
data: [1, 1, -3],
color: 'rgba(0,0,0, 0)',
}, {
name: 'Series-2',
type: 'bar',
stack: 'group',
data: [{
value: 1,
itemStyle: {
color: 'red'
}
}, {
value: 2,
itemStyle: {
color: 'green'
}
}, {
value: 1,
itemStyle: {
color: 'orange'
}
}],
markLine: {
symbol: "none",
data: [{
silent: false,
yAxis: 1,
lineStyle: {
color: "#000",
width: 1,
type: "solid"
}
}, ],
label: {
show: false,
}
},
}]
};
myChart.setOption(option);
<script src="https://cdn.jsdelivr.net/npm/echarts#4.8.0/dist/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>
P.S. If this not a secret, why you need it?

eCharts: How to change line colors for positive and negative values?

I want to color the area "under" the graph (i.e. between zero and value) green when positive, and red when negative, on an eCharts line graph.
Like this
We have already done it with a bar graph (below), but now we need to do it with a line graph.
You can achieve this by setting the visualMap property. I have done some hit and trial and achieved the following.
var myChart = echarts.init(document.getElementById('main'));
option = {
xAxis: {
type: 'category',
boundaryGap: false,
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
},
yAxis: {
type: 'value'
},
series: [{
data: [820, 932, 901, -1200, -800, 1330, 1320],
type: 'line',
areaStyle: {}
}],
visualMap: {
left: 'right',
min: 0,
max: 1,
inRange: {
color: ['red', 'green']
},
text: ['>0', '<0'],
calculable: true
},
};
// use configuration item and data specified to show chart
myChart.setOption(option);
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.6.0/echarts.min.js"></script>
<div id="main" style="width: 600px;height:400px;"></div>

Chartjs 2-categorical

I'm successfully graphing a bunch of data points using Chartjs 2 with React, with a category Y-axis, but would like to label them with their category label. They're currently showing "undefined" as a tooltip value:
Here's what I've got right now (not working):
labels: this.state.graphData.eventWeekArray,
datasets: [
{
label: title,
labels: data,
fill: false,
lineTension: 0.1,
borderColor: colorArray()[counter],
borderCapStyle: 'butt',
borderJoinStyle: 'miter',
pointBorderColor: 'rgba(75,192,192,1)',
pointBackgroundColor: '#fff',
pointBorderWidth: 1,
pointHoverRadius: 6,
pointHoverBackgroundColor: 'rgba(75,192,192,1)',
pointHoverBorderColor: 'rgba(220,220,220,1)',
pointHoverBorderWidth: 3,
pointRadius: 1,
pointHitRadius: 1,
showLine: true,
steppedLine: true,
spanGaps: true,
data: data,
year: dataYear,
measurement: 'state'
}
]
Using options and scaleLabel doesn't work, either:
const options = {
legend: {
display: true
},
scales: {
xAxes: [
{
scaleLabel: {
display: true,
labelString: 'Weeks'
},
ticks: {
autoSkip: true,
autoSkipPadding: 20
}
}
],
yAxes: [
{
type: 'category',
labels: this.state.eventLabelArray
},
{
type: 'linear',
labels: this.state.brixLabelArray
}
]
}
};

How can configure my y-axis on chart.js?

I am trying to build graph.
My y-axis start with 0 here, I dont know how to configure it and why it is talking 0 - I see other post which mentioned scaleOverride:true, scaleStartValue:0.1, scaleStepWidth:5 - I dont know how to use that in my below code , how can configure y-axis in chart.js.
Any pointer would be
I have following code
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "rgba(220,220,220,0.5)",
data: [6, 6, 6, 8, 6, 9, 8]
}]
};
function barChart() {
var context = document.getElementById('stacked').getContext('2d');
var myBar = new Chart(context, {
type: 'bar',
data: barChartData,
options: {
title:{
display:true,
text:"Chart.js Bar Chart - Stacked"
},
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
stacked: true,
}],
yAxes: [{
stacked: true
}]
}
}
});
};
$(document).ready(function() {
$(document).ready(barChart);
});
Thank you guys for helping, I observed that chart.js will automatically take value for y-axis based on your data, you can change y/x-axis setting under Options > Scales , I also needed to change step size of y-axis and get rid of x-axis grid line,"ticks" is something I was looking for, here is my sample code and steps to achieved all these.
Step 1) Canvas this is place holder where your chart will display on JSP
<canvas width="1393px;" height="500px;" id="stacked"></canvas>
Step 2) Create sample datasets (this is JSON you need to create based on your requirement but make sure you provide exact the same formated JSON response as given below along with your data.
var barChartData = {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [{
label: 'Dataset 1',
backgroundColor: "red",
data: [9, 6, 6, 8, 6, 9, 8]
},
{
label: 'Dataset 1',
backgroundColor: "rgba(225,226,228,0.5)",
data: [9, 6, 6, 8, 6, 9, 8]
}]
};
or you can call JSON from controller inside script as below
var jsonArry = <%=request.getAttribute("jsonArry")%>;
Step 3) call that JSON which you have created at step 2
function barChart(){
var context = document.getElementById('stacked').getContext('2d');
var myBar = new Chart(context, {
type: 'bar',
data: jsonArry,
options: {
tooltips: {
mode: 'label'
},
responsive: true,
scales: {
xAxes: [{
ticks:{
stepSize : 10,
},
stacked: true,
gridLines: {
lineWidth: 0,
color: "rgba(255,255,255,0)"
}
}],
yAxes: [{
stacked: true,
ticks: {
min: 0,
stepSize: 1,
}
}]
}
}
});
};
Hope this will help , for reference I have used following documentation Chart JS
Thanks.
Just remove the stacked option and it will stop starting from 0 (unless your data starts from 0).
Related fiddle - http://jsfiddle.net/rsyk9he0/
For stacked charts, Chart.js builds a list of positive and negative sums for each stack (bar) and then uses that to figure out the scale min and max values. If there are no negative values, the list of negative sums is a list of 0s. This forces the scale min to be 0.
scaleStartValue, scaleStepWidth, etc. are options from v1.x of Chart.js. You are using v2.x. See How to make integer scale in Chartjs for the 2.x equivalents.