@mozaic-ds/chart
Version:
This template should help get you started developing with Vue 3 and TypeScript in Vite. The template uses Vue 3 `<script setup>` SFCs, check out the [script setup docs](https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup) to learn more.
224 lines (207 loc) • 5.6 kB
text/typescript
import { reactive, ref } from 'vue';
import type { Ref } from 'vue';
import { getHtmlLegendPlugin } from './ChartsCommonLegend';
import PatternFunctions from './PatternFunctions';
import { addAlpha } from './ColorFunctions';
import { getVirtualNodeHeight } from 'mermaid/dist/diagrams/timeline/svgDraw';
const { getPatternIndexWithShift } = PatternFunctions();
interface Dataset {
data: number[];
label: any;
stack?: number;
}
export default function () {
const borderWidth = ref(3);
const barChartRef = ref(null as any);
const onHoverIndex: { dataSetIndex: number; columnIndex: number } = reactive({
dataSetIndex: -1,
columnIndex: -1
});
function privateGetHtmlLegendPlugin(
legendContainer: Ref,
selectMode: Ref<boolean>,
disableAccessibility: Ref<boolean>,
patternsColors: Ref<string[]>,
patternsList: Ref<
((
hover: boolean,
color: string,
disableAccessibility: boolean
) => CanvasPattern)[]
>,
enableHoverFeature: Ref<boolean>
) {
return getHtmlLegendPlugin(
legendContainer,
selectMode,
onHoverIndex,
disableAccessibility,
patternsColors,
patternsList,
enableHoverFeature
);
}
// Hack to force the chart to reload on Hover
function reloadChart() {
borderWidth.value = 4;
borderWidth.value = 3;
}
function getStackedDatasets(
datasets: Dataset[],
stackDatasets: boolean,
disableAccessibility: boolean,
patternsColors: string[],
patternsList: ((
hover: boolean,
color: string,
disableAccessibility: boolean
) => CanvasPattern)[],
patternShifting?: number
) {
// Hack to force refresh
const borderWithValue = borderWidth.value;
return datasets.map((dataset, datasetIndex) => {
return {
borderColor: function (context: any) {
return disableAccessibility
? '#00000000'
: getBorderColor(
datasetIndex,
context.index,
patternsColors,
patternShifting
);
},
backgroundColor: function (context: any) {
return getPattern(
datasetIndex,
context.index,
disableAccessibility,
patternsColors,
patternsList,
patternShifting
);
},
borderWidth: function () {
return disableAccessibility ? 1 : borderWithValue;
},
data: dataset.data,
label: dataset.label,
stack: `Stack ${stackDatasets ? dataset.stack : datasetIndex}`
};
});
}
function getDatasets(
firstDataSet: Dataset,
secondDataSet: Dataset,
patternsColors: string[],
patternsList: ((
hover: boolean,
color: string,
disableAccessibility: boolean
) => CanvasPattern)[],
disableAccessibility: boolean
) {
return getStackedDatasets(
[firstDataSet, secondDataSet],
false,
disableAccessibility,
patternsColors,
patternsList
);
}
function getBorderColor(
dataSetIndex: number,
contextIndex: number,
patternsColors: string[],
patternShifting?: number
) {
const index = getPatternIndexWithShift(dataSetIndex, patternShifting);
if (displayFullOpacity(dataSetIndex, contextIndex)) {
return patternsColors[index];
} else {
return addAlpha(patternsColors[index], 0.2);
}
}
function getPattern(
dataSetIndex: number,
contextIndex: number,
disableAccessibility: boolean,
patternsColors: string[],
patternsList: ((
hover: boolean,
color: string,
disableAccessibility: boolean
) => CanvasPattern)[],
patternShifting?: number
) {
const index = getPatternIndexWithShift(dataSetIndex, patternShifting);
if (displayFullOpacity(dataSetIndex, contextIndex)) {
return patternsList[index](
false,
patternsColors[index],
disableAccessibility
);
} else {
return patternsList[index](
true,
patternsColors[index],
disableAccessibility
);
}
}
function nothingHovered(): boolean {
return onHoverIndex.dataSetIndex < 0;
}
function columnHovered(dataSetIndex: number, contextIndex: number): boolean {
return (
onHoverIndex.dataSetIndex === dataSetIndex &&
onHoverIndex.columnIndex === contextIndex
);
}
function legendHovered(dataSetIndex: number): boolean {
return (
onHoverIndex.dataSetIndex === dataSetIndex && onHoverIndex.columnIndex < 0
);
}
function displayFullOpacity(
dataSetIndex: number,
contextIndex: number
): boolean {
return (
nothingHovered() ||
columnHovered(dataSetIndex, contextIndex) ||
legendHovered(dataSetIndex)
);
}
function resetOnHoverIndex() {
onHoverIndex.dataSetIndex = -1;
onHoverIndex.columnIndex = -1;
}
function getOnHoverOptions() {
return (
_ignore: unknown,
activeElements: Array<{ index: number; datasetIndex: number }>
) => {
if (activeElements[0] !== undefined) {
onHoverIndex.dataSetIndex = activeElements[0].datasetIndex;
onHoverIndex.columnIndex = activeElements[0].index;
} else {
resetOnHoverIndex();
}
};
}
return {
onHoverIndex,
reloadChart,
getDatasets,
getStackedDatasets,
getOnHoverOptions,
getBorderColor,
getPattern,
privateGetHtmlLegendPlugin,
getPatternIndexWithShift,
barChartRef,
borderWidth
};
}