Как мы можем добавить текст на гистограмму? - PullRequest
0 голосов
/ 19 марта 2020

Использование Lightningchart JS Мне нужна гистограмма, которая содержит текст на гистограмме. Как добавить текст на панель?

const months = [
    'January', 'February', 'March', 'April', 'May', 'June', 'July',
    'August', 'September', 'October', 'November', 'December'
]


    const barText = chart.addUIElement(
                    UILayoutBuilders.Row,
                    { x: axisX.scale, y: axisY.scale }
                )
                    .setOrigin(UIOrigins.Center)
                    .setDraggingMode(UIDraggingModes.notDraggable)
                    .setPosition({
                        x:x - figureThickness,
                        y: 0 ,
                    })
                    .setBackground(background => background
                        .setStrokeStyle(emptyLine)
                    )
                spanText.addElement(
                    UIElementBuilders.TextBox
                        .addStyler(
                            textBox =>
                                textBox.setFont(fontSettings => fontSettings.setSize(10)).setText(months[index])
                                    .setTextFillStyle(new SolidFill().setColor(ColorRGBA(255, 255, 255)))
                        )

Original Graph Expected Graph

1 Ответ

1 голос
/ 03 апреля 2020

То, что вы пытались сделать, немного сложнее, чем то, что действительно требуется.

Вы можете использовать UIElementBuilders.TextBox для создания текстовых полей для каждой диаграммы. Убедитесь, что вы используете шкалу осей для серии, в которую вы хотите поместить текстовые поля.

const uiElement = chart.addUIElement(
    UIElementBuilders.TextBox,
    { x:chart.getDefaultAxisX().scale, y:chart.getDefaultAxisY().scale }
)

Затем вы можете позиционировать текстовое поле с такой же информацией о положении, что и столбец.

.setPosition({x: x - figureGap, y:0})

Чтобы получить смещение позиционирования от y так, как вы хотели, вы можете изменить исходную точку для текстового поля.

.setOrigin(UIOrigins.CenterBottom) для столбцов, которые являются положительными и .setOrigin(UIOrigins.CenterTop) для столбцов, которые являются отрицательными.

См. Фрагмент кода ниже для полного примера.

/*
 * LightningChartJS example for rendering a 'vertical bar chart' using user-side logic as there is no dedicated Chart type for Bars, yet.
 */
// Extract required parts from LightningChartJS.
const {
    lightningChart,
    AxisScrollStrategies,
    SolidFill,
    ColorRGBA,
    emptyLine,
    emptyFill,
    AutoCursorModes,
    UIOrigins,
    emptyTick,
    UIElementBuilders
} = lcjs

const lc = lightningChart()

const months = [
    'January', 'February', 'March', 'April', 'May', 'June', 'July',
    'August', 'September', 'October', 'November', 'December'
]
// Define an interface for creating vertical bars.
let barChart
{
    barChart = (options) => {
        // flat red fill style for positive bars
        const flatRedStyle = new SolidFill().setColor(ColorRGBA(242, 67, 79))
        // flat blue fill style for negative bars
        const flatBlueStyle = new SolidFill().setColor(ColorRGBA(42, 171, 240))

        let x = 0
        const figureThickness = 10
        const figureGap = figureThickness * .5
        const bars = []

        // Create a XY-Chart and add a RectSeries to it for rendering rectangles.
        const chart = lc.ChartXY(options)
            .setTitle('Changes in electricity usage between 2017 and 2018')
            .setAutoCursorMode(AutoCursorModes.onHover)
            // Disable mouse interactions (e.g. zooming and panning) of plotting area
            .setMouseInteractions(false)

        // Bar series represented with rectangles.
        const rectangles = chart.addRectangleSeries()

        // cursor
        //#region
        // Show band using Rectangle series.
        const band = chart.addRectangleSeries()
            .setMouseInteractions(false)
            .setCursorEnabled(false).add({ x: 0, y: 0, width: 0, height: 0 })
            .setFillStyle(new SolidFill().setColor(ColorRGBA(255, 255, 255, 50)))
            .setStrokeStyle(emptyLine)
            .dispose()
        // Modify AutoCursor.
        chart.setAutoCursor(cursor => cursor
            .disposePointMarker()
            .disposeTickMarkerX()
            .disposeTickMarkerY()
            .setGridStrokeXStyle(emptyLine)
            .setGridStrokeYStyle(emptyLine)
            .setResultTable((table) => {
                table
                    .setOrigin(UIOrigins.CenterBottom)
            })
        )
        // Change how series parses its data-points using series method.
        rectangles.setResultTableFormatter((builder, series, figure) => {
            let counter = 0
            // Find cached entry for the figure.
            const entry = bars.find((bar, index) => {
                counter = index;
                return bar.rect == figure
            }).entry
            // Parse result table content from values of 'entry'.
            return builder
                .addRow(`Month: ${months[counter]}`)
                .addRow(`Value: ${entry.value}%`)
        })
        // Apply cursor logic using series.onHover method
        rectangles.onHover((_, point) => {
            if (point) {
                const figure = point.figure
                const dimensions = figure.getDimensionsPositionAndSize()
                // Show band.
                band
                    .setDimensions({
                        x: dimensions.x - figureGap * .5,
                        y: figure.scale.y.getInnerStart(),
                        width: dimensions.width + figureGap,
                        height: figure.scale.y.getInnerInterval()
                    })
                    .restore()
            } else
                band.dispose()
        })
        //#endregion

        // X-axis of the series
        const axisX = chart.getDefaultAxisX()
            .setTitle('Quarter')
            .setMouseInteractions(false)
            .setScrollStrategy(undefined)
            // Disable default ticks.
            .setTickStyle(emptyTick)

        // Y-axis of the series
        const axisY = chart.getDefaultAxisY()
            .setTitle('(%)')
            .setMouseInteractions(false)
            .setScrollStrategy(AxisScrollStrategies.fitting)

        /**
         * Add multiple bars.
         * @param entries Add multiple bars data.
         */
        const addValues = (entries) => {
            for (const entry of entries) {
                bars.push(add(entry))
            }
        }
        /**
         * Add single bar.
         * @param entry Add a single bar data.
         */
        const addValue = (entry) => {
            bars.push(add(entry))
        }
        /**
         * Construct bar to draw.
         * @param entry Single bar data.
         */
        const add = (entry) => {
            // Create rect dimensions.
            const rectDimensions = {
                x: x - figureThickness,
                y: 0,
                width: figureThickness,
                height: entry.value
            }
            // Add rect to the series.
            const rect = rectangles.add(rectDimensions)
            // Set individual color for the bar.
            rect.setFillStyle(entry.value > 0 ? flatRedStyle : flatBlueStyle)

            // Set view manually.
            axisX.setInterval(
                -(figureThickness + figureGap),
                x + figureGap
            )

            // Add custom tick, more like categorical axis.
            axisX.addCustomTick()
                .setValue(x - figureGap)
                .setGridStrokeLength(0)
                .setTextFormatter(_ => entry.category)
                .setMarker(marker => marker
                    .setPadding(4)
                    .setBackground((background) => background
                        .setFillStyle(emptyFill)
                        .setStrokeStyle(emptyLine)
                    )
                )

            const uiElement = chart.addUIElement(
                UIElementBuilders.TextBox,
                { x:chart.getDefaultAxisX().scale, y:chart.getDefaultAxisY().scale }
            )
                .setText(entry.label)
                .setTextFillStyle(new SolidFill({color:ColorRGBA(0,0,0)}))
                .setPosition({x: x - figureGap,y:0})
                .setOrigin(UIOrigins.CenterBottom)
            
            if(Math.sign(entry.value) === -1){
                uiElement.setOrigin(UIOrigins.CenterTop)
            }

            x += figureThickness + figureGap
            // Return data-structure with both original 'entry' and the rectangle figure that represents it.
            return {
                entry,
                rect
            }
        }

        // Return public methods of a bar chart interface.
        return {
            addValue,
            addValues
        }
    }
}

// Use bar chart interface to construct series.
const chart = barChart()
// Add multiple bars at once.
chart.addValues([
    { category: '', value: 20, label: 'JAN' },
    { category: 'Q1', value: 20, label: 'FEB'},
    { category: '', value: -25, label: 'MAR' },
    { category: '', value: 40, label: 'APR' },
    { category: 'Q2', value: 28, label: 'MAY' },
    { category: '', value: -23, label: 'JUN' },
    { category: '', value: -40, label: 'JUL' },
    { category: 'Q3', value: 35, label: 'AUG' },
    { category: '', value: 17, label: 'SEP' },
    { category: '', value: 24, label: 'OCT' },
    { category: 'Q4', value: -29, label: 'NOV' },
    { category: '', value: 15, label: 'DEC' }
])
<script src="https://unpkg.com/@arction/lcjs@1.2.2/dist/lcjs.iife.js"></script>
...