Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于折线图选中点更新显示 #1577

Closed
Choice-Fei opened this issue Dec 12, 2024 · 4 comments
Closed

关于折线图选中点更新显示 #1577

Choice-Fei opened this issue Dec 12, 2024 · 4 comments
Labels

Comments

@Choice-Fei
Copy link

image
你好,我想通过代码来控制更新这个选中点的显示(非点击),怎么实现

@AAChartModel
Copy link
Owner

参考:

OC 版本的代码:

//https://github.com/AAChartModel/AAChartKit-Swift/issues/345
+ (AAOptions *)setCrosshairAndTooltipToTheDefaultPositionAfterLoadingChart {
    AAChartModel *aaChartModel = AAChartModel.new
    .chartTypeSet(AAChartTypeAreaspline)//图表类型
    .colorsThemeSet(@[@"#04d69f",@"#1e90ff",@"#ef476f",@"#ffd066",])
    .stackingSet(AAChartStackingTypeNormal)
    .yAxisVisibleSet(false)
    .markerRadiusSet(@0)
    .seriesSet(@[
        AASeriesElement.new
        .nameSet(@"Tokyo Hot")
        .lineWidthSet(@5.0)
        .fillOpacitySet(@0.4)
        .dataSet(@[@0.45, @0.43, @0.50, @0.55, @0.58, @0.62, @0.83, @0.39, @0.56, @0.67, @0.50, @0.34, @0.50, @0.67, @0.58, @0.29, @0.46, @0.23, @0.47, @0.46, @0.38, @0.56, @0.48, @0.36]),
        AASeriesElement.new
        .nameSet(@"Berlin Hot")
        .lineWidthSet(@5.0)
        .fillOpacitySet(@0.4)
        .dataSet(@[@0.38, @0.31, @0.32, @0.32, @0.64, @0.66, @0.86, @0.47, @0.52, @0.75, @0.52, @0.56, @0.54, @0.60, @0.46, @0.63, @0.54, @0.51, @0.58, @0.64, @0.60, @0.45, @0.36, @0.67]),
        AASeriesElement.new
        .nameSet(@"London Hot")
        .lineWidthSet(@5.0)
        .fillOpacitySet(@0.4)
        .dataSet(@[@0.46, @0.32, @0.53, @0.58, @0.86, @0.68, @0.85, @0.73, @0.69, @0.71, @0.91, @0.74, @0.60, @0.50, @0.39, @0.67, @0.55, @0.49, @0.65, @0.45, @0.64, @0.47, @0.63, @0.64]),
        AASeriesElement.new
        .nameSet(@"NewYork Hot")
        .lineWidthSet(@5.0)
        .fillOpacitySet(@0.4)
        .dataSet(@[@0.60, @0.51, @0.52, @0.53, @0.64, @0.84, @0.65, @0.68, @0.63, @0.47, @0.72, @0.60, @0.65, @0.74, @0.66, @0.65, @0.71, @0.59, @0.65, @0.77, @0.52, @0.53, @0.58, @0.53]),
    ]);
    
    AAOptions *aaOptions = aaChartModel.aa_toAAOptions;
    
    aaOptions.tooltip
        .styleSet(AAStyleColor(AAColor.whiteColor))
        .backgroundColorSet(@"#050505")
        .borderColorSet(@"#050505");
    
    aaOptions.xAxis
        .crosshairSet(AACrosshair.new
            .colorSet(AAColor.darkGrayColor)
            .dashStyleSet(AAChartLineDashStyleTypeLongDashDotDot)
            .widthSet(@2));
    
    //默认选中的位置索引
    NSUInteger defaultSelectedIndex = 5;
    
    //https://api.highcharts.com/highcharts/chart.events.load
    //https://www.highcharts.com/forum/viewtopic.php?t=36508
    aaOptions.chart
        .eventsSet(AAChartEvents.new
            .loadSet([NSString stringWithFormat:@AAJSFunc(function() {
                const points = [];
                const chart = this;
                const series = chart.series;
                const length = series.length;
                           
                for (let i = 0; i < length; i++) {
                    const pointElement = series[i].data[%ld];
                    pointElement.onMouseOver();
                    points.push(pointElement);
                }
                chart.xAxis[0].drawCrosshair(null, points[0]);
                chart.tooltip.refresh(points);
                       }), defaultSelectedIndex]));
    
    
    return aaOptions;
}

你可以在 demo 中找到这段代码.

@AAChartModel
Copy link
Owner

AAChartModel commented Dec 12, 2024

参考 demo 中的这段图表示例代码:

+ (AAOptions *)autoCrosshairAndTooltip {
    return AAOptions.new
        .titleSet(AATitle.new
            .textSet(@"Auto Crosshair And Tooltip"))
        .chartSet(AAChart.new
            .typeSet(AAChartTypeAreaspline)
            .eventsSet(AAChartEvents.new
                .loadSet(@AAJSFunc(function() {
                    const chart = this;
                    let currentIndex = 0;
                    let intervalId;
                    let isTouched = false;

                    function moveTooltip() {
                        const pointsToShow = [];
                        for (let i = 0; i < chart.series.length; i++) {
                            const point = chart.series[i].points[currentIndex];
                            if (point) {
                                pointsToShow.push(point);
                            }
                        }

                        if (pointsToShow.length > 0) {
                            chart.tooltip.refresh(pointsToShow);
                            chart.xAxis[0].drawCrosshair(null, pointsToShow[0]);

                            currentIndex = (currentIndex + 1) % chart.series[0].points.length;
                        }
                    }

                    function startInterval() {
                        if (intervalId) {
                            clearInterval(intervalId);
                        }
                        intervalId = setInterval(moveTooltip, 2000); // 每2秒切换一次
                    }

                    // 立即显示第一个点的 tooltip 和十字线
                    moveTooltip();

                    // 初始启动 interval
                    startInterval();

                    // 触摸开始
                    chart.container.ontouchstart = function(e) {
                        isTouched = true;
                        if (intervalId) {
                            clearInterval(intervalId);
                            intervalId = null;
                        }
                        handleTouch(e);
                    };

                    // 触摸移动
                    chart.container.ontouchmove = function(e) {
                        if (isTouched) {
                            handleTouch(e);
                        }
                    };

                    function handleTouch(e) {
                        e.preventDefault(); // 阻止默认的滚动行为
                        const touch = e.touches[0];
                        const event = chart.pointer.normalize(touch);
                        const point = chart.series[0].searchPoint(event, true);
                        if (point) {
                            currentIndex = chart.series[0].points.indexOf(point);
                            const pointsToShow = [];
                            for (let i = 0; i < chart.series.length; i++) {
                                const pointInSeries = chart.series[i].points[currentIndex];
                                if (pointInSeries) {
                                    pointsToShow.push(pointInSeries);
                                }
                            }
                            chart.tooltip.refresh(pointsToShow);
                            chart.xAxis[0].drawCrosshair(event, point);
                        }
                    }

                    // 触摸结束
                    chart.container.ontouchend = function() {
                        isTouched = false;
                        if (!intervalId) {
                            // 立即移动到下一个点,然后开始 interval
                            moveTooltip();
                            startInterval();
                        }
                    };

                    // 在图表销毁时清除 interval
                    this.callbacks.push(function() {
                        if (intervalId) {
                            clearInterval(intervalId);
                        }
                    });
                }))))
        .colorsSet(@[@"#04d69f", @"#1e90ff", @"#ef476f", @"#ffd066"])
        .plotOptionsSet(AAPlotOptions.new
            .seriesSet(AASeries.new
                .stackingSet(AAChartStackingTypeNormal)
                .markerSet(AAMarker.new
                    .radiusSet(@0))))
        .tooltipSet(AATooltip.new
            .styleSet(AAStyleColor(AAColor.whiteColor))
            .backgroundColorSet(@"#050505")
            .borderColorSet(@"#050505"))
        .xAxisSet(AAXAxis.new
            .crosshairSet(AACrosshair.new
                .colorSet(AAColor.darkGrayColor)
                .dashStyleSet(AAChartLineDashStyleTypeLongDashDotDot)
                .widthSet(@2)))
        .yAxisSet(AAYAxis.new
            .visibleSet(false))
        .seriesSet(@[
            AASeriesElement.new
                .nameSet(@"Tokyo Hot")
                .lineWidthSet(@5.0)
                .fillOpacitySet(@0.4)
                .dataSet(@[@0.45, @0.43, @0.50, @0.55, @0.58, @0.62, @0.83, @0.39, @0.56, @0.67, @0.50, @0.34, @0.50, @0.67, @0.58, @0.29, @0.46, @0.23, @0.47, @0.46, @0.38, @0.56, @0.48, @0.36]),
            AASeriesElement.new
                .nameSet(@"Berlin Hot")
                .lineWidthSet(@5.0)
                .fillOpacitySet(@0.4)
                .dataSet(@[@0.38, @0.31, @0.32, @0.32, @0.64, @0.66, @0.86, @0.47, @0.52, @0.75, @0.52, @0.56, @0.54, @0.60, @0.46, @0.63, @0.54, @0.51, @0.58, @0.64, @0.60, @0.45, @0.36, @0.67]),
            AASeriesElement.new
                .nameSet(@"London Hot")
                .lineWidthSet(@5.0)
                .fillOpacitySet(@0.4)
                .dataSet(@[@0.46, @0.32, @0.53, @0.58, @0.86, @0.68, @0.85, @0.73, @0.69, @0.71, @0.91, @0.74, @0.60, @0.50, @0.39, @0.67, @0.55, @0.49, @0.65, @0.45, @0.64, @0.47, @0.63, @0.64]),
            AASeriesElement.new
                .nameSet(@"NewYork Hot")
                .lineWidthSet(@5.0)
                .fillOpacitySet(@0.4)
                .dataSet(@[@0.60, @0.51, @0.52, @0.53, @0.64, @0.84, @0.65, @0.68, @0.63, @0.47, @0.72, @0.60, @0.65, @0.74, @0.66, @0.65, @0.71, @0.59, @0.65, @0.77, @0.52, @0.53, @0.58, @0.53]),
        ]);
}

@Choice-Fei
Copy link
Author

默认项的话我看懂了,动态更新的话,就需要重新设置event然后调用aa_refreshChartWithOptions这个方法来实现?

@AAChartModel
Copy link
Owner

默认项的话我看懂了,动态更新的话,就需要重新设置event然后调用aa_refreshChartWithOptions这个方法来实现?

只是更新局部内容的话, 调用这个全局刷新的方法 aa_refreshChartWithOptions, 效率太低了.

可以参考 demo 中的下面这段代码:

- (void)setupChartViewHandler {
    __weak typeof(self) weakSelf = self;
    [_aaChartView1 moveOverEventHandler:^(AAChartView *aaChartView,
                                          AAMoveOverEventMessageModel *message) {
        //默认选中的位置索引
        NSUInteger defaultSelectedIndex = message.index;
        
        //https://api.highcharts.com/highcharts/chart.events.load
        //https://www.highcharts.com/forum/viewtopic.php?t=36508
       NSString *jsFunc = ([NSString stringWithFormat:@AAJSFunc((
    function syncRefreshTooltip() {
           const points = [];
           const chart = aaGlobalChart;
           const series = chart.series;
           const length = series.length;
                      
           for (let i = 0; i < length; i++) {
               const pointElement = series[i].data[%ld];
               pointElement.onMouseOver();
               points.push(pointElement);
           }
           chart.xAxis[0].drawCrosshair(null, points[0]);
           chart.tooltip.refresh(points);
    }
    syncRefreshTooltip();
        )), defaultSelectedIndex]);
        
        
        
        [weakSelf.aaChartView2 aa_evaluateJavaScriptStringFunction:jsFunc];
    }];
}

重点是这一句[weakSelf.aaChartView2 aa_evaluateJavaScriptStringFunction:jsFunc];.

直接执行这一小段 js 代码即可. 这样能做到只是局部刷新, 也就避免了低效的全局刷新.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants