I could see in ExtJs scattered cart we could use different marker configs to show cross,circle,square etc. But instead of that can we show an image or glyph there?
Yes you can show image instead of circle, square etc.
You will need to override Ext.chart.Shape to add additional image types for your series. You can use those defined types in markerConfig of series.
Basically you will need to define your own shape type which will be created with Ext.draw.Sprite in chart.
Here is a working example with ExtJS 4.2.1.x:
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.override(Ext.chart.Shape, {
newPhone: function (surface, opts) {
return surface.add(Ext.apply({
type: 'image',
src: 'http://icons.iconarchive.com/icons/igh0zt/ios7-style-metro-ui/512/MetroUI-Other-Phone-icon.png',
x: opts.x,
y: opts.y,
width: 14,
height: 14
}, opts));
},
oldPhone: function (surface, opts) {
return surface.add(Ext.apply({
type: 'image',
src: 'https://cdn3.iconfinder.com/data/icons/communication-1/100/old_phone-512.png',
x: opts.x,
y: opts.y,
width: 14,
height: 14
}, opts));
}
});
var store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
data: [{
'name': 'metric one',
'data1': 10,
'data2': 12,
'data3': 14,
'data4': 8,
'data5': 13
}, {
'name': 'metric two',
'data1': 7,
'data2': 8,
'data3': 16,
'data4': 10,
'data5': 3
}, {
'name': 'metric three',
'data1': 5,
'data2': 2,
'data3': 14,
'data4': 12,
'data5': 7
}, {
'name': 'metric four',
'data1': 2,
'data2': 14,
'data3': 6,
'data4': 1,
'data5': 23
}, {
'name': 'metric five',
'data1': 27,
'data2': 38,
'data3': 36,
'data4': 13,
'data5': 33
}]
});
Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 600,
height: 600,
animate: true,
theme: 'Category2',
store: store,
axes: [{
type: 'Numeric',
position: 'left',
fields: ['data2', 'data3'],
title: 'Sample Values',
grid: true,
minimum: 0
}, {
type: 'Category',
position: 'bottom',
fields: ['name'],
title: 'Sample Metrics'
}],
series: [{
type: 'scatter',
markerConfig: {
type: 'oldPhone'
},
axis: 'left',
xField: 'name',
yField: 'data2'
}, {
type: 'scatter',
markerConfig: {
type: 'newPhone'
},
axis: 'left',
xField: 'name',
yField: 'data3'
}]
});
}
});
Example Fiddle: https://fiddle.sencha.com/#view/editor&fiddle/29rm
Related
How do we get the getLimit() and setLimit() methods by using listeners in the scatter chart. And can anyone explain dynamic change of limits in the components.
Here attached code for listeners,
listeners: {
itemmousemove: function (series, item, event,tip) {
console.log('itemmousemove', item.category, item.field);
}
}
How to change dynamically properties of limits in the scatter chart, Attached the code below.
limits: [{
value: 'metric two',
line: {
strokeStyle: 'red',
lineDash: [6, 3],
title: {
text: 'Qty',
fontSize: 14,
fontWeight: 'bold'
}
}
}]
Here is a example how you can manipulate limits in the chart, not realy sure what you wanted to do in the "itemmousemove" so i put it a itemdblclick sample instead :
Sample FIDDLE
Ext.application({
name: 'Fiddle',
layout: 'fit',
launch: function () {
var chart = Ext.create('Ext.chart.CartesianChart', {
width: 600,
height: 400,
insetPadding: 40,
interactions: ['itemhighlight'],
plugins: {
chartitemevents: {
moveEvents: true
}
},
store: {
fields: ['name', 'data1', 'data2'],
data: [{
'name': 'metric one',
'data1': 10,
'data2': 14
}, {
'name': 'metric two',
'data1': 7,
'data2': 16
}, {
'name': 'metric three',
'data1': 5,
'data2': 14
}, {
'name': 'metric four',
'data1': 2,
'data2': 6
}, {
'name': 'metric five',
'data1': 27,
'data2': 36
}]
},
axes: [{
id: 'myAxis',
type: 'numeric',
position: 'left',
fields: ['data1'],
title: {
text: 'Sample Values',
fontSize: 15
},
grid: true,
minimum: 0,
limits: [{
value: 0.2,
line: {
strokeStyle: 'red',
lineDash: [6, 3],
title: {
text: 'Monthly minimum',
fontSize: 14
}
}
}]
}, {
type: 'category',
position: 'bottom',
fields: ['name'],
title: {
text: 'Sample Values',
fontSize: 15
}
}],
series: {
type: 'scatter',
highlight: {
size: 12,
radius: 12,
fill: '#96D4C6',
stroke: '#30BDA7'
},
fill: true,
xField: 'name',
yField: 'data2',
marker: {
type: 'circle',
fill: '#30BDA7',
radius: 10,
lineWidth: 0
}
},
listeners: {
itemdblclick: function (series, item, event, tip) {
var lim = chart.getAxis('myAxis').getLimits();
var new_lim = CreateNewLimit(0.9, 'yellow', 'Clicked Limit');
lim.push(new_lim);
RefreshChart(lim);
}
}
});
Ext.create('Ext.panel.Panel', {
title: 'Scatter Chart',
renderTo: document.body,
tbar: [{
xtype: 'button',
text: 'Toggle Limit',
handler: function () {
var lim = chart.getAxis('myAxis').getLimits();
var new_lim = CreateNewLimit(0.7, 'blue', 'Monthly Max');
if (lim.length == 1) {
lim.push(new_lim);
} else {
lim.splice(1, 1);
}
RefreshChart(lim);
}
}, {
xtype: 'button',
text: 'Add New ',
handler: function () {
var lim = chart.getAxis('myAxis').getLimits();
var new_lim = CreateNewLimit(0.5, 'green', 'Monthly Average');
lim.push(new_lim);
RefreshChart(lim)
}
}],
items: [
chart
]
});
function RefreshChart(lim) {
chart.getAxis('myAxis').setLimits(lim);
chart.getStore().removeAll();
chart.getStore().reload();
}
function CreateNewLimit(val, color, text) {
return {
value: val,
line: {
strokeStyle: color,
lineDash: [6, 3],
title: {
text: text,
fontSize: 14
}
}
};
}
}
});
I use ExtJS to create a line chart and create a button to get image base64.Now, I don't want this button. I need an event whitch fire when the line chart finish draw and then get image base64. I found an event "painted", and I try to use it, but it can't work, Why?.
reference:ExtJS line chart example
Works just fine for me.
Cartesian Graph with a series and some lines inside that.
Add painted listener to the cartesian graph, call getImage('stream') on the cartesian graph (this), check out the data element of the returned object.
I merely added this listener configuration to the cartesian which will display the png data for the full graph in a MessageBox:
listeners: {
painted: function(element, eOpts) {
Ext.Msg.alert('Image Data', this.getImage('stream').data);
}
},
See below for the adjusted full example from the documentation:
Ext.create({
xtype: 'cartesian',
renderTo: document.body,
width: 600,
height: 400,
insetPadding: 40,
listeners: {
painted: function(element, eOpts) {
Ext.Msg.alert('Image Data', this.getImage('stream').data);
}
},
store: {
fields: ['name', 'data1', 'data2'],
data: [{
'name': 'metric one',
'data1': 10,
'data2': 14
}, {
'name': 'metric two',
'data1': 7,
'data2': 16
}, {
'name': 'metric three',
'data1': 5,
'data2': 14
}, {
'name': 'metric four',
'data1': 2,
'data2': 6
}, {
'name': 'metric five',
'data1': 27,
'data2': 36
}]
},
axes: [{
type: 'numeric',
position: 'left',
fields: ['data1'],
title: {
text: 'Sample Values',
fontSize: 15
},
grid: true,
minimum: 0
}, {
type: 'category',
position: 'bottom',
fields: ['name'],
title: {
text: 'Sample Values',
fontSize: 15
}
}],
series: [{
type: 'line',
style: {
stroke: '#30BDA7',
lineWidth: 2
},
xField: 'name',
yField: 'data1',
marker: {
type: 'path',
path: ['M', - 4, 0, 0, 4, 4, 0, 0, - 4, 'Z'],
stroke: '#30BDA7',
lineWidth: 2,
fill: 'white'
}
}, {
type: 'line',
fill: true,
style: {
fill: '#96D4C6',
fillOpacity: .6,
stroke: '#0A3F50',
strokeOpacity: .6,
},
xField: 'name',
yField: 'data2',
marker: {
type: 'circle',
radius: 4,
lineWidth: 2,
fill: 'white'
}
}]
});
At the top of my view, I have defined the following variable:
var chartq = new Ext.chart.Chart({
renderTo : Ext.getBody(),
xtype: 'chart',
animate: true,
width : 400,
height : 300,
store: {
fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
data: [{
'name': 'metric one',
'data1': 10,
'data2': 12,
'data3': 14,
'data4': 8,
'data5': 13
}, {
'name': 'metric two',
'data1': 7,
'data2': 8,
'data3': 16,
'data4': 10,
'data5': 3
}, {
'name': 'metric three',
'data1': 5,
'data2': 2,
'data3': 14,
'data4': 12,
'data5': 7
}, {
'name': 'metric four',
'data1': 2,
'data2': 14,
'data3': 6,
'data4': 1,
'data5': 23
}, {
'name': 'metric five',
'data1': 27,
'data2': 38,
'data3': 36,
'data4': 13,
'data5': 33
}]
},
axes: [{
type: 'numeric',
position: 'left',
title: {
text: 'Sample Values',
fontSize: 15
},
fields: 'data1'
}, {
type: 'category',
position: 'bottom',
title: {
text: 'Sample Values',
fontSize: 15
},
fields: 'name'
}],
series: [{
type: 'bar',
xField: 'name',
yField: 'data1',
style: {
fill: 'blue'
}
}]
});
Ext.define('axis3.view.Chart', {
extend: 'Ext.Panel',
requires: ['Ext.TitleBar'],
alias: 'widget.chartview',
getSlideLeftTransition: function () {
return { type: 'slide', direction: 'left' };
},
getSlideRightTransition: function () {
return { type: 'slide', direction: 'right' };
},
config: {
layout: {
type: 'fit'
},
items: [{
xtype : 'label',
html : 'Some label.'
},
{
xtype: 'container',
flex: 1,
items:chartq //Ext.chart.Chart
},
{
xtype: 'toolbar',
docked: 'bottom',
},
{
xtype: 'titlebar',
title: 'Axis First Stats App',
docked: 'top',
items: [
{
xtype: 'button',
text: 'Log Off',
itemId: 'logOffButton',
align: 'right'
},
{
xtype: 'button',
text: 'Back',
itemId: 'backButton',
align: 'left'
},
],
}],
html: [
'<div id="localuid">Signed in Uid: <span>'+localStorage.uid+'</span></div>'
].join(""),
listeners: [{
delegate: '#logOffButton',
event: 'tap',
fn: 'onLogOffButtonTap'
},{
delegate: '#backButton',
event: 'tap',
fn: 'onBacktButtonTap'
}]
},
onLogOffButtonTap: function () {
localStorage.clear();
window.location.reload();
},
onBackButtonTap: function () {
Ext.create('axis3.view.Main',{});
Ext.Viewport.animateActiveItem('mainview', this.getSlideRightTransition());
},
});
The view becomes active as expected when a button in the toolbar is pressed. But, the chart is not visible. No errors are shown in console log. I have tried adding the variable to the config and to the 'items', but the chart still does not show. No errors in console.log
The container for the chart is being created in the browser as expected - just no graph appearing
Can someone please tell me what I am missing?
Charts need a width and height before they'll render properly. I added a static width and height to your chartq definition and it appeared as I would expect:
var chartq = new Ext.chart.Chart({
width: 100,
height: 100,
store: {...
I need lowest value on my vertical axis to be zero. I have set minimum: 0 in my view, but it still shows the lowest value to be a figure less than zero. The lowest value in my data is 1 - there are NO values less than zero.
Here is the view:
var chartq = new Ext.chart.Chart({
renderTo : Ext.getBody(),
xtype: 'chart',
id:'demochart',
animate: true,
width : '80%',
height : '60%',
store: {
fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
data: [{
'name': 'metric one',
'data1': 10,
'data2': 12,
'data3': 14,
'data4': 8,
'data5': 13
}, {
'name': 'metric two',
'data1': 7,
'data2': 8,
'data3': 16,
'data4': 10,
'data5': 3
}, {
'name': 'metric three',
'data1': 5,
'data2': 2,
'data3': 14,
'data4': 12,
'data5': 7
}, {
'name': 'metric four',
'data1': 2,
'data2': 14,
'data3': 6,
'data4': 1,
'data5': 23
}, {
'name': 'metric five',
'data1': 27,
'data2': 38,
'data3': 36,
'data4': 13,
'data5': 33
}]
},
axes: [{
type: 'numeric',
position: 'left',
minumum: 0,
title: {
text: 'Sample Values',
fontSize: 15
},
fields: 'data1'
}, {
type: 'category',
position: 'bottom',
title: {
text: 'Sample Values',
fontSize: 15
},
fields: 'name'
}],
series: [{
type: 'column',
stacked: true,
xField: 'name',
yField: 'data1',
style: {
fill: 'blue'
}
}]
});
///////////////////////////////////////////////
Ext.define('axis3.view.Main', {
extend: 'Ext.form.Panel',
requires: ['Ext.TitleBar','Ext.data.Store','Ext.chart.Chart'],
alias: 'widget.mainview',
getSlideLeftTransition: function () {
return { type: 'slide', direction: 'left' };
},
getSlideRightTransition: function () {
return { type: 'slide', direction: 'right' };
},
config: {
layout: {
type: 'fit'
},
items: [
{
xtype : 'container',
flex: 1,
items: [chartq] //Ext.chart.Chart
},
{
xtype : 'selectfield',
store : companiesStore2,
name : 'companies',
id : 'companiesSelect',
itemId: 'companySelect',
valueField : 'companyname',
displayField : 'companyname',
},
{
xtype: 'toolbar',
docked: 'bottom',
items: [],
},{
xtype: 'titlebar',
title: 'Axis First Stats App',
docked: 'top',
items: [
{
xtype: 'button',
text: 'Log Off',
itemId: 'logOffButton2',
align: 'right'
},
],
}],
html: [
'<div id="newContent"></div>'
].join(""),
listeners: [{
delegate: '#companySelect',
event: 'change',
fn: 'onGetStatsCommand'
},{
delegate: '#logOffButton2',
event: 'tap',
fn: 'onLogOffButtonTap'
},{
delegate: '#chartButton',
event: 'tap',
fn: 'onChartButtonTap'
}]
},
onGetStatsCommand: function () {
this.fireEvent('onGetStatsCommand', Ext.getCmp('companiesSelect').getValue());
},
onLogOffButtonTap: function () {
this.fireEvent('onSignOffCommand');
},
onChartButtonTap: function () {
Ext.create('axis3.view.Chart',{});
Ext.Viewport.animateActiveItem('chartview', this.getSlideLeftTransition());
}
});
And the chart
Weirdly, in the fiddle it looks correct
What do I need to do to correct this issue?
You've written minumum instead of minimum in your axis config.
My task is to fetch different types of charts ,when i click from the drop down box.
Based on which graph i select from dropdown ,i need to display the same in JS file.
Currently i can display different types of charts.
Can you please help me how to fetch from based on dropdown values through sencha EXT JS.
Thanks in advance..
please find the attached code below.
/*global Ext:false */
Ext.onReady(function () {
// The data store containing the list of states
var charts = Ext.create('Ext.data.Store', {
fields: [ 'name'],
data: [{
"name": "Bar"
}, {
"name": "Pie"
}, {
"name": "Line"
},{
"name": "Area"
}, {
"name": "Column"
}, {
"name": "Gauge"
}
]
});
// Create the combo box, attached to the charts data store
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose Chart',
store: charts,
queryMode: 'local',
displayField: 'name',
renderTo: Ext.getBody()
});
//Line Chart
var store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
data: [
{ 'name': 'metric one', 'data1': 10, 'data2': 12, 'data3': 14, 'data4': 8, 'data5': 13 },
{ 'name': 'metric two', 'data1': 7, 'data2': 8, 'data3': 16, 'data4': 10, 'data5': 3 },
{ 'name': 'metric three', 'data1': 5, 'data2': 2, 'data3': 14, 'data4': 12, 'data5': 7 },
{ 'name': 'metric four', 'data1': 2, 'data2': 14, 'data3': 6, 'data4': 1, 'data5': 23 },
{ 'name': 'metric five', 'data1': 4, 'data2': 4, 'data3': 36, 'data4': 13, 'data5': 33 }
]
});
var linechart = Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 500,
height: 300,
animate: true,
store: store,
axes: [
{
type: 'Numeric',
position: 'left',
fields: ['data1', 'data2'],
label: {
renderer: Ext.util.Format.numberRenderer('0,0')
},
title: 'Sample Values',
grid: true,
minimum: 0
},
{
type: 'Category',
position: 'bottom',
fields: ['name'],
title: 'Sample Metrics'
}
],
series: [
{
type: 'line',
highlight: {
size: 7,
radius: 7
},
axis: 'left',
xField: 'name',
yField: 'data1',
markerConfig: {
type: 'cross',
size: 4,
radius: 4,
'stroke-width': 0
}
},
{
type: 'line',
highlight: {
size: 7,
radius: 7
},
axis: 'left',
fill: true,
xField: 'name',
yField: 'data2',
markerConfig: {
type: 'circle',
size: 4,
radius: 4,
'stroke-width': 0
}
}
]
});
//Bar Chart
var store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'data'],
data: [
{ 'name': 'metric one', 'data':10 },
{ 'name': 'metric two', 'data': 7 },
{ 'name': 'metric three', 'data': 5 },
{ 'name': 'metric four', 'data': 2 },
{ 'name': 'metric five', 'data':27 }
]
});
Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 500,
height: 300,
animate: true,
store: store,
axes: [{
type: 'Numeric',
position: 'bottom',
fields: ['data'],
label: {
renderer: Ext.util.Format.numberRenderer('0,0')
},
title: 'Sample Values',
grid: true,
minimum: 0
}, {
type: 'Category',
position: 'left',
fields: ['name'],
title: 'Sample Metrics'
}],
series: [{
type: 'bar',
axis: 'bottom',
highlight: true,
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item) {
this.setTitle(storeItem.get('name') + ': ' + storeItem.get('data') + ' views');
}
},
label: {
display: 'insideEnd',
field: 'data',
renderer: Ext.util.Format.numberRenderer('0'),
orientation: 'horizontal',
color: '#333',
'text-anchor': 'middle'
},
xField: 'name',
yField: 'data'
}]
});
//pie chart
var store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'data'],
data: [
{ 'name': 'metric one', 'data': 10 },
{ 'name': 'metric two', 'data': 7 },
{ 'name': 'metric three', 'data': 5 },
{ 'name': 'metric four', 'data': 2 },
{ 'name': 'metric five', 'data': 27 }
]
});
Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 500,
height: 350,
animate: true,
store: store,
theme: 'Base:gradients',
series: [{
type: 'pie',
angleField: 'data',
showInLegend: true,
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item) {
// calculate and display percentage on hover
var total = 0;
store.each(function(rec) {
total += rec.get('data');
});
this.setTitle(storeItem.get('name') + ': ' + Math.round(storeItem.get('data') / total * 100) + '%');
}
},
highlight: {
segment: {
margin: 20
}
},
label: {
field: 'name',
display: 'rotate',
contrast: true,
font: '18px Arial'
}
}]
});
//column chart
var store = Ext.create('Ext.data.JsonStore', {
fields: ['name', 'data'],
data: [
{ 'name': 'January', 'data': 10 },
{ 'name': 'February', 'data': 20 },
{ 'name': 'March', 'data': 30},
{ 'name': 'April', 'data': 40 },
{ 'name': 'May', 'data': 50 },
{ 'name': 'June', 'data': 60 },
{ 'name': 'July', 'data': 70 },
{ 'name': 'August', 'data': 60 },
{ 'name': 'September', 'data': 50 },
{ 'name': 'October', 'data': 40},
{ 'name': 'November', 'data': 30},
{ 'name': 'December', 'data': 20}
]
});
Ext.create('Ext.chart.Chart', {
renderTo: Ext.getBody(),
width: 1000,
height: 500,
animate: true,
store: store,
axes: [
{
type: 'Numeric',
position: 'left',
fields: ['data'],
label: {
renderer: Ext.util.Format.numberRenderer('0,0')
},
title: 'Sample Values',
grid: true,
minimum: 0
},
{
type: 'Category',
position: 'bottom',
fields: ['name'],
title: 'Sample Metrics'
}
],
series: [
{
type: 'column',
axis: 'left',
highlight: true,
tips: {
trackMouse: true,
width: 140,
height: 28,
renderer: function(storeItem, item) {
this.setTitle(storeItem.get('name') + ': ' + storeItem.get('data') + ' $');
}
},
label: {
display: 'insideEnd',
'text-anchor': 'middle',
field: 'data',
renderer: Ext.util.Format.numberRenderer('0'),
orientation: 'vertical',
color: '#333'
},
xField: 'name',
yField: 'data'
}
]
});
});
You're going to want to get yourself familiar with the card layout:
For the component to switch views, I feel you're better off using a button with a menu selecting your charts than trying a combo box.
Ext.create('Ext.button.Button', {
text: 'Select Chart',
menu: this.getChartList,
action: 'selectChart',
menuAlign: 'tl-bl'
}]
getChartList: function() {
var menuItems = [];
this.store.each(function(rec) {
mainMenuItems.push({
text: rec.get('name')
});
}
return new Ext.menu.Menu({
items: mainMenuItems
});
}
Then in your controller, or wherever you want to listen to your button:
this.control({
'button[action=selectChart] menuitem': {
click: this.onSelectChartClick,
}
});
onSelectChartClick: function(item) {
switch (item.text) {
case 'Bar':
//logic for showing bar graph
break;
case 'Pie':
//logic for showing pie chart
break;
case 'Line':
//logic for showing line graph
break;
}
}
As for the logic to show the charts, on init you should create a card layout... you could start with a container that holds your items:
this.p = Ext.create('Ext.panel.Panel', {
layout: 'card',
items: [
this.createBarGraph(),
this.createPieChart(),
this.createLineGraph()
]
});
and then on your button listener you can set the active item to your charts:
this.p.getLayout().setActiveItem(this.barGraph);