Line Markers

The LineMarker class allows you to add a mouse-driven cursor to your charts. The cursor consists of a text element used to display information about the point under the mouse and optional lines to indicate the exact position of the mouse.

You can customize the appearance of the LineMarker using CSS, and its behavior using properties including content, interaction, and lines.

import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; import * as wjChart from '@grapecity/wijmo.chart'; import * as wjCore from '@grapecity/wijmo'; import * as wjInput from '@grapecity/wijmo.input'; import { getData } from './data'; // document.readyState === 'complete' ? init() : window.onload = init; // function init() { // create the chart let theChart = new wjChart.FlexChart('#theChart', { chartType: 'Line', bindingX: 'date', axisY: { majorGrid: false }, legend: { position: 'None' }, tooltip: { content: '' }, series: [ { binding: 'value', name: 'Value' } ], itemsSource: getData() }); // // add a LineMarker let lm = new wjChart.LineMarker(theChart, { isVisible: false, lines: 'Both', interaction: 'Move', content: (ht) => { return ht.item ? wjCore.format('The value on <b>{date:MMM d, yyyy}</b><br/>is <b>{value:c}</b>', ht.item) : 'No items here...'; } }); // // show the marker when the mouse is over the chart theChart.addEventListener(theChart.hostElement, 'mouseenter', () => { lm.isVisible = true; }); theChart.addEventListener(theChart.hostElement, 'mouseleave', () => { lm.isVisible = false; }); // // configure the LineMarker let lines = new wjInput.ComboBox('#lines', { itemsSource: 'None,Vertical,Horizontal,Both'.split(','), textChanged: (s) => lm.lines = s.text, text: 'Both' }); // let interaction = new wjInput.ComboBox('#interaction', { itemsSource: 'None,Move,Drag'.split(','), textChanged: (s) => lm.interaction = s.text, text: 'Move' }); } <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart LineMarkers</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div class="container-fluid"> <label for="lines">Lines: </label> <div id="lines"></div><br> <label for="interaction">Interaction: </label> <div id="interaction"></div> <div id="theChart"></div> </div> </body> </html> import * as wjCore from '@grapecity/wijmo'; // // create some random data export function getData() { let arr = [], value = 100, date = new Date(); // for (let i = 0; i < 100; i++) { arr.push({ date: date, value: value + Math.random() * 10 - 4 }); // date = wjCore.DateTime.addDays(date, -1); } // return arr; } .wj-flexchart { height: 300px; margin: 10px 0; } .wj-flexchart .wj-chart-linemarker { background: transparent; } .wj-chart-linemarker-content { padding: 12px; margin: 6px; background: white; border-radius: 3px; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } .wj-flexchart .wj-chart-linemarker .wj-chart-linemarker-hline, .wj-flexchart .wj-chart-linemarker .wj-chart-linemarker-vline { height: 1px; width: 1px; opacity: .5; background: navy; } .wj-control { margin-bottom: 3px; } label { width: 120px; text-align: right; } body { margin-bottom: 24pt; } import 'bootstrap.css'; import '@grapecity/wijmo.styles/wijmo.css'; import './styles.css'; // import { Component, Inject, enableProdMode, NgModule, AfterViewInit, ViewChild } from '@angular/core'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { BrowserModule } from '@angular/platform-browser'; import { WjInputModule } from '@grapecity/wijmo.angular2.input'; import { WjChartModule } from '@grapecity/wijmo.angular2.chart'; import { DataService } from './app.data'; import * as wjCore from '@grapecity/wijmo'; import * as wjChart from '@grapecity/wijmo.chart'; // @Component({ selector: 'app-component', templateUrl: 'src/app.component.html' }) export class AppComponent implements AfterViewInit { data: any[]; linesData: string[]; interactionData: string[]; lines: string; interaction: string; lmVisible: boolean; @ViewChild('theChart') theChart: wjChart.FlexChart; // constructor(@Inject(DataService) private dataService: DataService) { this.data = dataService.getData(); this.linesData = dataService.getLinesData(); this.interactionData = dataService.getInteractionData(); this.lines = 'Both'; this.interaction = 'Move'; this.lmVisible = false; } // markerContent(ht: wjChart.HitTestInfo) { return ht.item ? wjCore.format('The value on <b>{date:MMM d, yyyy}</b><br/>is <b>{value:c}</b>', ht.item) : 'No items here...'; } // ngAfterViewInit() { // show the marker when the mouse is over the chart this.theChart.addEventListener(this.theChart.hostElement, 'mouseenter', () => { this.lmVisible = true; }); this.theChart.addEventListener(this.theChart.hostElement, 'mouseleave', () => { this.lmVisible = false; }); } } // @NgModule({ imports: [WjInputModule, WjChartModule, BrowserModule], declarations: [AppComponent], providers: [DataService], bootstrap: [AppComponent] }) export class AppModule { } // enableProdMode(); // Bootstrap application with hash style navigation and global services. platformBrowserDynamic().bootstrapModule(AppModule); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart LineMarkers</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- Polyfills --> <script src="node_modules/core-js/client/shim.min.js"></script> <script src="node_modules/zone.js/dist/zone.min.js"></script> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.js"></script> <script src="systemjs.config.js"></script> <script> // workaround to load 'rxjs/operators' from the rxjs bundle System.import('rxjs').then(function (m) { System.set(SystemJS.resolveSync('rxjs/operators'), System.newModule(m.operators)); System.import('./src/app.component'); }); </script> </head> <body> <app-component></app-component> </body> </html> <div class="container-fluid"> <div class="form-group"> <label for="lines">Lines: </label> <wj-combo-box [(text)]="lines" [itemsSource]="linesData"></wj-combo-box><br> <label for="interaction">Interaction: </label> <wj-combo-box [(text)]="interaction" [itemsSource]="interactionData"></wj-combo-box> <wj-flex-chart #theChart chartType="Line" bindingX="date" tooltipContent="" [itemsSource]="data"> <wj-flex-chart-legend position="None"></wj-flex-chart-legend> <wj-flex-chart-series binding="value" name="Value"></wj-flex-chart-series> <wj-flex-chart-axis wjProperty="axisY" [majorGrid]="false"></wj-flex-chart-axis> <wj-flex-line-marker [lines]="lines" [interaction]="interaction" [isVisible]="lmVisible" [content]="markerContent"></wj-flex-line-marker> </wj-flex-chart> </div> </div> import { Injectable } from '@angular/core'; import * as wjCore from '@grapecity/wijmo'; // @Injectable() export class DataService { getData() { let arr = [], value = 100, date = new Date(); // for (let i = 0; i < 100; i++) { arr.push({ date: date, value: value + Math.random() * 10 - 4 }); // date = wjCore.DateTime.addDays(date, -1); } // return arr; } // getLinesData() { return 'None,Vertical,Horizontal,Both'.split(','); } // getInteractionData() { return 'None,Move,Drag'.split(','); } } .wj-flexchart { height: 300px; margin: 10px 0; } .wj-flexchart .wj-chart-linemarker { background: transparent; } .wj-chart-linemarker-content { padding: 12px; margin: 6px; background: white; border-radius: 3px; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } .wj-flexchart .wj-chart-linemarker .wj-chart-linemarker-hline, .wj-flexchart .wj-chart-linemarker .wj-chart-linemarker-vline { height: 1px; width: 1px; opacity: .5; background: navy; } .wj-control { margin-bottom: 3px; } label { width: 120px; text-align: right; } body { margin-bottom: 24pt; } <template> <div class="container-fluid"> <div class="form-group"> <label for="lines">Lines: </label> <wj-combo-box :text="lines" :itemsSource="linesData" :textChanged="lineChanged"></wj-combo-box><br> <label for="interaction">Interaction: </label> <wj-combo-box :text="interaction" :itemsSource="interactionData" :textChanged="interactionChanged"></wj-combo-box> <wj-flex-chart chartType="Line" bindingX="date" tooltipContent="" :itemsSource="data" :initialized="initializeChart"> <wj-flex-chart-legend position="None"></wj-flex-chart-legend> <wj-flex-chart-series binding="value" name="Value"></wj-flex-chart-series> <wj-flex-chart-axis wjProperty="axisY" :majorGrid="false"></wj-flex-chart-axis> <wj-flex-chart-line-marker :lines="lines" :interaction="interaction" :isVisible="lmVisible" :content="markerContent"></wj-flex-chart-line-marker> </wj-flex-chart> </div> </div> </template> <script> import "@grapecity/wijmo.styles/wijmo.css"; import 'bootstrap.css'; import Vue from 'vue'; import '@grapecity/wijmo.vue2.core'; import '@grapecity/wijmo.vue2.input'; import '@grapecity/wijmo.vue2.chart'; import { getData } from './data'; import * as wjCore from '@grapecity/wijmo'; let App = Vue.extend({ name: 'app', data: function () { return { data: getData(), linesData: 'None,Vertical,Horizontal,Both'.split(','), interactionData: 'None,Move,Drag'.split(','), lines: 'Both', interaction: 'Move', lmVisible: false } }, methods: { initializeChart: function(flex) { this.theChart = flex; // show the marker when the mouse is over the chart flex.addEventListener(flex.hostElement, 'mouseenter', () => { this.lmVisible = true; }); flex.addEventListener(flex.hostElement, 'mouseleave', () => { this.lmVisible = false; }); }, lineChanged: function(flex) { this.lines = flex.text; }, interactionChanged: function(flex) { this.interaction = flex.text; }, markerContent: function(ht) { return ht.item ? wjCore.format('The value on <b>{date:MMM d, yyyy}</b><br/>is <b>{value:c}</b>', ht.item) : 'No items here...'; } } }) new Vue({ render: h => h(App) }).$mount('#app'); </script> <style> .wj-flexchart { height: 300px; margin: 10px 0; } .form-group .wj-flexchart .wj-chart-linemarker { background: transparent; } .wj-chart-linemarker-content { padding: 12px; margin: 6px; background: white; border-radius: 3px; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } .wj-flexchart .wj-chart-linemarker .wj-chart-linemarker-hline, .wj-flexchart .wj-chart-linemarker .wj-chart-linemarker-vline { height: 1px; width: 1px; opacity: .5; background: navy; } .wj-control { margin-bottom: 3px; } label { width: 120px; text-align: right; } body { margin-bottom: 24pt; } </style> <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>GrapeCity Wijmo FlexChart LineMarkers</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app.vue'); </script> </head> <body> <div id="app"></div> </body> </html> export function getData() { let arr = [], value = 100, date = new Date(); // for (let i = 0; i < 100; i++) { arr.push({ date: date, value: value + Math.random() * 10 - 4 }); // date = wijmo.DateTime.addDays(date, -1); } // return arr; } import "@grapecity/wijmo.styles/wijmo.css"; import "bootstrap.css"; import "./app.css"; // import * as React from 'react'; import * as ReactDOM from 'react-dom'; // import * as wjCore from "@grapecity/wijmo"; import * as wjChart from "@grapecity/wijmo.react.chart"; import * as wjInput from "@grapecity/wijmo.react.input"; import { getData } from "./data"; class App extends React.Component { constructor(props) { super(props); this.state = { data: getData(), linesData: 'None,Vertical,Horizontal,Both'.split(','), interactionData: 'None,Move,Drag'.split(','), lines: 'Both', interaction: 'Move', lmVisible: false }; } render() { return <div className="container-fluid"> <div className="form-group"> <label htmlFor="lines">Lines: </label> <wjInput.ComboBox selectedValue={this.state.lines} itemsSource={this.state.linesData} textChanged={this.lineChanged.bind(this)}></wjInput.ComboBox><br /> <label htmlFor="interaction">Interaction: </label> <wjInput.ComboBox selectedValue={this.state.interaction} itemsSource={this.state.interactionData} textChanged={this.interactionChanged.bind(this)}></wjInput.ComboBox> <wjChart.FlexChart chartType="Line" bindingX="date" tooltipContent="" itemsSource={this.state.data} initialized={this.initializeChart.bind(this)}> <wjChart.FlexChartLegend position="None"></wjChart.FlexChartLegend> <wjChart.FlexChartSeries binding="value" name="Value"></wjChart.FlexChartSeries> <wjChart.FlexChartAxis wjProperty="axisY" majorGrid={false}></wjChart.FlexChartAxis> <wjChart.FlexChartLineMarker lines={this.state.lines} interaction={this.state.interaction} isVisible={this.state.lmVisible} content={this.markerContent.bind(this)}> </wjChart.FlexChartLineMarker> </wjChart.FlexChart> </div> </div>; } initializeChart(flex) { // show the marker when the mouse is over the chart flex.addEventListener(flex.hostElement, 'mouseenter', () => { this.setState({ lmVisible: true }); }); flex.addEventListener(flex.hostElement, 'mouseleave', () => { this.setState({ lmVisible: false }); }); } lineChanged(flex) { this.setState({ lines: flex.selectedValue }); } interactionChanged(flex) { this.setState({ interaction: flex.selectedValue }); } markerContent(ht) { return ht.item ? wjCore.format('The value on <b>{date:MMM d, yyyy}</b><br/>is <b>{value:c}</b>', ht.item) : 'No items here...'; } } ReactDOM.render(<App />, document.getElementById('app')); <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>Grapecity Wijmo OLAP Pivot Chart Overview</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- SystemJS --> <script src="node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('./src/app'); </script> </head> <body> <div id="app"></div> </body> </html> .wj-flexchart { height: 300px; margin: 10px 0; } .form-group .wj-flexchart .wj-chart-linemarker { background: transparent; } .wj-chart-linemarker-content { padding: 12px; margin: 6px; background: white; border-radius: 3px; box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23); } .wj-flexchart .wj-chart-linemarker .wj-chart-linemarker-hline, .wj-flexchart .wj-chart-linemarker .wj-chart-linemarker-vline { height: 1px; width: 1px; opacity: .5; background: navy; } .wj-control { margin-bottom: 3px; } label { width: 120px; text-align: right; } body { margin-bottom: 24pt; } import * as wjCore from "@grapecity/wijmo"; export function getData() { let arr = [], value = 100, date = new Date(); // for (let i = 0; i < 100; i++) { arr.push({ date: date, value: value + Math.random() * 10 - 4 }); // date = wjCore.DateTime.addDays(date, -1); } // return arr; }