StockChart Annotation Not rendering

hello.

I use Vue3 + typescript

The inside of the vue file is in Composition API format.

-------------------------------------

<script setup lang="ts">

  ~~

</script>

-------------------------------------

I am developing in this way.

The ej2-vue-charts version in use is v22.1.36.

I want to add the Custom Component I created to the Annotation of StockChart.

I used the code below, but rendering does not work.

I hope you can get help with a solution or sample code that works well.

help. please.


※ StockChartControl.vue and ChartInfoPanel.vue are components.


Related Codes



ChartInfoPanel.vue
<script setup lang="ts">
import { onMounted } from 'vue';
import { ChartInfo } from '../models/base-types';

const props = defineProps<{
  modelValue: ChartInfo;
}>();

const emitData = defineEmits<{
  (eventName: "update:modelValue"): void;
}>();

onMounted(() => {  
});

function onClick() {
  alert("click!!");
}

</script>

<template>
  <div id="stock-chart-panel">
    <div class="row row-cols-auto gx-2">
      <div class="col">
        {{ props.modelValue.name }}
      </div>
      <div class="col">
        <button class="btn btn-outline-light btn-sm px-1 py-0"
          style="background-color: gray;opacity: 40%;font-size: 0.74rem;" @click="onClick"><i
            class="bi bi-gear"></i></button>
      </div>
    </div>
  </div>
</template>


StockChartControl.vue

<script setup lang="ts">
import { onBeforeMount, onMounted, provide } from "vue"
import Ohlcv from "../models/ohlcv";
import moment from "moment";
import { ChartInfo } from "../models/base-types";
import ChartInfoPanel from "./../components/ChartInfoPanel.vue"

import {
  StockChartComponent as EjsStockchart,
  StockChartAxesDirective as EStockchartAxes,
  StockChartAxisDirective as EStockchartAxis,
  StockChartSeriesCollectionDirective as EStockchartSeriesCollection,
  StockChartSeriesDirective as EStockchartSeries,  
  StockChartAnnotationsDirective as EStockchartAnnotations,
  StockChartAnnotationDirective as EStockchartAnnotation,
  DateTime,  
  Crosshair,
  ColumnSeries,
  Tooltip,
  RangeTooltip,
  LineSeries,
  SplineSeries,
  CandleSeries,
  HiloOpenCloseSeries,
  HiloSeries,
  RangeAreaSeries,
  Trendlines,
  Export,
  StockLegend,
  Zoom,
  ScrollBar,
  ChartAnnotation,  
  StockChartAxisModel,
  CrosshairSettingsModel,
  LegendSettingsModel,
  StockChartAreaModel,
  StockTooltipSettingsModel,
  ZoomSettingsModel,
  CrosshairTooltipModel,
  StockChartBorderModel,
} from "@syncfusion/ej2-vue-charts";


let ohlcvData: Ohlcv[] = [];
let prevOhlcv: Ohlcv | null = null;

const chartInfo: ChartInfo = {
  name: "Sample-Chart",
  description: "Test...."
};

function randomFloat(min: number, max: number, decimals: number) {
    const str = (Math.random() * (max - min) + min).toFixed(decimals);
    return parseFloat(str);
}

onBeforeMount(() => {

  //create chart data
  for (let i = 0; i < 1000; i++) {

    const now = moment();
    const date = now.clone().add(i, "days");

    const open = prevOhlcv === null ?  randomFloat(100, 200, 2): randomFloat(prevOhlcv.low, prevOhlcv.high, 2);
    const high = randomFloat(open, open + 10, 2);
    const low = randomFloat(open, open - 10, 2);
    const close = randomFloat(low, high, 2);
    const volume = randomFloat(0, 1000000, 2);

    const ohlcv = new Ohlcv(open, high, low, close, volume, date.toDate());
    ohlcvData.push(ohlcv);

    prevOhlcv = ohlcv;  
  }
});


onMounted(() => {
});

const contentTemplate = function() {
  return { template: ChartInfoPanel };
};

let selectedTheme = location.hash.split("/")[1];
selectedTheme = selectedTheme ? selectedTheme : "Material";
let theme = (selectedTheme.charAt(0).toUpperCase() + selectedTheme.slice(1)).replace(/-dark/i, "Dark").replace(/contrast/i, 'Contrast');

let seriesData = ohlcvData;

let primaryXAxis: StockChartAxisModel = {
  valueType: "DateTime",
  majorGridLines: { color: "transparent" },
  crosshairTooltip: { enable: true, },
  enableAutoIntervalOnZooming: false,  
  labelFormat: "yyyy-MM-dd"
};

let primaryYAxis: StockChartAxisModel = {
  lineStyle: { color: "transparent" },
  majorTickLines: { color: "transparent", height: 0 },
  crosshairTooltip: { enable: true },    
};

let crosshairTooltip: CrosshairTooltipModel = { enable: true };
let chartArea: StockChartAreaModel = { border: { width: 0 } };
let crosshair: CrosshairSettingsModel = { enable: true, lineType: 'Both' };
let legend: LegendSettingsModel = { visible: false, padding: 3, position: "Bottom", title: `` };

let tooltip: StockTooltipSettingsModel = { enable: false, shared: false, position: "Fixed" }
let border: StockChartBorderModel = { width: 0 };
let zoom: ZoomSettingsModel = { enableMouseWheelZooming: false, enablePinchZooming: false, enableSelectionZooming: true, toolbarItems: ['ZoomIn', 'ZoomOut', 'Pan', 'Reset'], showToolbar: false, enablePan: false, mode: 'X'};

const stockChartElements = [
  ColumnSeries,
  DateTime,
  Tooltip,
  Crosshair,
  RangeTooltip,
  LineSeries,
  SplineSeries,
  CandleSeries,
  HiloOpenCloseSeries,
  HiloSeries,
  RangeAreaSeries,
  Trendlines,
  Export,
  StockLegend,
  Zoom,
  ScrollBar,
  ChartAnnotation
];

provide('stockChart', stockChartElements);

</script>

<template>
  <div class="container-fluid">
    <div class="row">
      <ejs-stockchart ref="mainChart" height='800px' :primaryXAxis="primaryXAxis" :primaryYAxis="primaryYAxis"
        :chartArea="chartArea" :crosshair="crosshair" :tooltip="tooltip" :border="border"
        :theme="theme" :legendSettings="legend" :enableSelector="true" :enablePeriodSelector="false" connector="{color: #ff0000}"
        :zoomSettings="zoom" enableCustomRange="true">
        <e-stockchart-annotations>          
          <e-stockchart-annotation :content="contentTemplate" coordinateUnits="Pixel" x=0 y="200" yAxisName="yAxis0" region="Chart" horizontalAlignment="Far" verticalAlignment="Bottom">
          </e-stockchart-annotation>
        </e-stockchart-annotations>        
        <e-stockchart-axes>
          <e-stockchart-axis
            rowIndex="0"
            name="yAxis1"
            position="Bottom"        
            opposedPosition="true"    
            labelPosition="Inside"            
            tickPosition="Inside"
            :crosshairTooltip=crosshairTooltip
          ></e-stockchart-axis>    
        </e-stockchart-axes>
        <e-stockchart-series-collection>                    
          <e-stockchart-series :dataSource="seriesData" type="Candle" market="true" volume="volume" xName="dateTime" low="low" high="high" open="open" close="close" yName="open" yAxisName="yAxis1" name="Stock" :enableSolidCandles="true"></e-stockchart-series>          
        </e-stockchart-series-collection>
      </ejs-stockchart>
    </div>
  </div>
</template>
<style>
</style>


base-type.ts

type ChartInfo = {
  name: string,
  description: string | null,
}

export type { ChartInfo }



1 Reply

NP Nishanthi Panner Selvam Syncfusion Team November 6, 2023 03:37 PM UTC

Hi Ultra,


Greetings from Syncfusion.


We have ensured your reported scenario by using functional template for annotation in the stockchart with Vue3. We're pleased to inform you that StockChart annotations are rendering correctly as per the expected behavior.


We have attached code-snippet, sample and screenshot for your reference.


Code-snippet:


<ejs-stockchart :primaryXAxis="primaryXAxis"  :primaryYAxis="primaryYAxis" :title="title">

    <e-stockchart-annotations>         

          <e-stockchart-annotation :content="contentTemplate" x="50%" y="25%" >

          </e-stockchart-annotation>

        </e-stockchart-annotations>        

      <e-stockchart-series-collection>

          <e-stockchart-series :dataSource="seriesData" type="Candle" xName="x" low="low" high="high" open="open" close="close" yName="y">

          </e-stockchart-series>

      </e - stockchart - series - collection >

  </ejs - stockchart >

 

   let contentVue = app.component("contentTemplate", {

        template: `Stock Annotation`,

        data() {

            return {

                data: {}

            };

        }

    });

    let contentTemplate = function () {

        return { template: contentVue };

    };


Additionally, please make sure to add the below configuration to your vite.config.ts file. This configuration is essential to ensure that the annotation template is rendered correctly.


Vite.config.ts

 

  export default defineConfig({

        plugins: [vue()],

        resolve: {

            alias: {

                'vue': 'vue/dist/vue.esm-bundler',

            },

        }

    })


Screenshot:




More information on annotation we suggest you to refer https://ej2.syncfusion.com/vue/documentation/accumulation-chart/annotation


Kindly revert us if you have any concerns.


Regards,

Nishanthi


Attachment: Vue3_chart_annotation_311d3ab1.zip

Loader.
Up arrow icon