ExtJs 5.1.0 - Unrecognized class name / alias: widget.cartesian - javascript

I want to show a stacked area chart in a new window. The enviroment is the ExtJs Webdesktop.
When I create the window through:
Ext.create('Desktop.displayPresences.view.displayPresencesChart').show()
I always get these error messages:
mypath/desktop/widget/cartesian.js?_dc=1423082524533 404 (Not Found)
Error: [Ext.create] Unrecognized class name / alias: widget.cartesian
I researched a lot but couldn't solve the problem yet.
What I've done:
Added this to app.json
"requires": [
"ext-charts"
],
Through sencha cmd I tried these commands
sencha app build
sencha app refresh
sencha app watch
In the google develeopers tools in the sources tab I can see that the necessary file 'Ext.chart.series.Cartesian' is loaded. It is in the packages/ext-charts/src/chart/series folder.
This is my code
Ext.define('Desktop.displayPresences.view.displayPresencesChart', {
extend: 'Ext.Window',
requires: [
'Ext.chart.*',
'Ext.data.JsonStore'
],
xtype: 'area-stacked',
width: 650,
initComponent: function() {
var me = this;
this.myDataStore = Ext.create('Ext.data.JsonStore', {
fields: ['month', 'data1', 'data2', 'data3', 'data4' ],
data: [
{ month: 'Jan', data1: 20, data2: 37, data3: 35, data4: 4 },
{ month: 'Feb', data1: 20, data2: 37, data3: 36, data4: 5 },
{ month: 'Mar', data1: 19, data2: 36, data3: 37, data4: 4 },
{ month: 'Apr', data1: 18, data2: 36, data3: 38, data4: 5 },
{ month: 'May', data1: 18, data2: 35, data3: 39, data4: 4 },
{ month: 'Jun', data1: 17, data2: 34, data3: 42, data4: 4 },
{ month: 'Jul', data1: 16, data2: 34, data3: 43, data4: 4 },
{ month: 'Aug', data1: 16, data2: 33, data3: 44, data4: 4 },
{ month: 'Sep', data1: 16, data2: 32, data3: 44, data4: 4 },
{ month: 'Oct', data1: 16, data2: 32, data3: 45, data4: 4 },
{ month: 'Nov', data1: 15, data2: 31, data3: 46, data4: 4 },
{ month: 'Dec', data1: 15, data2: 31, data3: 47, data4: 4 }
]
});
me.items = [{
xtype: 'cartesian',
width: '100%',
height: 500,
legend: {
docked: 'bottom'
},
store: this.myDataStore,
insetPadding: 40,
sprites: [{
type: 'text',
text: 'Area Charts - Stacked Area',
font: '22px Helvetica',
width: 100,
height: 30,
x: 40, // the sprite x position
y: 20 // the sprite y position
}, {
type: 'text',
text: 'Data: Browser Stats 2012',
font: '10px Helvetica',
x: 12,
y: 430
}, {
type: 'text',
text: 'Source: http://www.w3schools.com/',
font: '10px Helvetica',
x: 12,
y: 440
}],
axes: [{
type: 'numeric',
fields: 'data1',
position: 'left',
grid: true,
minimum: 0,
renderer: function (v) { return v.toFixed(v < 10 ? 1: 0) + '%'; }
}, {
type: 'category',
fields: 'month',
position: 'bottom',
grid: true,
label: {
rotate: {
degrees: -45
}
}
}],
series: [{
type: 'area',
axis: 'left',
title: [ 'IE', 'Firefox', 'Chrome', 'Safari' ],
xField: 'month',
yField: [ 'data1', 'data2', 'data3', 'data4' ],
style: {
opacity: 0.80
},
highlight: {
fillStyle: '#000',
lineWidth: 2,
strokeStyle: '#fff'
},
tooltip: {
trackMouse: true,
style: 'background: #fff',
renderer: function(storeItem, item) {
var browser = item.series.getTitle()[Ext.Array.indexOf(item.series.getYField(), item.field)];
this.setHtml(browser + ' for ' + storeItem.get('month') + ': ' + storeItem.get(item.field) + '%');
}
}
}]
}];
this.callParent();
}
});
I don't know why the xtype: 'cartesian' is searching at this location (mypath/desktop/widget/cartesian.js)?
Normally you need for an xtype an alias, but when I check Ext.chart.series.Cartesian there is no alias definied?
So I tried to define one by myself. But then I just got the message: Uncaught TypeError: undefined is not a function.
Any ideas how to fix this?
This is my file structure in the developer tools:
Best regards

I could solve it, my entry in app.json was wrong.
If you want to use the cartesian as a xtype you have to use the new 'sencha-charts', 'ext-charts' was from the old ExtJs Version.
Additionally I set 'Ext.chart.Cartesian' as a direct require.

If you look more at the Ext.chart.series.Cartesian and its parent Ext.chart.series.Series, you'll see that they are not widgets - that is, they re not descendants of Ext.component.Component. This explains the lack of an xtype.
The widget that has the xtype of 'cartesian' is Ext.chart.Cartesian.
The next part of the answer is why you can't see that. You've got the package loaded via app.json correctly, and I would assume that the Ext.chart.Cartesian is being loaded correctly by your wildcard requires (I don't use those, personally). So on that part, I'm stumped - the only thing I can suggest is checking in the dev tools to make sure the Cartesian chart is loaded, and possibly dropping the wildcard requires for an explicit list of the desired classes.

Related

Date label in JavaScript chart doesn't display properly

I'm doing a Django project. In my chart.html file, I created a javascript bar chart. The data and the label of the chart have been defined in my views.py file.
This is my JavaScript bar chart: (I'm drawing this chart to display the order numbers in the most recent 7 days)
var ctx = document.getElementById("BarChart7d");
var BarChart7d = new Chart(ctx, {
type: 'bar',
data: {
labels: [{{date7}}, {{date6}}, {{date5}}, {{date4}}, {{date3}}, {{date2}}, {{date1}}],
datasets: [{
label: "orders: ",
backgroundColor: ['#4e73df', '#1cc88a', '#36b9cc', "#e74a3b", "#f6c23e", "#9B59B6", "#D68910"],
hoverBackgroundColor: ['#353F8C ', '#17a673', '#2c9faf', "#9C4545", "#9C8545", "#4A235A", "#784212"],
borderColor: "#4e73df",
data: {{value7day}},
}],
},
options: {
maintainAspectRatio: false,
layout: {
padding: {
left: 10,
right: 25,
top: 25,
bottom: 0
}
},
scales: {
xAxes: [{
gridLines: {
display: false,
drawBorder: false
},
ticks: {
maxTicksLimit: 6
},
maxBarThickness: 80,
}],
yAxes: [{
ticks: {
callback: function(value, index, values) {
return number_format(value);
}
},
gridLines: {
color: "rgb(234, 236, 244)",
zeroLineColor: "rgb(234, 236, 244)",
drawBorder: false,
borderDash: [2],
zeroLineBorderDash: [2]
}
}],
},
legend: {
display: false
},
tooltips: {
titleMarginBottom: 10,
titleFontColor: '#6e707e',
titleFontSize: 14,
backgroundColor: "rgb(255,255,255)",
bodyFontColor: "#858796",
borderColor: '#dddfeb',
borderWidth: 1,
xPadding: 15,
yPadding: 15,
displayColors: false,
caretPadding: 10,
callbacks: {
label: function(tooltipItem, chart) {
var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || '';
return datasetLabel + number_format(tooltipItem.yLabel);
}
}
},
}
});
The {{value7day}} and the labels {{date7}} to {{date1}} have been defined in views.py:
rnow = {'date': '2022-01-15', 'value': 34},
...
{'date': '2022-03-16', 'value': 26},
{'date': '2022-03-17', 'value': 15},
{'date': '2022-03-18', 'value': 13},
{'date': '2022-03-21', 'value': 29},
{'date': '2022-03-22', 'value': 22},
{'date': '2022-03-23', 'value': 22},
{'date': '2022-03-24', 'value': 25},
{'date': '2022-03-25', 'value': 15}]
day1 = list(rnow)[-1]
day2 = list(rnow)[-2]
day3 = list(rnow)[-3]
day4 = list(rnow)[-4]
day5 = list(rnow)[-5]
day6 = list(rnow)[-6]
day7 = list(rnow)[-7]
value7day = [ day7['value'], day6['value'], day5['value'] , day4['value'], day3['value'], day2['value'], day1['value']]
date7 = day7['date']
date6 = day6['date']
date5 = day5['date']
date4 = day4['date']
date3 = day3['date']
date2 = day2['date']
date1 = day1['date']
The date data is already string type. However, the labels are not shown properly. Instead of being displayed as 2022-03-17, 2022-03-18, 2022-03-21 they are displayed as 2002, 2001, 1998 ?? I think I should change the format of the label to date. How should I do that?
I imagine your javascript ends up looking like
data: {
labels: [2022-03-16, 2022-03-17, ...]
The labels are treated as numbers, and some subtraction is done, so you end up with values like 1998, etc.
Those values should be strings:
labels: ["2022-03-16", "2022-03-17", ...]
in other words
labels: ["{{date7}}", "{{date6}}", ...]

Highcharts - Y axis colors by point

How can I configure the y axis so that it has different colors?
From this:
enter image description here
To this:
enter image description here
JSFIDDLE:
yAxis: {
min: 0,
title: {
text: 'Population (millions)',
align: 'high'
},
labels: {
overflow: 'justify'
},
lineWidth: 2
},
Maybe someone had a similar problem?
https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/bar-basic/
You can achieve it by setting yAxis.lineColor as Highcharts.GradientColorObject. Check the demo and code posted below.
Code:
Highcharts.chart('container', {
chart: {
type: 'bar',
events: {
load: function() {
let chart = this,
yAxis = chart.yAxis[0];
yAxis.update({
lineColor: {
linearGradient: [chart.plotLeft + yAxis.width, 0, 0, 0],
stops: [
[0, 'yellow'],
[0.33, 'yellow'],
[0.33, 'red'],
[0.66, 'red'],
[0.66, '#21B04C'],
[1, '#21B04C']
]
}
})
}
}
},
xAxis: {
categories: ['Africa', 'America', 'Asia', 'Europe', 'Oceania']
},
yAxis: {
lineWidth: 4
},
series: [{
name: 'Year 1800',
data: [107, 31, 635, 203, 2]
}, {
name: 'Year 1900',
data: [133, 156, 947, 408, 6]
}, {
name: 'Year 2000',
data: [814, 841, 3714, 727, 31]
}, {
name: 'Year 2016',
data: [1216, 1001, 4436, 738, 40]
}]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<div id="container"></div>
Demo:
https://jsfiddle.net/BlackLabel/7feLmsvq/
API reference:
https://api.highcharts.com/highcharts/yAxis.lineColor
https://api.highcharts.com/highcharts/chart.events.load
https://api.highcharts.com/class-reference/Highcharts.Axis#update
https://api.highcharts.com/class-reference/Highcharts.GradientColorObject

Highcharts legend item not displaying properly (until window is resized)

I have a chart with legend items which are overlapping each other (this is the image for itemDistance option set to 20 - clearly the distance between items is less than 20px, it seems that 20px is item distance between legend symbols):
The chart is fixed and legend is displayed properly only after resizing the window (image for exactly same configuration object - the only window has been resized):
I can't figure out what I have done wrong or if I have just encountered a bug in Highcharts. I'm using Highcharts v. 7.2.0 with HighchartsReactOfficial library v. 2.2.2. My configuration object:
const options: Highcharts.Options = {
chart: {
type: 'spline',
spacingLeft: 40,
spacingRight: 40,
},
title: {
style: {
display: 'none',
},
},
subtitle: {
style: {
display: 'none',
},
},
credits: {
enabled: false,
},
legend: {
itemDistance: 20,
itemStyle: {
color: '#7990A1',
},
},
plotOptions: {
series: {
marker: {
symbol: 'circle',
lineWidth: 1,
},
shadow: true,
},
},
series: [{
name: 'test1',
type: 'spline',
color: '#576A7B',
data: [23, 3, 33, 54, 29, 38],
},
{
name: 'test2',
type: 'spline',
color: '#FE7B1A',
data: [45, 21, 76, 43, 67, 59],
},
{
name: 'test3',
type: 'spline',
color: '#00BAFF',
data: [7, 19, 5, 9, 12, 11],
},
{
name: 'test4',
type: 'spline',
color: '#000000',
data: [40, 3, 71, 20, 28, 31],
},
],
yAxis: {
title: {
style: {
display: 'none',
},
},
showFirstLabel: false,
},
xAxis: {
categories: ['2019-05-15', '2019-05-16', '2019-05-17', '2019-05-18', '2019-05-19', '2019-05-20'],
},
};
Used by rendering component:
<HighchartsReact highcharts={Highcharts} options={options} />
Help will be greatly appreciated.

Is it possible to dynamically add more Y Axes or more X Axes on chart js?

I've been trying for a few days to dynamically add custom scales to my chart, using chart js. I am using Angular 2 and Typescript.
I tried it in two different ways. The first one triggers an error. The second one works but it's not what i am aiming for. So what am I doing wrong?
First method:
I have a modal which has some inputs to set a custom scale and it returns an object that looks like the scale object from the Chart JS documentation:
customScale = {
id: 'y-axis-2',
type: 'linear',
position:'right',
scaleLabel: {
display: true,
labelString: 'scale 3'
},
ticks: {
max: 20,
min: 1
}
}
I have a function who is supposed to add that scale to the scales array attached to my chart.
addCustomScale(customScale: any, axis: string) {
const ci = this.chartComponent.chart;
let scale = [];
scale.push(customScale);
if (axis === 'Axis Y') {
ci.options.scales.yAxes = Chart.helpers.scaleMerge(Chart.defaults.scale,{yAxes: scale}).yAxes;
} else {
ci.options.scales.xAxes = Chart.helpers.scaleMerge(Chart.defaults.scale, {xAxes: scale}).xAxes;
}
ci.update();
}
When calling this function, i get an error:
ERROR TypeError: Cannot set property 'options' of undefined
at core.controller.js:51
So far my chart looks like this:
<canvas width="600" height="300" id="canvas" #myCanvas baseChart
[datasets]="lineChartData"
[labels]="lineChartLabels"
[options]="mfChartOptions"
[legend]="lineChartLegend"
[chartType]="lineChartType"></canvas>
I defined everything in typescript:
import {BaseChartDirective} from 'ng2-charts';
declare const Chart: any;
#Component({
selector: 'app-chart',
templateUrl: './chart.component.html',
styleUrls: ['./chart.component.css']
})
export class ChartComponent {
#ViewChild(BaseChartDirective) chartComponent: BaseChartDirective;
public lineChartData: Array<any> = [
{data: [65, 59, 80, 81, 56, 55, 40], yAxisID: 'y-axis-0', label: 'Series A'},
{data: [28, 48, 40, 19, 86, 27, 90], yAxisID: 'y-axis-1', label: 'Series B'},
{data: [18, 48, 77, 9, 100, 27, 40], yAxisID: 'y-axis-1', label: 'Series C'}
];
public lineChartLabels: Array<any> = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
public lineChartLegend = true;
public lineChartType = 'line';
public mfChartOptions = {
responsive: true,
pan: {
enabled: true,
mode: 'xy'
},
zoom: {
enabled: true,
drag: true,
mode: 'xy'
},
legend: {
position: 'bottom',
},
scales: {
yAxes: [{
id: 'y-axis-0',
type: 'linear',
position: 'left',
}, {
id: 'y-axis-1',
type: 'linear',
position: 'right',
ticks: {
max: 100,
min: 0
}
}]
},
annotation: {
events: ['click'],
annotations: []
},
tooltipTemplate: '<%if (label){%><%=label %>: <%}%><%= value + \' %\' %>',
tooltips: {
intersect: true,
bodySpacing: 4
},
plugins: {
filler: {
propagate: true
}
}
};
Second method. I just added another scale to the scales that i already have in options, like this:
public mfChartOptions = {
responsive: true,
pan: {
enabled: true,
mode: 'xy'
},
zoom: {
enabled: true,
drag: true,
mode: 'xy'
},
scales: {
yAxes: [{
id: 'y-axis-0',
type: 'linear',
position: 'left',
}, {
id: 'y-axis-1',
type: 'linear',
position: 'right',
ticks: {
max: 100,
min: 0
}
}, {
id: 'y-axis-2',
type: 'linear',
position: 'right',
ticks: {
max: 80,
min: 40
}
}]
},
annotation: {
events: ['click'],
annotations: []
},
tooltipTemplate: '<%if (label){%><%=label %>: <%}%><%= value + \' %\' %>',
tooltips: {
intersect: true,
bodySpacing: 4
},
plugins: {
filler: {
propagate: true
}
}
};
And changed my dataset to:
public lineChartData: Array<any> = [
{data: [65, 59, 80, 81, 56, 55, 40], yAxisID: 'y-axis-0', label: 'Series A'},
{data: [28, 48, 40, 19, 86, 27, 90], yAxisID: 'y-axis-1', label: 'Series B'},
{data: [18, 48, 77, 9, 100, 27, 40], yAxisID: 'y-axis-2', label: 'Series C'}
];
This one works just fine, but i want to allow the user to create a custom scale, instead of hard coding it.
you can destroy the chart and run new Chart function again.
Here is fiddle : https://jsfiddle.net/cbalakus/fhadc9by/
function addYAxis() {
var leng = window.myLine.options.scales.yAxes.length + 1;
var clr = chartColors[Math.floor(Math.random() * chartColors.length)];
opts.scales.yAxes.push({
type: "linear",
display: true,
position: "right",
id: "y-axis-" + leng,
ticks: {
fontColor: clr
}
});
lineChartData.datasets.push({
label: "y-axis-" + leng,
borderColor: clr,
backgroundColor: clr,
fill: false,
data: getDatas(),
yAxisID: "y-axis-" + leng,
});
window.myLine.destroy();
var ctx = document.getElementById("cvs").getContext("2d");
window.myLine = Chart.Line(ctx, {
data: lineChartData,
options: opts
});
}

Setting up the Shield UI JavaScript Chart Stacking mode property

I am trying to set some stacking for my Shield UI JavaScipt Chart. I use the following code, that doesn’t seem to work:
$(function () {
$("#chart").shieldChart({
primaryHeader: {
text: 'Shield UI Inversed Bar Chart Example',
align: 'center'
},
isInverted: true,
seriesSettings: {
dataSeries: [
{
seriesType: 'bar',
stackMode: "percent",
collectionAlias: 'Series A',
data: [12, 22, 25, 32, 33, 25]
},
{
seriesType: 'bar',
collectionAlias: 'Series B',
data: [22, 11, 22, 31, 32, 22]
},
{
seriesType: 'bar',
collectionAlias: 'Series C',
data: [20, 37, 11, 22, 25, 24]
}
]
});
});
I tried with stackMode: "normal", as well, but it didn’t solve the problem.
Here is your code with corrected syntax:
$(function () {
$("#chart").shieldChart({
primaryHeader: {
text: 'Shield UI Inversed Bar Chart Example',
align: 'center'
},
isInverted: true,
seriesSettings: {
dataSeries: [
{
seriesType: 'bar',
stackMode: "percent",
collectionAlias: 'Series A',
data: [12, 22, 25, 32, 33, 25]
},
{
seriesType: 'bar',
collectionAlias: 'Series B',
data: [22, 11, 22, 31, 32, 22]
},
{
seriesType: 'bar',
collectionAlias: 'Series C',
data: [20, 37, 11, 22, 25, 24]
}
]
}
});
});
The stackMode property is applicable for the whole chart e.g. all the series. It is not allowed to place it per series. Neither does it make any sense.
seriesSettings: {
bar: {
stackMode: "percent"
}
},
And here is the whole code you can test:
$(function() {
$("#chart").shieldChart({
primaryHeader: {
text: 'Shield UI Inversed Bar Chart Example',
align: 'center'
},
isInverted: true,
seriesSettings: {
bar: {
stackMode: "percent"
}
},
dataSeries: [
{
seriesType: 'bar',
collectionAlias: 'Series A',
data: [12,-522,25,32,33,25]
},
{
seriesType: 'bar',
collectionAlias: 'Series B',
data: [22,11,22,31,32,22]
},
{
seriesType: 'bar',
collectionAlias: 'Series C',
data: [20,37,11,22,25,24]
}
]
});
});

Categories