import 'bootstrap.css';
import '@mescius/wijmo.styles/wijmo.css';
import './styles.css';
//
import '@mescius/wijmo.touch';
import * as wjcCore from '@mescius/wijmo';
import * as wjcGrid from '@mescius/wijmo.grid';
import * as wjcGridFilter from '@mescius/wijmo.grid.filter';
import * as wjcGridSearch from '@mescius/wijmo.grid.search';
import * as wjcGridGroupPanel from '@mescius/wijmo.grid.grouppanel';
import * as wjcInput from '@mescius/wijmo.input';
import { CellMaker, SparklineMarkers } from '@mescius/wijmo.grid.cellmaker';
import { KeyValue, Country, DataService } from './data';
import { ExportService } from './export';
//
class App {
constructor(dataSvc, exportSvc) {
this._itemsCount = 500;
this._lastId = this._itemsCount;
this._dataSvc = dataSvc;
this._exportSvc = exportSvc;
// initializes data maps
this._productMap = this._buildDataMap(this._dataSvc.getProducts());
this._countryMap = new wjcGrid.DataMap(this._dataSvc.getCountries(), 'id', 'name');
this._colorMap = this._buildDataMap(this._dataSvc.getColors());
// initializes cell templates
this._historyCellTemplate = CellMaker.makeSparkline({
markers: SparklineMarkers.High | SparklineMarkers.Low,
maxPoints: 25,
label: 'price history',
});
this._ratingCellTemplate = CellMaker.makeRating({
range: [1, 5],
label: 'rating'
});
// initializes data size
document.getElementById('itemsCount').addEventListener('change', (e) => {
const value = e.target.value;
this._itemsCount = wjcCore.changeType(value, wjcCore.DataType.Number);
this._handleItemsCountChange();
});
// initializes export
const btnExportToExcel = document.getElementById('btnExportToExcel');
this._excelExportContext = new ExcelExportContext(btnExportToExcel);
btnExportToExcel.addEventListener('click', () => {
this._exportToExcel();
});
document.getElementById('btnExportToPdf').addEventListener('click', () => {
this._exportToPdf();
});
// initializes the grid
this._initializeGrid();
// initializes items source
this._itemsSource = this._createItemsSource();
this._theGrid.itemsSource = this._itemsSource;
}
close() {
const ctx = this._excelExportContext;
this._exportSvc.cancelExcelExport(ctx);
}
_initializeGrid() {
// creates the grid
this._theGrid = new wjcGrid.FlexGrid('#theGrid', {
autoGenerateColumns: false,
allowAddNew: true,
allowDelete: true,
allowPinning: wjcGrid.AllowPinning.SingleColumn,
newRowAtTop: true,
showMarquee: true,
selectionMode: wjcGrid.SelectionMode.MultiRange,
validateEdits: false,
columns: [
{ binding: 'id', header: 'ID', width: 70, isReadOnly: true },
{
binding: 'date', header: 'Date', format: 'MMM d yyyy', isRequired: false, width: 130,
editor: new wjcInput.InputDate(document.createElement('div'), {
format: 'MM/dd/yyyy',
isRequired: false
})
},
{
binding: 'countryId', header: 'Country', dataMap: this._countryMap, width: 145,
cellTemplate: (ctx) => {
const dataItem = ctx.row.dataItem;
if (wjcCore.isUndefined(dataItem) || dataItem === null) {
return '';
}
const country = this._getCountry(ctx.item);
return `<span class="flag-icon flag-icon-${country.flag}"></span> ${country.name}`;
}
},
{ binding: 'price', header: 'Price', format: 'c', isRequired: false, width: 100 },
{
binding: 'history', header: 'History', width: 180, align: 'center', allowSorting: false,
cellTemplate: this._historyCellTemplate
},
{
binding: 'change', header: 'Change', align: 'right', width: 115,
cellTemplate: (ctx) => {
const dataItem = ctx.row.dataItem;
if (wjcCore.isUndefined(dataItem) || dataItem === null) {
return '';
}
const cls = this._getChangeCls(ctx.value);
const value = this._formatChange(ctx.value);
return `<span class="${cls}">${value}</span>`;
}
},
{
binding: 'rating', header: 'Rating', width: 180, align: 'center', cssClass: 'cell-rating',
cellTemplate: this._ratingCellTemplate
},
{
binding: 'time', header: 'Time', format: 'HH:mm', isRequired: false, width: 95,
editor: new wjcInput.InputTime(document.createElement('div'), {
format: 'HH:mm',
isRequired: false
})
},
{
binding: 'colorId', header: 'Color', dataMap: this._colorMap, width: 145,
cellTemplate: (ctx) => {
const dataItem = ctx.row.dataItem;
if (wjcCore.isUndefined(dataItem) || dataItem === null) {
return '';
}
const color = this._getColor(ctx.item);
return `<span class="color-tile" style="background: ${color.value}"></span> ${color.value}`;
}
},
{ binding: 'productId', header: 'Product', dataMap: this._productMap, width: 145 },
{ binding: 'discount', header: 'Discount', format: 'p0', width: 130 },
{ binding: 'active', header: 'Active', width: 100 }
]
});
// create the grid search box
new wjcGridSearch.FlexGridSearch('#theSearch', {
placeholder: 'Search',
grid: this._theGrid,
cssMatch: ''
});
// adds Excel-like filter
new wjcGridFilter.FlexGridFilter(this._theGrid, {
filterColumns: [
'id', 'date', 'time', 'countryId', 'productId',
'colorId', 'price', 'change', 'discount', 'rating', 'active'
]
});
// adds group panel
new wjcGridGroupPanel.GroupPanel('#theGroupPanel', {
placeholder: 'Drag columns here to create groups',
grid: this._theGrid
});
}
_getCountry(item) {
const country = this._countryMap.getDataItem(item.countryId);
return country ? country : Country.NotFound;
}
_getColor(item) {
const color = this._colorMap.getDataItem(item.colorId);
return color ? color : KeyValue.NotFound;
}
_getChangeCls(value) {
if (wjcCore.isNumber(value)) {
if (value > 0) {
return 'change-up';
}
if (value < 0) {
return 'change-down';
}
}
return '';
}
_formatChange(value) {
if (wjcCore.isNumber(value)) {
return wjcCore.Globalize.formatNumber(value, 'c');
}
if (!wjcCore.isUndefined(value) && value !== null) {
return wjcCore.changeType(value, wjcCore.DataType.String);
}
return '';
}
_exportToExcel() {
const ctx = this._excelExportContext;
if (!ctx.exporting) {
this._exportSvc.startExcelExport(this._theGrid, ctx);
}
else {
this._exportSvc.cancelExcelExport(ctx);
}
}
_exportToPdf() {
this._exportSvc.exportToPdf(this._theGrid, {
countryMap: this._countryMap,
colorMap: this._colorMap,
historyCellTemplate: this._historyCellTemplate
});
}
_createItemsSource() {
const data = this._dataSvc.getData(this._itemsCount);
const view = new wjcCore.CollectionView(data, {
getError: (item, prop) => {
const displayName = this._theGrid.columns.getColumn(prop).header;
return this._dataSvc.validate(item, prop, displayName);
}
});
view.collectionChanged.addHandler((s, e) => {
// initializes new added item with a history data
if (e.action === wjcCore.NotifyCollectionChangedAction.Add) {
e.item.history = this._dataSvc.getHistoryData();
e.item.id = this._lastId;
this._lastId++;
}
});
return view;
}
_disposeItemsSource(itemsSource) {
if (itemsSource) {
itemsSource.collectionChanged.removeAllHandlers();
}
}
// build a data map from a string array using the indices as keys
_buildDataMap(items) {
const map = [];
for (let i = 0; i < items.length; i++) {
map.push({ key: i, value: items[i] });
}
return new wjcGrid.DataMap(map, 'key', 'value');
}
_handleItemsCountChange() {
this._disposeItemsSource(this._itemsSource);
this._lastId = this._itemsCount;
this._itemsSource = this._createItemsSource();
this._theGrid.itemsSource = this._itemsSource;
}
}
//
class ExcelExportContext {
constructor(btn) {
this._exporting = false;
this._progress = 0;
this._preparing = false;
this._btn = btn;
}
get exporting() {
return this._exporting;
}
set exporting(value) {
if (value !== this._exporting) {
this._exporting = value;
this._onPropertyChanged();
}
}
get progress() {
return this._progress;
}
set progress(value) {
if (value !== this._progress) {
this._progress = value;
this._onPropertyChanged();
}
}
get preparing() {
return this._preparing;
}
set preparing(value) {
if (value !== this._preparing) {
this._preparing = value;
this._onPropertyChanged();
}
}
_onPropertyChanged() {
wjcCore.enable(this._btn, !this._preparing);
if (this._exporting) {
const percent = wjcCore.Globalize.formatNumber(this._progress, 'p0');
this._btn.textContent = `Cancel (${percent} done)`;
}
else {
this._btn.textContent = 'Export To Excel';
}
}
}
//
document.readyState === 'complete' ? init() : window.onload = init;
//
function init() {
const dataSvc = new DataService();
const exportSvc = new ExportService();
const app = new App(dataSvc, exportSvc);
window.addEventListener('unload', () => {
app.close();
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>MESCIUS Wijmo FlexGrid Overview</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- SystemJS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.21.5/system.src.js" integrity="sha512-skZbMyvYdNoZfLmiGn5ii6KmklM82rYX2uWctBhzaXPxJgiv4XBwJnFGr5k8s+6tE1pcR1nuTKghozJHyzMcoA==" crossorigin="anonymous"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('./src/app');
</script>
</head>
<body>
<div class="container-fluid">
<!-- filter/navigation -->
<div class="row">
<!-- search box -->
<div class="toolbar-item col-sm-3 col-md-5">
<div id="theSearch"></div>
</div>
<!-- data size -->
<div class="toolbar-item col-sm-3 col-md-3">
<div class="input-group">
<span class="input-group-addon">Items:</span>
<select id="itemsCount" class="form-control">
<option value="5">5</option>
<option value="50">50</option>
<option value="500" selected>500</option>
<option value="5000">5,000</option>
<option value="50000">50,000</option>
<option value="100000">100,000</option>
</select>
</div>
</div>
<!-- export to Excel -->
<div class="toolbar-item col-sm-3 col-md-2">
<button id="btnExportToExcel" class="btn btn-default btn-block">Export To Excel</button>
</div>
<!-- export to PDF -->
<div class="toolbar-item col-sm-3 col-md-2">
<button id="btnExportToPdf" class="btn btn-default btn-block">Export To PDF</button>
</div>
</div>
<!-- the grid -->
<div id="theGroupPanel"></div>
<div id="theGrid"></div>
</div>
</body>
</html>
import * as wjcCore from '@mescius/wijmo';
import { RequiredValidator, MinNumberValidator, MinDateValidator, MaxNumberValidator, MaxDateValidator } from './validation';
//
export class KeyValue {
}
KeyValue.NotFound = { key: -1, value: '' };
//
export class Country {
}
Country.NotFound = { id: -1, name: '', flag: '' };
//
export class DataService {
constructor() {
this._products = ['Widget', 'Gadget', 'Doohickey'];
this._colors = ['Black', 'White', 'Red', 'Green', 'Blue'];
this._countries = [
{ id: 0, name: 'US', flag: 'us' },
{ id: 1, name: 'Germany', flag: 'de' },
{ id: 2, name: 'UK', flag: 'gb' },
{ id: 3, name: 'Japan', flag: 'jp' },
{ id: 4, name: 'Italy', flag: 'it' },
{ id: 5, name: 'Greece', flag: 'gr' }
];
this._validationConfig = {
'date': [
new RequiredValidator(),
new MinDateValidator(new Date('2000-01-01T00:00:00')),
new MaxDateValidator(new Date('2100-01-01T00:00:00'))
],
'time': [
new RequiredValidator(),
new MinDateValidator(new Date('2000-01-01T00:00:00')),
new MaxDateValidator(new Date('2100-01-01T00:00:00'))
],
'productId': [
new RequiredValidator(),
new MinNumberValidator(0, `{0} can't be less than {1} (${this._products[0]})`),
new MaxNumberValidator(this._products.length - 1, `{0} can't be greater than {1} (${this._products[this._products.length - 1]})`)
],
'countryId': [
new RequiredValidator(),
new MinNumberValidator(0, `{0} can't be less than {1} (${this._countries[0].name})`),
new MaxNumberValidator(this._countries.length - 1, `{0} can't be greater than {1} (${this._countries[this._countries.length - 1].name})`)
],
'colorId': [
new RequiredValidator(),
new MinNumberValidator(0, `{0} can't be less than {1} (${this._colors[0]})`),
new MaxNumberValidator(this._colors.length - 1, `{0} can't be greater than {1} (${this._colors[this._colors.length - 1]})`)
],
'price': [
new RequiredValidator(),
new MinNumberValidator(0, `Price can't be a negative value`)
]
};
}
getCountries() {
return this._countries;
}
getProducts() {
return this._products;
}
getColors() {
return this._colors;
}
getHistoryData() {
return this._getRandomArray(25, 100);
}
getData(count) {
const data = [];
const dt = new Date();
const year = dt.getFullYear();
const itemsCount = Math.max(count, 5);
// add items
for (let i = 0; i < itemsCount; i++) {
const item = this._getItem(i, year);
data.push(item);
}
// set invalid data to demonstrate errors visualization
data[1].price = -2000;
data[2].date = new Date('1970-01-01T00:00:00');
data[4].time = undefined;
data[4].price = -1000;
return data;
}
validate(item, prop, displayName) {
const validators = this._validationConfig[prop];
if (wjcCore.isUndefined(validators)) {
return '';
}
const value = item[prop];
for (let i = 0; i < validators.length; i++) {
const validationError = validators[i].validate(displayName, value);
if (!wjcCore.isNullOrWhiteSpace(validationError)) {
return validationError;
}
}
}
_getItem(i, year) {
const date = new Date(year, i % 12, 25, i % 24, i % 60, i % 60);
const countryIndex = this._getRandomIndex(this._countries);
const productIndex = this._getRandomIndex(this._products);
const colorIndex = this._getRandomIndex(this._colors);
const item = {
id: i,
date: date,
time: new Date(date.getTime() + Math.random() * 30 * (24 * 60 * 60 * 1000)),
countryId: this._countries[countryIndex].id,
productId: productIndex,
colorId: colorIndex,
price: wjcCore.toFixed(Math.random() * 10000 + 5000, 2, true),
change: wjcCore.toFixed(Math.random() * 1000 - 500, 2, true),
history: this.getHistoryData(),
discount: wjcCore.toFixed(Math.random() / 4, 2, true),
rating: this._getRating(),
active: i % 4 == 0,
size: Math.floor(100 + Math.random() * 900),
weight: Math.floor(100 + Math.random() * 900),
quantity: Math.floor(Math.random() * 10),
description: "Across all our software products and services, our focus is on helping our customers achieve their goals. Our key principles – thoroughly understanding our customers' business objectives, maintaining a strong emphasis on quality, and adhering to the highest ethical standards – serve as the foundation for everything we do."
};
return item;
}
_getRating() {
return Math.ceil(Math.random() * 5);
}
_getRandomIndex(arr) {
return Math.floor(Math.random() * arr.length);
}
_getRandomArray(len, maxValue) {
const arr = [];
for (let i = 0; i < len; i++) {
arr.push(Math.floor(Math.random() * maxValue));
}
return arr;
}
}
@import 'https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/3.1.0/css/flag-icon.css';
body {
font-size: 1.5em;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Light", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
}
.toolbar-item {
margin-bottom: 6px;
}
.wj-flexgridsearch {
width: 100%;
}
.wj-flexgrid {
height: 330px;
}
.wj-flexgrid .wj-cell {
padding: 7px;
border: none;
}
.wj-cell.wj-state-invalid:not(.wj-header)::after {
top: -14px;
border: 14px solid transparent;
border-right-color: red;
}
.flag-icon {
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4);
}
.color-tile {
display: inline-block;
position: relative;
width: 1em;
height: 1em;
border-radius: 50%;
box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.4);
vertical-align: middle;
}
.change-up {
color: darkgreen;
}
.change-up:after {
content: '\25b2';
margin-left: 0.5em;
}
.change-down {
color: darkred;
}
.change-down:after {
content: '\25bc';
margin-left: 0.5em;
}
.cell-rating {
font-size: 12px;
}
.wj-flexgrid .wj-detail {
padding: 4px 16px;
}
.wj-detail h3 {
margin: 10px 0;
}
import * as wjcCore from '@mescius/wijmo';
import * as wjcGrid from '@mescius/wijmo.grid';
import * as wjcGridPdf from '@mescius/wijmo.grid.pdf';
import * as wjcGridXlsx from '@mescius/wijmo.grid.xlsx';
import * as wjcPdf from '@mescius/wijmo.pdf';
import * as wjcXlsx from '@mescius/wijmo.xlsx';
import { KeyValue, Country } from './data';
//
const ExcelExportDocName = 'FlexGrid.xlsx';
const PdfExportDocName = 'FlexGrid.pdf';
const FakeColumn = new wjcGrid.Column();
const FakeRow = new wjcGrid.Row();
//
class Fonts {
}
Fonts.ZapfDingbatsSm = new wjcPdf.PdfFont('zapfdingbats', 8, 'normal', 'normal');
Fonts.ZapfDingbatsLg = new wjcPdf.PdfFont('zapfdingbats', 16, 'normal', 'normal');
//
export class IExcelExportContext {
}
//
export class ExportService {
startExcelExport(flex, ctx) {
if (ctx.preparing || ctx.exporting) {
return;
}
ctx.exporting = false;
ctx.progress = 0;
ctx.preparing = true;
wjcGridXlsx.FlexGridXlsxConverter.saveAsync(flex, {
includeColumnHeaders: true,
includeStyles: false,
formatItem: this._formatExcelItem.bind(this)
}, ExcelExportDocName, () => {
console.log('Export to Excel completed');
this._resetExcelContext(ctx);
}, err => {
console.error(`Export to Excel failed: ${err}`);
this._resetExcelContext(ctx);
}, prg => {
if (ctx.preparing) {
ctx.exporting = true;
ctx.preparing = false;
}
ctx.progress = prg / 100.;
}, true);
console.log('Export to Excel started');
}
cancelExcelExport(ctx) {
wjcGridXlsx.FlexGridXlsxConverter.cancelAsync(() => {
console.log('Export to Excel canceled');
this._resetExcelContext(ctx);
});
}
exportToPdf(flex, options) {
wjcGridPdf.FlexGridPdfConverter.export(flex, PdfExportDocName, {
maxPages: 100,
exportMode: wjcGridPdf.ExportMode.All,
scaleMode: wjcGridPdf.ScaleMode.ActualSize,
documentOptions: {
pageSettings: {
layout: wjcPdf.PdfPageOrientation.Landscape
},
header: {
declarative: {
text: '\t&[Page]\\&[Pages]'
}
},
footer: {
declarative: {
text: '\t&[Page]\\&[Pages]'
}
}
},
styles: {
cellStyle: {
backgroundColor: '#ffffff',
borderColor: '#c6c6c6'
},
altCellStyle: {
backgroundColor: '#f9f9f9'
},
groupCellStyle: {
backgroundColor: '#dddddd'
},
headerCellStyle: {
backgroundColor: '#eaeaea'
},
// Highlight Invalid Cells
errorCellStyle: {
backgroundColor: 'rgba(255, 0, 0, 0.3)'
}
},
customCellContent: false,
formatItem: (e) => this._formatPdfItem(e, options)
});
}
_formatExcelItem(e) {
const panel = e.panel;
if (panel.cellType !== wjcGrid.CellType.Cell) {
return;
}
// highlight invalid cells
if (panel.grid._getError(panel, e.row, e.col)) {
const fill = new wjcXlsx.WorkbookFill();
fill.color = '#ff0000';
e.xlsxCell.style.fill = fill;
}
}
_resetExcelContext(ctx) {
ctx.exporting = false;
ctx.progress = 0;
ctx.preparing = false;
}
_formatPdfItem(e, options) {
const panel = e.panel;
if (panel.cellType !== wjcGrid.CellType.Cell) {
return;
}
switch (panel.columns[e.col].binding) {
case 'countryId':
this._formatPdfCountryCell(e, options.countryMap);
break;
case 'colorId':
this._formatPdfColorCell(e, options.colorMap);
break;
case 'change':
this._formatPdfChangeCell(e);
break;
case 'history':
/*** Version #1: get grid cell produced before by a cell template ***/
// const cell = e.getFormattedCell();
// this._formatPdfHistoryCell(e, cell);
/*** Version #2: create fake cell from a cell template ***/
const history = e.panel.getCellData(e.row, e.col, false);
const cell = this._createCellFromCellTemplate(options.historyCellTemplate, history);
this._formatPdfHistoryCell(e, cell);
break;
case 'rating':
this._formatPdfRatingCell(e);
break;
}
}
_formatPdfCountryCell(e, countryMap) {
e.drawBackground(e.style.backgroundColor);
// check whether country exists
const countryName = e.data;
if (this._isCountryExist(countryName, countryMap)) {
// bound rectangle of cell's content area
const contentRect = e.contentRect;
// draw flag image
const image = e.canvas.openImage(`resources/${countryName}.png`);
const imageTop = contentRect.top + (contentRect.height - image.height) / 2;
e.canvas.drawImage(image, contentRect.left, imageTop);
// draw country name
e.canvas.drawText(countryName, contentRect.left + image.width + 3, e.textTop);
}
// cancel standard cell content drawing
e.cancel = true;
}
_formatPdfColorCell(e, colorMap) {
e.drawBackground(e.style.backgroundColor);
// check whether color exists
const colorName = e.data;
if (this._isColorExist(colorName, colorMap)) {
// bound rectangle of cell's content area
const contentRect = e.contentRect;
// draw color indicator
const imageHeight = Math.min(10, contentRect.height);
const imageWidth = 1.33 * imageHeight;
const imageTop = contentRect.top + (contentRect.height - imageHeight) / 2;
e.canvas.paths
.rect(contentRect.left, imageTop, imageWidth, imageHeight)
.fillAndStroke(wjcCore.Color.fromString(colorName), wjcCore.Color.fromString('gray'));
// draw color name
e.canvas.drawText(colorName, contentRect.left + imageWidth + 3, e.textTop);
}
// cancel standard cell content drawing
e.cancel = true;
}
_formatPdfChangeCell(e) {
e.drawBackground(e.style.backgroundColor);
// get change value and text
const cellData = e.panel.getCellData(e.row, e.col, false);
let change = 0;
let changeText = '';
if (wjcCore.isNumber(cellData)) {
change = cellData;
changeText = wjcCore.Globalize.formatNumber(change, 'c');
}
else if (!wjcCore.isUndefined(cellData) && cellData !== null) {
changeText = wjcCore.changeType(cellData, wjcCore.DataType.String);
}
// determine whether change is positive or negative
let changeIndicator = '';
let changeColor = e.style.color;
if (change > 0) {
changeIndicator = '\x73'; // ▲
changeColor = 'darkgreen';
}
else if (change < 0) {
changeIndicator = '\x74'; // ▼
changeColor = 'darkred';
}
// draw change indicator
let indent = 10;
e.canvas.drawText(changeIndicator, e.contentRect.right - indent, e.contentRect.top + indent, {
brush: changeColor,
font: Fonts.ZapfDingbatsSm
});
// draw change text
indent += 3;
e.canvas.drawText(changeText, e.contentRect.left, e.textTop, {
brush: changeColor,
align: wjcPdf.PdfTextHorizontalAlign.Right,
width: e.contentRect.width - indent
});
// cancel standard cell content drawing
e.cancel = true;
}
_formatPdfHistoryCell(e, cell) {
e.drawBackground(e.style.backgroundColor);
// draw history svg
const svgUrl = this._getHistorySvgDataUrlFromCell(cell, e.clientRect.width, e.clientRect.height);
if (svgUrl) {
let cr = e.contentRect;
e.canvas.drawSvg(svgUrl, cr.left + 2, cr.top + 2, { width: cr.width - 4, height: cr.height - 4 });
}
// cancel standard cell content drawing
e.cancel = true;
}
_getHistorySvgDataUrlFromCell(cell, width, height) {
let dataUrl = null;
// extract SVG from provided cell
const svg = cell.getElementsByTagName('svg')[0];
if (svg) {
const clone = svg.cloneNode(true);
clone.setAttribute('version', '1.1');
clone.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns', 'http://www.w3.org/2000/svg');
clone.style.overflow = 'visible';
clone.style.stroke = '#376092';
clone.style.fill = '#376092';
const s = document.createElement('style');
s.setAttribute('type', 'text/css');
s.innerHTML = `<![CDATA[
line {
stroke-width: 2;
}
circle {
stroke-width: 0;
stroke-opacity: 0;
}
.wj-marker {
fill: #d00000;
opacity: 1;
}
]]>`;
const defs = document.createElement('defs');
defs.appendChild(s);
clone.insertBefore(defs, clone.firstChild);
const outer = document.createElement('div');
outer.appendChild(clone);
dataUrl = 'data:image/svg+xml;base64,' + btoa(unescape(encodeURIComponent(outer.innerHTML)));
}
return dataUrl;
}
_formatPdfRatingCell(e) {
e.drawBackground(e.style.backgroundColor);
// check whether rating is defined
let rating = wjcCore.changeType(e.data, wjcCore.DataType.Number);
if (wjcCore.isInt(rating)) {
const ratingIndicator = '\x48'; // ★
const ratingNormalColor = wjcCore.Color.fromRgba(255, 165, 0, 1); // orange
const ratingLightColor = wjcCore.Color.fromRgba(255, 165, 0, 0.2);
// draw rating indicators
const indent = 16;
const count = 5;
const width = count * indent;
const y = e.clientRect.top + indent;
let x = e.contentRect.left + (e.contentRect.width - width) / 2;
rating = wjcCore.clamp(rating, 1, count);
for (let i = 0; i < count; i++) {
e.canvas.drawText(ratingIndicator, x, y, {
brush: (i < rating) ? ratingNormalColor : ratingLightColor,
font: Fonts.ZapfDingbatsLg,
height: e.clientRect.height
});
x += indent;
}
}
// cancel standard cell content drawing
e.cancel = true;
}
_isCountryExist(countryName, countryMap) {
const countryId = countryMap.getKeyValue(countryName);
if (wjcCore.isUndefined(countryId) || countryId === null) {
return false;
}
if (countryId === Country.NotFound.id) {
return false;
}
return true;
}
_isColorExist(colorName, colorMap) {
const colorId = colorMap.getKeyValue(colorName);
if (wjcCore.isUndefined(colorId) || colorId === null) {
return false;
}
if (colorId === KeyValue.NotFound.key) {
return false;
}
return true;
}
_createCellFromCellTemplate(cellTemplate, data) {
const cell = document.createElement('div');
cellTemplate({
col: FakeColumn,
row: FakeRow,
value: data,
item: null,
text: null
}, cell);
return cell;
}
}
import * as wjcCore from '@mescius/wijmo';
export class RequiredValidator {
validate(name, value) {
const message = name + ' is required';
if (wjcCore.isUndefined(value)) {
return message;
}
const str = wjcCore.changeType(value, wjcCore.DataType.String);
if (wjcCore.isNullOrWhiteSpace(str)) {
return message;
}
return '';
}
}
export class MinValueValidator {
constructor(minValue, message = '{0} can\'t be less than {1}', format = null) {
this.minValue = minValue;
this.message = message;
this.format = format;
}
validate(name, value) {
if (value < this.minValue) {
return wjcCore.format(this.message, {
0: name,
1: this._formatValue(this.minValue)
});
}
return '';
}
}
export class MaxValueValidator {
constructor(maxValue, message = '{0} can\'t be greater than {1}', format = null) {
this.maxValue = maxValue;
this.message = message;
this.format = format;
}
validate(name, value) {
if (value > this.maxValue) {
return wjcCore.format(this.message, {
0: name,
1: this._formatValue(this.maxValue)
});
}
return '';
}
}
export class MinNumberValidator extends MinValueValidator {
constructor(minValue, message = '{0} can\'t be less than {1}', format = 'n') {
super(minValue, message, format);
}
_formatValue(value) {
return wjcCore.Globalize.formatNumber(value, this.format);
}
}
export class MaxNumberValidator extends MaxValueValidator {
constructor(maxValue, message = '{0} can\'t be greater than {1}', format = 'n') {
super(maxValue, message, format);
}
_formatValue(value) {
return wjcCore.Globalize.formatNumber(value, this.format);
}
}
export class MinDateValidator extends MinValueValidator {
constructor(minValue, message = '{0} can\'t be less than {1}', format = 'MM/dd/yyyy') {
super(minValue, message, format);
}
_formatValue(value) {
return wjcCore.Globalize.formatDate(value, this.format);
}
}
export class MaxDateValidator extends MaxValueValidator {
constructor(maxValue, message = '{0} can\'t be greater than {1}', format = 'MM/dd/yyyy') {
super(maxValue, message, format);
}
_formatValue(value) {
return wjcCore.Globalize.formatDate(value, this.format);
}
}
(function (global) {
System.config({
transpiler: 'plugin-babel',
babelOptions: {
es2015: true
},
meta: {
'*.css': { loader: 'css' }
},
paths: {
// paths serve as alias
'npm:': 'node_modules/'
},
// map tells the System loader where to look for things
map: {
'jszip': 'npm:jszip/dist/jszip.js',
'@mescius/wijmo': 'npm:@mescius/wijmo/index.js',
'@mescius/wijmo.input': 'npm:@mescius/wijmo.input/index.js',
'@mescius/wijmo.styles': 'npm:@mescius/wijmo.styles',
'@mescius/wijmo.cultures': 'npm:@mescius/wijmo.cultures',
'@mescius/wijmo.chart': 'npm:@mescius/wijmo.chart/index.js',
'@mescius/wijmo.chart.analytics': 'npm:@mescius/wijmo.chart.analytics/index.js',
'@mescius/wijmo.chart.animation': 'npm:@mescius/wijmo.chart.animation/index.js',
'@mescius/wijmo.chart.annotation': 'npm:@mescius/wijmo.chart.annotation/index.js',
'@mescius/wijmo.chart.finance': 'npm:@mescius/wijmo.chart.finance/index.js',
'@mescius/wijmo.chart.finance.analytics': 'npm:@mescius/wijmo.chart.finance.analytics/index.js',
'@mescius/wijmo.chart.hierarchical': 'npm:@mescius/wijmo.chart.hierarchical/index.js',
'@mescius/wijmo.chart.interaction': 'npm:@mescius/wijmo.chart.interaction/index.js',
'@mescius/wijmo.chart.radar': 'npm:@mescius/wijmo.chart.radar/index.js',
'@mescius/wijmo.chart.render': 'npm:@mescius/wijmo.chart.render/index.js',
'@mescius/wijmo.chart.webgl': 'npm:@mescius/wijmo.chart.webgl/index.js',
'@mescius/wijmo.chart.map': 'npm:@mescius/wijmo.chart.map/index.js',
'@mescius/wijmo.gauge': 'npm:@mescius/wijmo.gauge/index.js',
'@mescius/wijmo.grid': 'npm:@mescius/wijmo.grid/index.js',
'@mescius/wijmo.grid.detail': 'npm:@mescius/wijmo.grid.detail/index.js',
'@mescius/wijmo.grid.filter': 'npm:@mescius/wijmo.grid.filter/index.js',
'@mescius/wijmo.grid.search': 'npm:@mescius/wijmo.grid.search/index.js',
'@mescius/wijmo.grid.style': 'npm:@mescius/wijmo.grid.style/index.js',
'@mescius/wijmo.grid.grouppanel': 'npm:@mescius/wijmo.grid.grouppanel/index.js',
'@mescius/wijmo.grid.multirow': 'npm:@mescius/wijmo.grid.multirow/index.js',
'@mescius/wijmo.grid.transposed': 'npm:@mescius/wijmo.grid.transposed/index.js',
'@mescius/wijmo.grid.transposedmultirow': 'npm:@mescius/wijmo.grid.transposedmultirow/index.js',
'@mescius/wijmo.grid.pdf': 'npm:@mescius/wijmo.grid.pdf/index.js',
'@mescius/wijmo.grid.sheet': 'npm:@mescius/wijmo.grid.sheet/index.js',
'@mescius/wijmo.grid.xlsx': 'npm:@mescius/wijmo.grid.xlsx/index.js',
'@mescius/wijmo.grid.selector': 'npm:@mescius/wijmo.grid.selector/index.js',
'@mescius/wijmo.grid.cellmaker': 'npm:@mescius/wijmo.grid.cellmaker/index.js',
'@mescius/wijmo.nav': 'npm:@mescius/wijmo.nav/index.js',
'@mescius/wijmo.odata': 'npm:@mescius/wijmo.odata/index.js',
'@mescius/wijmo.olap': 'npm:@mescius/wijmo.olap/index.js',
'@mescius/wijmo.rest': 'npm:@mescius/wijmo.rest/index.js',
'@mescius/wijmo.pdf': 'npm:@mescius/wijmo.pdf/index.js',
'@mescius/wijmo.pdf.security': 'npm:@mescius/wijmo.pdf.security/index.js',
'@mescius/wijmo.viewer': 'npm:@mescius/wijmo.viewer/index.js',
'@mescius/wijmo.xlsx': 'npm:@mescius/wijmo.xlsx/index.js',
'@mescius/wijmo.undo': 'npm:@mescius/wijmo.undo/index.js',
'@mescius/wijmo.interop.grid': 'npm:@mescius/wijmo.interop.grid/index.js',
'@mescius/wijmo.touch': 'npm:@mescius/wijmo.touch/index.js',
'@mescius/wijmo.cloud': 'npm:@mescius/wijmo.cloud/index.js',
'@mescius/wijmo.barcode': 'npm:@mescius/wijmo.barcode/index.js',
'@mescius/wijmo.barcode.common': 'npm:@mescius/wijmo.barcode.common/index.js',
'@mescius/wijmo.barcode.composite': 'npm:@mescius/wijmo.barcode.composite/index.js',
'@mescius/wijmo.barcode.specialized': 'npm:@mescius/wijmo.barcode.specialized/index.js',
'jszip': 'npm:jszip/dist/jszip.js',
'bootstrap.css': 'npm:bootstrap/dist/css/bootstrap.min.css',
'css': 'npm:systemjs-plugin-css/css.js',
'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js',
'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js'
},
// packages tells the System loader how to load when no filename and/or no extension
packages: {
src: {
defaultExtension: 'js'
},
"node_modules": {
defaultExtension: 'js'
},
}
});
})(this);