Sparkline Shape

Auto Shapes and Picture Shapes now support rendering sparklines, and sparklines can be moved, scaled, and rotated with shapes.

Auto shapes and picture shapes now support rendering sparklines. The following example shows how to add a sparkline in a picture shape. The following example shows how to add a sparkline in an auto shape.
<template> <div class="sample-tutorial"> <gc-spread-sheets class="sample-spreadsheets" @workbookInitialized="initSpread"> <gc-worksheet></gc-worksheet> </gc-spread-sheets> </div> </template> <script setup> import GC from "@mescius/spread-sheets"; import { ref } from "vue"; import "@mescius/spread-sheets-vue"; import '@mescius/spread-sheets-shapes'; const spreadRef = ref(null); const initSpread = (spread) => { spreadRef.value = spread; spread.addSparklineEx(new Clock()); var sheet = spread.getActiveSheet(); initGaugeSparklineSample(sheet); initColumnSparklineSample(sheet); initCustomSparklineSample(sheet); } function initGaugeSparklineSample(sheet) { sheet.setValue(12, 1, 10000); var shape = sheet.shapes.add('', GC.Spread.Sheets.Shapes.AutoShapeType.roundedRectangularCallout, 68, 30, 235, 200); var style = shape.style(); style.fill = { src: '' }; style.line.width = 2; style.line.color = 'rgb(0,0,0)'; shape.style(style); shape.adjustments([-0.317, 0.545, 0.16667]); shape.setFormula('style.fill.src', '=GAUGEKPISPARKLINE(28000,Sheet1!B13,0,50000,TRUE,TEXT(28000,"$0,K"),TEXT(Sheet1!B13,"$0,K"),TEXT(0,"$0,K"),TEXT(50000,"$0,K"),,-90,90,0.5,0,{0,10000,"#F7A711"},{10000,25000,"#BBBBBB"},{25000,50000,"#82BC00"})'); var spinButton = addSpinButton(sheet, 260, 62, 38, 58, '=Sheet1!B13', 0, 50000, 1000, 10000); sheet.shapes.group([shape, spinButton]); } function initColumnSparklineSample(sheet) { sheet.getRange(12, 6, 1, 5).hAlign(1); var shape = sheet.shapes.addPictureShape('', '', 378, 30, 296, 205); var spin1 = addSpinButton(sheet, 396, 188, 28, 38, '=Sheet1!G13', 0, 10, 1, 5); var spin2 = addSpinButton(sheet, 454, 188, 28, 38, '=Sheet1!H13', 0, 10, 1, 3); var spin3 = addSpinButton(sheet, 512, 188, 28, 38, '=Sheet1!I13', 0, 10, 1, 2); var spin4 = addSpinButton(sheet, 570, 188, 28, 38, '=Sheet1!J13', 0, 10, 1, 4); var spin5 = addSpinButton(sheet, 628, 188, 28, 38, '=Sheet1!K13', 0, 10, 1, 1); var style = shape.style(); style.fill = { type: GC.Spread.Sheets.Shapes.GradientFillType.linear, angle: 90, stops: [ { position: 0, color: '#B993D6' }, { position: 1, color: '#8CA6DB' } ] }; style.line.width = 2; style.line.color = 'rgb(0,0,0)'; shape.style(style); let pictureFormat = shape.pictureFormat(); pictureFormat.crop = { left: 0, right: 0, top: -0.05, bottom: -0.35 }; shape.pictureFormat(pictureFormat); shape.geometryType(GC.Spread.Sheets.Shapes.AutoShapeType.roundedRectangle); shape.setFormula('src', '=COLUMNSPARKLINE(Sheet1!G13:K13,1)'); sheet.shapes.group([shape, spin1, spin2, spin3, spin4, spin5]); } function initCustomSparklineSample(sheet) { sheet.getRange(21, 1, 1, 3).hAlign(0).vAlign(1); sheet.setRowHeight(21, 40); addSpinButton(sheet, 94, 420, 30, 40, 'Sheet1!B22', 0, 23, 1, 12); addSpinButton(sheet, 156, 420, 30, 40, 'Sheet1!C22', 0, 59, 1, 45); addSpinButton(sheet, 218, 420, 30, 40, 'Sheet1!D22', 0, 59, 1, 30); var shape = sheet.shapes.addPictureShape('', '', 70, 265, 150, 150); shape.setFormula('src', '=CUSTOMECLOCKSPARKLINE(Sheet1!B22,Sheet1!C22,Sheet1!D22)'); } function addSpinButton(sheet, x, y, width, height, cellLink, minValue, maxValue, step, value) { var spinButton = sheet.shapes.addFormControl('', GC.Spread.Sheets.Shapes.FormControlType.spinButton, x, y, width, height); var options = spinButton.options(); options.cellLink = cellLink; options.minValue = minValue; options.maxValue = maxValue; options.step = step; spinButton.options(options); spinButton.value(value); return spinButton; } class Clock extends GC.Spread.Sheets.Sparklines.SparklineEx { createFunction() { var func = new GC.Spread.CalcEngine.Functions.Function("CUSTOMECLOCKSPARKLINE", 3, 3); func.evaluate = function (args) { return { hours: args[0], mintues: args[1], seconds: args[2] }; }; return func; } paint(context, value, x, y, width, height) { var centerX = x + width / 2; var centerY = y + height / 2; var margin = 10; var padding = 10; var radius = Math.min(width, height) / 2 - margin; if (!value || radius <= 0) { return; } context.save(); //draw circle this._drawCircle(context, centerX, centerY, radius); //draw center this._drawCenter(context, centerX, centerY, 3); //draw hands this._drawHands(context, value, centerX, centerY, radius); //draw numerals this._drawNumerals(context, centerX, centerY, radius - padding); context.restore(); } _drawNumerals(context, centerX, centerY, radius) { var numerals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; context.textAlign = "right"; context.font = "12px sans-serif"; numerals.forEach(function (numeral) { var angle = Math.PI / 6 * (numeral - 3); var numeralWidth = context.measureText(numeral).width; context.beginPath(); context.fillText(numeral, centerX + Math.cos(angle) * radius + numeralWidth / 2, centerY + Math.sin(angle) * radius + numeralWidth / 2); }); } _drawHands(context, value, centerX, centerY, radius) { var hours = value.hours, mintues = value.mintues, seconds = value.seconds; hours = hours > 12 ? hours - 12 : hours; this._drawHand(context, centerX, centerY, hours * 5 + (mintues / 60) * 5, radius / 2); this._drawHand(context, centerX, centerY, mintues, radius * 3 / 4); context.strokeStyle = "red"; this._drawHand(context, centerX, centerY, seconds, radius * 3 / 4); } _drawHand(context, centerX, centerY, loc, radius) { var angle = (Math.PI * 2) * (loc / 60) - Math.PI / 2; context.beginPath(); context.moveTo(centerX, centerY); context.lineTo(centerX + Math.cos(angle) * radius, centerY + Math.sin(angle) * radius); context.stroke(); }; _drawCenter(context, centerX, centerY, radius) { context.beginPath(); context.arc(centerX, centerY, radius, 0, Math.PI * 2, true); context.fill(); } _drawCircle(context, centerX, centerY, radius) { context.beginPath(); context.arc(centerX, centerY, radius, 0, Math.PI * 2, true); context.stroke(); }; } </script> <style scoped> .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: 100%; height: 100%; overflow: hidden; float: left; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } #app { height: 100%; } </style>
<!DOCTYPE html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>SpreadJS VUE</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script> <script src="./systemjs.config.js"></script> <script src="./compiler.js" type="module"></script> <script> var System = SystemJS; System.import("./src/app.js"); System.import('$DEMOROOT$/en/lib/vue3/license.js'); </script> </head> <body> <div id="app"></div> </body> </html>
(function (global) { SystemJS.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, packageConfigPaths: [ './node_modules/*/package.json', "./node_modules/@mescius/*/package.json", "./node_modules/@babel/*/package.json", "./node_modules/@vue/*/package.json" ], map: { 'vue': "npm:vue/dist/vue.esm-browser.js", 'tiny-emitter': 'npm:tiny-emitter/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', "systemjs-babel-build": "npm:systemjs-plugin-babel/systemjs-babel-browser.js", '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js' }, meta: { '*.css': { loader: 'systemjs-plugin-css' }, '*.vue': { loader: "../plugin-vue/index.js" } } }); })(this);