【问题标题】:custom ticks based on selected range from rangeSelector in Highstock基于从 Highstock 中的 rangeSelector 中选择的范围的自定义刻度
【发布时间】:2018-03-09 07:15:29
【问题描述】:

我正在尝试让我的 Highcharts/Highstock 图表在 rangeSelector 设置为 All 时显示自定义刻度,我以这种方式设置它,但是当我尝试使用图表的交互式部分时抛出错误

Highstock Change tick interval on range selector change收到以下答复

  componentDidMount() {
    // Timezone Offset for PST standard is UTC timezone
    Highcharts.setOptions({
        global: {
          timezoneOffset: 8 * 60
        },
        lang: {
          thousandsSep: ','
        }
    });
    Highcharts.stockChart('chart', {
      chart: {
          backgroundColor:'rgba(255, 255, 255, 0.0)',
          height: 400,
          zoomType: 'xy'
      },

      title: {
          text: 'Bitcoin Chart',
          style: {
            color: 'white'
          }
      },

      navigator: {
        trigger: "navigator",
        triggerOp: "navigator-drag",
        rangeSelectorButton: undefined,
        handles: {
          backgroundColor: 'white',
          borderColor: 'black'
        }
      },

      scrollbar: {
        enabled: false
      },

      rangeSelector: {
        buttons: [{
            type: 'day',
            count: 1,
            text: '1d'
        }, {
            type: 'day',
            count: 7,
            text: '7d'
        }, {
            type: 'month',
            count: 1,
            text: '1m'
        }, {
            type: 'month',
            count: 3,
            text: '3m'
        }, {
            type: 'year',
            count: 1,
            text: '1y'
        }, {
            type: 'all',
            text: 'All'
        }],
          selected: 6,
          // styles for the buttons
          buttonTheme: {
            fill: 'black',
            // stroke: 'none',
            'stroke-width': 0,
            r: 8,
            style: {
                color: 'white',
                fontWeight: 'bold'
            },
            states: {
                hover: {
                },
                select: {
                    fill: 'white',
                    style: {
                        color: 'black'
                    }
                }
            }
          },
          // Date Selector box
          inputBoxBorderColor: 'black',
          inputBoxWidth: 120,
          inputBoxHeight: 18,
          inputStyle: {
              color: 'black',
              fontWeight: 'bold'
          },
          labelStyle: {
              color: 'silver',
              fontWeight: 'bold'
          },
      },

      series: [{
          name: 'Bitcoin Price',
          color: 'black',
          data: this.props.data.all_price_values,
          type: 'area',
          threshold: null,
          tooltip: {
            valuePrefix: '$',
            valueSuffix: ' USD',
            valueDecimals: 2
          }
      }],

      plotOptions: {
          series: {
              fillColor: {
                  linearGradient: [0, 0, 0, 0],
                  stops: [
                      [0, '#FF9900'],
                      [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
                  ]
              }
          }
      },

      xAxis: {
        events: {
          setExtremes: function(e) {
            if (e.trigger === "rangeSelectorButton" && e.rangeSelectorButton.text === "All") {
              var range = e.max - e.min;

              // ticks spaced by one day or one hour
              var ticksSpacing = range >= 86400 * 1000 ? 86400 : 3600;

              this.update({
                  tickPositioner: function() {
                      var positions = [],
                      info = this.tickPositions.info;
                      for (var x = this.dataMin; x <= this.dataMax; x += ticksSpacing * 1000) { // Seconds * 1000 for ticks
                          positions.push(x);
                      };
                      positions.info = info;
                      return positions;
                  }
              }, false);
            }
          }
        },
        title: {
          enabled: true,
          text: 'Date (Timezone: PST)',
          style: {
            color: 'white'
          }
        },
        labels: {
          style: {
            color: 'white'
          }
        },
        type: 'datetime',
        dateTimeLabelFormats: {
            day: '%b %e, %Y'
        },
        tickInterval: 1
      },

      yAxis: {
        floor: 0,
        labels: {
          formatter: function () {
                    return '$' + this.axis.defaultLabelFormatter.call(this);
            },
          format: '{value:,.0f}',
          align: 'left',
          style: {
            color: 'white'
          },
        },
      },
      // Mobile Design
      responsive: {
          rules: [{
              condition: {
                  maxWidth: 600
              },
              chartOptions: {
                  chart: {
                      height: 400
                  },
                  subtitle: {
                      text: null
                  },
                  navigator: {
                      enabled: false
                  }
              }
          }]
      }
    });
  }

我说的是蓝色突出显示的部分,当我移动它时,它会引发错误

我试图让图表在 ALL rangeSelector 上每天有 2 个图,显示一天中的第一个点和一天中的最后一个点。我做错了什么?

编辑 1:更新为完整配置,X 轴现在被原始答案打乱,自定义范围选择器上的刻度仍在工作中。添加图像以显示正在发生的事情

【问题讨论】:

    标签: reactjs highcharts highstock


    【解决方案1】:

    每次更改要在图表上显示的范围时,都会引发 setExtremes 事件。它可以有几个来源:

    • 在范围选择器中单击按钮
    • 导航器中的手柄拖动
    • 等等..

    事件的实际属性取决于它的起源。如果您使用console.log(e) 输出事件,您会发现这两个来源并不相同:

    范围选择器中的按钮点击

    {
        trigger: "rangeSelectorButton",
        rangeSelectorButton: {
            text: "2Hour", 
            type: "hour",
            count: 2, 
        }, 
        ...
    }
    

    在导航器中处理拖动

    {
        trigger: "navigator", 
        triggerOp: "navigator-drag", 
        rangeSelectorButton: undefined
    }
    

    如果您在导航器中拖动句柄,则没有rangeSelectorButton 附加到事件,因为它没有意义:在这种情况下,没有按下任何按钮。

    要修复您的错误,您可以在 trigger 属性上添加检查:

     xAxis: {
        events: {
          setExtremes: function(e) {
            if (e.trigger === "rangeSelectorButton" && e.rangeSelectorButton.text === "All") {
               ...
            }
          }
       }
    

    如何解决实际问题

    现在,真正的问题。您想根据显示的内容更改刻度:每天的开始和结束,或者如果不是完整的一天,则为小时。您可以使用代表所选时间范围的e.mine.max 来做到这一点。

    像这样:

    setExtremes: function(e) {
        var range = e.max - e.min;
    
        // ticks spaced by one day or one hour
        var ticksSpacing = range >= 86400 * 1000 ? 86400 : 3600;
    
        this.update({
            tickPositioner: function() {
                var positions = [],
                info = this.tickPositions.info;
                for (var x = this.dataMin; x <= this.dataMax; x += ticksSpacing * 1000) { // Seconds * 1000 for ticks
                    positions.push(x);
                };
                positions.info = info;
                return positions;
            }
        }, false);
    }
    

    【讨论】:

    • 谢谢,与我所做的相比,这现在完全有意义。将报告结果:)
    • 这个解决方案现在在选择范围选择器中的“全部”按钮时弄乱了我的 x 轴标签。我的标签应该是这个(默认为全部)gyazo.com/0cffd8a77b31bccfd74090c46b9ba778。然后选择 All 按钮将其变成这个 gyazo.com/d7e73272f53c60ce5d1f888c52bdd482。函数加载后,标签都被搞砸了。我已更新代码以显示图表的完整配置以帮助调试
    • 1.您的 setExtremes 仅在您单击范围选择器时更改轴; 2. 你的标签很奇怪,因为你的数据可能不一致,并且数据有差距。为确保时间线一致,您可以使用xAxis.ordinal:api.highcharts.com/highstock/xAxis.ordinal
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多