var ctChart = new wijmo.chart.FlexChart('#chartTypes', {
itemsSource: appData,
bindingX: 'country',
series: [
{ name: 'Sales', binding: 'sales' },
{ name: 'Expenses', binding: 'expenses' },
{ name: 'Downloads', binding: 'downloads' }
]
});
var typeMenu = new wijmo.input.Menu('#typeMenu', {
itemClicked: function (s, e) {
ctChart.chartType = parseInt(s.selectedValue);
updateMenuHeader(s, 'Chart Type');
}
});
updateMenuHeader(typeMenu, 'Chart Type');
var stackingMenu = new wijmo.input.Menu('#stackingMenu', {
itemClicked: function (s, e) {
ctChart.stacking = parseInt(s.selectedValue);
updateMenuHeader(s, 'Stacking');
}
});
updateMenuHeader(stackingMenu, 'Stacking');
var rotatedMenu = new wijmo.input.Menu('#rotatedMenu', {
itemClicked: function (s, e) {
ctChart.rotated = s.selectedValue == 'true';
updateMenuHeader(s, 'Rotated');
}
});
updateMenuHeader(rotatedMenu, 'Rotated');
Result (live):
Range Bar/Column
By default, Bar and Column charts show values extending from
zero to a given value. Range Bar and Column charts use two
bindings so you can specify where each bar or column starts
and ends.
The example below shows how to create range bar/column charts:
var rngChart = new wijmo.chart.FlexChart('#rangebarChart', {
itemsSource: rangeData,
bindingX: 'country',
series: [{ binding: 'num1,num2' }],
tooltip: {
content: function (ht) {
var str = ht.x + ': ';
var dataTypes = rangebarDataTypeMenu.selectedValue.split(',');
var min = Math.min(ht.item[dataTypes[0]], ht.item[dataTypes[1]]);
var max = Math.max(ht.item[dataTypes[0]], ht.item[dataTypes[1]]);
if (wijmo.isDate(ht.item[dataTypes[0]])) {
str += (new Date(min)).toLocaleDateString() + ' - ' + (new Date(max)).toLocaleDateString();
} else {
str += Math.round(min) + ' - ' + Math.round(max);
}
return str;
}
}
});
var rangebarTypeMenu = new wijmo.input.Menu('#rangebarTypeMenu', {
itemClicked: function (s, e) {
rngChart.chartType = parseInt(s.selectedValue);
updateMenuHeader(s, 'Chart Type');
}
});
updateMenuHeader(rangebarTypeMenu, 'Chart Type');
var rangebarDataTypeMenu = new wijmo.input.Menu('#rangebarDataTypeMenu', {
itemClicked: function (s, e) {
rngChart.series[0].binding = s.selectedValue;
updateMenuHeader(s, 'Data Type');
}
});
updateMenuHeader(rangebarDataTypeMenu, 'Data Type');
Result (live):
Funnel Charts
Funnel charts are often used to represent stages in a sales process and
show the amount of potential revenue for each stage. They can also be
useful in identifying potential problem areas in an organization's sales
processes.
The example below shows how to create and customize a Funnel Chart:
You can use different chart types for each chart series by setting the
chartType property on individual series. This overrides the chart's
default chart type.
In the example below, the chart's chartType property is set to
Column, but the Downloads series overrides it to use the
LineAndSymbol chart type:
Use the legend's properties to customize the appearance of the chart
legend, and header, footer, and axis title properties
to add titles to your charts.
You can style the legend and titles using CSS. The CSS tab below shows the rules
used to customize the appearance of the legend and titles. Notice that these are
SVG elements, so you have to use CSS attributes such as "fill" instead of "color."
The FlexChart has built-in support for tooltips. By default, the control
displays tooltips when the user touches or hovers the mouse on a data point.
The tooltip content is generated using a template, which may contain the following
parameters:
seriesName: The name of the series that contains the chart element.
pointIndex: The index of the chart element within the series.
x: The x value of the chart element.
y: The y value of the chart element.
By default, the tooltip template is set to
<b>{seriesName}</b><br/>{x} {y}.
You can see how that works in the previous examples.
In this example, we set the tooltip template to
<b>{seriesName}</b> <img src='resources/{x}.png'/><br/>{y},
which replaces the country name with the country's flag.
You can disable the chart tooltips by setting the template to an empty string.
The FlexChart automatically picks colors for each series based on a default
palette, which you can override by setting the palette property.
But you can also override the default settings by setting the style
property of any series to an object that specifies SVG styling attributes,
including fill, stroke, strokeThickness, and so on.
The Series.style property is an exception to the general rule that
all styling in Wijmo is done through CSS. The exception reflects the fact
that many charts have dynamic series, which would be impossible to style
in advance. For example, a stock chart may show series selected by the
user while running the application.
The chart in this example uses the style and symbolStyle
properties to select style attributes for each series:
Use axis properties to customize the chart's axes, including ranges
(minimum and maximum), label format, tickmark spacing, and gridlines.
The Axis class has boolean properties that allow you to turn features
on or off (axisLine, labels, majorTickMarks, and
majorGrid).
You can style the appearance of the features that are turned on using CSS.
The appearance of the FlexChart is defined in CSS.
In addition to the default theme, we include about a dozen professionally
designed themes that customize the appearance of all Wijmo controls to
achieve a consistent attractive look.
To customize the appearance of the chart, inspect the elements you want to
style and then create some CSS rules that apply to those elements.
For example, if you right-click one of the labels on the X axis in IE or
Chrome, you will see that it is an element with the "wj-label" class, that
is contained in an element with the "wj-axis-x" class, which is contained
in the the top-level control element that has the "wj-flexchart" class.
The first CSS rule in this example uses this information to customize the
X labels. The rule selector adds the additional requirement that the parent
element must have, the "wj-flexchart" and the "custom-flex-chart"
classes. Without this, the rule would apply to all the charts on the page.
The FlexChart allows you to select series or data points by clicking
or touching them.
Use the selectionMode property to specify whether you want to
allow selection by series, by data point, or no selection at all
(selection is disabled by default.)
Setting the selectionMode property to Series or Point
causes the FlexChart to update the Selection property when the user
clicks the mouse, and to apply "wj-state-selected" class to the
selected chart elements.
The Selection property returns the currently selected series.
To get the currently selected data point, get the currently selected item
within the selected series using the Series.collectionView.currentItem
property as shown in the example.
var smChart = new wijmo.chart.FlexChart('#chartSelectionMode', {
itemsSource: appData,
bindingX: 'country',
selectionMode: 'Series',
series: [
{ name: 'Sales', binding: 'sales' },
{ name: 'Expenses', binding: 'expenses' },
{ name: 'Downloads', binding: 'downloads' }
],
selectionChanged: function (s, e) {
showChartSelection();
}
});
// chart type
var typeMenu = new wijmo.input.Menu('#chartTypeMenu', {
itemClicked: function (s, e) {
smChart.chartType = parseInt(s.selectedValue);
updateMenuHeader(s, 'Chart Type');
}
});
updateMenuHeader(typeMenu, 'Chart Type');
// selection mode
var selectionModeMenu = new wijmo.input.Menu('#seletionModeMenu', {
itemClicked: function (s, e) {
smChart.selectionMode = parseInt(s.selectedValue);
showChartSelection();
updateMenuHeader(s, 'Selection Mode');
}
});
updateMenuHeader(selectionModeMenu, 'Selection Mode');
// update selection pane when selection or selection mode change
function showChartSelection() {
var seriesContainer = document.getElementById('seriesContainer'),
series = smChart.selectionMode ? smChart.selection : null
if (series) {
// show selected series
seriesContainer.style.display = '';
setText('seriesName', series.name);
var item = series.collectionView.currentItem,
detailContainer = document.getElementById('detailContainer');
if (item && smChart.selectionMode == wijmo.chart.SelectionMode.Point) {
// show selected point
detailContainer.style.display = '';
setText('seriesCountry', item.country);
setText('seriesSales', item.sales, 'c2');
setText('seriesExpenses', item.expenses, 'c2');
setText('seriesDownloads', item.downloads, 'n0');
} else {
detailContainer.style.display = 'none';
}
} else {
seriesContainer.style.display = 'none';
}
}
Result (live):
Current Selection
Series:
Country
Sales
Expenses
Downloads
Toggle Series Visibility
The Series class has a visibility property that allows
you to determine whether a series should be shown in the chart and
in the legend, only in the legend, or completely hidden.
This sample shows how you can use the visibility property to
toggle the visibility of a series using two methods:
Clicking on legend entries:
The chart sets the chart's option.legendToggle property to true,
which toggles the visibility property of a series when its legend entry is
clicked.
Using checkboxes:
When the checked state changed, it will set the visibility property of each series by the checked state.
var svChart = new wijmo.chart.FlexChart('#chartLegendToggle', {
// initialize chart
itemsSource: appData,
bindingX: 'country',
legendToggle: true,
series: [
{ name: 'Sales', binding: 'sales' },
{ name: 'Expenses', binding: 'expenses' },
{ name: 'Downloads', binding: 'downloads' }
],
// update checkboxes when series visibility changes
seriesVisibilityChanged: function (s, e) {
s.series.forEach(function (series) {
var seriesName = series.name,
checked = series.visibility == wijmo.chart.SeriesVisibility.Visible;
document.getElementById('cb' + seriesName).checked = checked;
});
}
});
// update series visibility when checkboxes are clicked
svChart.series.forEach(function (series, index) {
var el = document.getElementById('cb' + series.name);
el.checked = series.visibility == wijmo.chart.SeriesVisibility.Visible;
el.addEventListener('click', function (e) {
series.visibility = e.target.checked
? wijmo.chart.SeriesVisibility.Visible
: wijmo.chart.SeriesVisibility.Legend;
});
});
Result (live):
Gradient Colors
The FlexChart supports gradient colors.
The gradient descriptor is an expression formatted as
follows: <type>(<coords>)<colors>[:<offset>[:<opacity>]][-<colors>[:<offset>[:<opacity>]]]-<colors>[:<offset>[:<opacity>]].
The <type> can be either linear or radial.
The uppercase L or R letters indicate absolute coordinates offset from the SVG surface.
Lowercase l or r letters indicate coordinates calculated relative to the element to which the gradient is applied.
Coordinates specify a linear gradient vector as x1, y1, x2, y2,
or a radial gradient as cx, cy, r and optional fx, fy, fr
specifying a focal point away from the center of the circle.
Specify <colors> as a list of dash-separated CSS color values.
Each color may be followed by a custom offset and opacity value, separated with a colon character.
var gradChart = new wijmo.chart.FlexChart('#chartGradientColors', {
itemsSource: appData,
bindingX: 'country',
series: [
{ binding: 'sales' }
]
});
// chart type
var gradientChartType = new wijmo.input.Menu('#gradientChartType', {
itemClicked: function (s, e) {
gradChart.chartType = parseInt(gradientChartType.selectedValue);
updateMenuHeader(s, 'Chart Type');
}
});
updateMenuHeader(gradientChartType, 'Chart Type');
// custom gradient
var startColor = new wijmo.input.InputColor('#gradientStartColor', {
valueChanged: function(s, e) {
applyGradientColor();
},
value: '#ff0000'
});
var endColor = new wijmo.input.InputColor('#gradientEndColor', {
valueChanged: function(s, e) {
applyGradientColor();
},
value: '#0000ff'
});
var startOffset = new wijmo.input.InputNumber('#gradientStartOffset', {
min: 0,
max: 1,
step: .1,
valueChanged: function(s, e) {
if (s.value >= s.min && s.value <= s.max) {
applyGradientColor();
}
},
value: 0
});
var endOffset = new wijmo.input.InputNumber('#gradientEndOffset', {
min: 0,
max: 1,
step: .1,
valueChanged: function(s, e) {
if (s.value >= s.min && s.value <= s.max) {
applyGradientColor();
}
},
value: 1
});
var startOpacity = new wijmo.input.InputNumber('#gradientStartOpacity', {
min: 0,
max: 1,
step: .1,
valueChanged: function(s, e) {
if (s.value >= s.min && s.value <= s.max) {
applyGradientColor();
}
},
value: 1
});
var endOpacity = new wijmo.input.InputNumber('#gradientEndOpacity', {
min: 0,
max: 1,
step: .1,
valueChanged: function(s, e) {
if (s.value >= s.min && s.value <= s.max) {
applyGradientColor();
}
},
value: 1
});
// gradient type and direction
var type = new wijmo.input.Menu('#gradientTypeMenu', {
itemClicked: function(s, e) {
applyGradientColor();
updateMenuHeader(type, 'Gradient Type');
}
});
updateMenuHeader(type, 'Gradient Type');
var direction = new wijmo.input.Menu('#gradientDirectionMenu', {
itemClicked: function(s, e) {
applyGradientColor();
updateMenuHeader(direction, 'Direction');
}
});
updateMenuHeader(direction, 'Direction');
// apply the current gradient color
function applyGradientColor() {
if (type && direction) {
var t = type.selectedValue,
d = direction.selectedValue,
color = t,
dtDirection = document.getElementById('dtGradientDirection'),
ddDirection = document.getElementById('ddGradientDirection');
if (t === 'l') {
dtDirection.style.display = 'block';
ddDirection.style.display = 'block';
color += d == 'horizontal'
? '(0, 0, 1, 0)'
: '(0, 0, 0, 1)';
} else {
dtDirection.style.display = 'none';
ddDirection.style.display = 'none';
color += '(0.5, 0.5, 0.5)'
}
color += startColor.value;
if (startOffset.value != 0 || startOpacity.value != 1) {
color += ':' + startOffset.value;
}
if (startOpacity.value != 1) {
color += ':' + startOpacity.value;
}
color += '-' + endColor.value;
if (endOffset.value != 1 || endOpacity.value != 1) {
color += ':' + endOffset.value;
}
if (endOpacity.value != 1) {
color += ':' + endOpacity.value;
}
setText('gradientColorsLabel', color);
gradChart.series[0].style = {
fill: color
};
gradChart.refresh(true);
}
}
applyGradientColor();
Result (live):
Generated fill string:
Start Color:
Start Offset:
Start Opacity:
End Color:
End Offset:
End Opacity:
Dynamic Charts
The FlexChart uses an ICollectionView internally, so any changes
you make to the data source are automatically reflected in the chart.
In this sample, we use a timer to add items to the data source, discarding
old items to keep the total count at 200. The result is a dynamic chart that
scrolls as new data arrives.