我正在制作一个堆叠的条形图,比较两个不同年份的季度业绩.一年绘制为正值条形图,第二年使用结果值*-1绘制,因此它绘制在同一季度以下.

enter image description here

在本例中,2023年QTR1为469,2022年QTR1实际为676.在查询过程中,最低年份值乘以-1.

如何使负值显示在底部栏的下方,并使正值保持在顶部,就像现在一样?

JavaScript:如下所示:

 <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
 <script type="text/javascript">

     google.charts.load('current', { packages: ['corechart'] });
     google.charts.setOnLoadCallback(drawChart);

     function drawChart() {
         var data = new google.visualization.DataTable();

         var jsonList = @(Json.Serialize(Model.listAllAircraftChartQuarterly))

         var title = 'Quarterly Aircraft Transaction Trend';

         data.addColumn('string', 'Quarter');
         data.addColumn('number', '2023');
         data.addColumn('number', '2022');
         data.addColumn('number', '% Change');
         data.addRows(jsonList.map((p) => {
             return [p.yearQuarter, p.year2top, p.year3bottom, p.year2percent];
         }));

         var formatPercent = new google.visualization.NumberFormat({ pattern: '#.#%' });
         formatPercent.format(data, 3);

         var view = new google.visualization.DataView(data);
         view.setColumns([0, 1,
             {
                 calc: "stringify",
                 sourceColumn: 1,
                 type: "string",
                 role: "annotation"
             },
             2,
             {
                 calc: "stringify",
                 sourceColumn: 2,
                 type: "string",
                 role: "annotation"
             },
             3,
             {
                 calc: "stringify",
                 sourceColumn: 3,
                 type: "string",
                 role: "annotation"
             }
         ]);
         var options = {
             title: title,
             titlePosition: 'out',
             isStacked: true,

             seriesType: "bars",
             vAxes: {
                 0: {
                     textPosition: 'out',
                     viewWindowMode: 'pretty',
                     title: "",
                     viewWindow: { min: -1100, max: 1100 },
                     gridlines: { color: 'lightgray' },
                 },
                 1: {
                     textPosition: 'out',
                     viewWindow: { min: -1, max: 1 },
                     format: 'percent',
                     gridlines: { color: 'transparent' }
                 },
             },
             series: {
                 0: { targetAxisIndex: 0, color: 'blue' },
                 1: { targetAxisIndex: 0, color: 'gray' },
                 2: { targetAxisIndex: 1, color: 'red', type: 'line', lineWidth: 1, lineDashStyle: [4, 4], pointSize: 5 },
             },
             width: '100%',
             height: '300',

             legend: { position: 'top' },
             chartArea: {
                 height: '100%',
                 width: '100%',
                 top: 48,
                 left: 60,
                 right: 60,
                 bottom: 75
             },
             annotations: {
                 highContrast: false,
                 textStyle: {
                     color: 'red',
                     fontSize: 12,
                     bold: true
                 },
                 alwaysOutside: true
             },
         }

         var chart = new google.visualization.ComboChart(document.getElementById('primaryYear2and3'));
         chart.draw(view, options);

         document.getElementById('downloadimg2and3').innerHTML = '<a download="google-chart-image" href="' + chart.getImageURI() +
             '"><button type="button" class="btn btn-outline-dark btn-sm opacity-25 ms-4 mb-3">Download Chart Image</button></a>';

         window.addEventListener('resize', drawChart, false);
     }
 </script>

我试着研究过其他帖子.

推荐答案

the only option to move the annotations for the second series below the bars,
is to provide a negative stem length using the annotations configuration option,
within the series option for the second series...

1: { targetAxisIndex: 0, color: 'gray', annotations: {stem: {length: -80}} },  // <-- negative stem length

请参见下面的工作片段...

google.charts.load('current', {
  packages: ['corechart']
}).then(drawChart);

function drawChart() {
  var data = new google.visualization.DataTable();

  //var jsonList = @(Json.Serialize(Model.listAllAircraftChart))
  var jsonList = [
    {yearQuarter: 'Quarter 1', year2top: 469, year3bottom: -676, year2percent: -0.306},
    {yearQuarter: 'Quarter 2', year2top: 580, year3bottom: -739, year2percent: -0.215},
    {yearQuarter: 'Quarter 3', year2top: 566, year3bottom: -623, year2percent: -0.091},
    {yearQuarter: 'Quarter 4', year2top: 817, year3bottom: -800, year2percent: -0.01}
  ];

  var title = 'Quarterly Aircraft Transaction Trend';

  data.addColumn('string', 'Quarter');
  data.addColumn('number', '2023');
  data.addColumn('number', '2022');
  data.addColumn('number', '% Change');
  data.addRows(jsonList.map((p) => {
     return [p.yearQuarter, p.year2top, p.year3bottom, p.year2percent];
  }));

  var formatPercent = new google.visualization.NumberFormat({ pattern: '#.#%' });
  formatPercent.format(data, 3);

  var view = new google.visualization.DataView(data);
  view.setColumns([0, 1,
     {
         calc: "stringify",
         sourceColumn: 1,
         type: "string",
         role: "annotation"
     },
     2,
     {
         calc: "stringify",
         sourceColumn: 2,
         type: "string",
         role: "annotation"
     },
     3,
     {
         calc: "stringify",
         sourceColumn: 3,
         type: "string",
         role: "annotation"
     }
  ]);
  var options = {
     title: title,
     titlePosition: 'out',
     isStacked: true,

     seriesType: "bars",
     vAxes: {
         0: {
             textPosition: 'out',
             viewWindowMode: 'pretty',
             title: "",
             viewWindow: { min: -1100, max: 1100 },
             gridlines: { color: 'lightgray' },
         },
         1: {
             textPosition: 'out',
             viewWindow: { min: -1, max: 1 },
             format: 'percent',
             gridlines: { color: 'transparent' }
         },
     },
     series: {
         0: { targetAxisIndex: 0, color: 'blue' },
         1: { targetAxisIndex: 0, color: 'gray', annotations: {stem: {length: -80}} },
         2: { targetAxisIndex: 1, color: 'red', type: 'line', lineWidth: 1, lineDashStyle: [4, 4], pointSize: 5 },
     },
     width: '100%',
     height: '300',

     legend: { position: 'top' },
     chartArea: {
         height: '100%',
         width: '100%',
         top: 48,
         left: 60,
         right: 60,
         bottom: 75
     },
     annotations: {
         highContrast: false,
         textStyle: {
             color: 'red',
             fontSize: 12,
             bold: true
         },
         alwaysOutside: true
     },
  }

  var chart = new google.visualization.ComboChart(document.getElementById('primaryYear2and3'));
  chart.draw(view, options);

  google.visualization.events.addListener(chart, 'ready', function () {
    document.getElementById('downloadimg2and3').innerHTML = '<a download="google-chart-image" href="' + chart.getImageURI() +
       '"><button type="button" class="btn btn-outline-dark btn-sm opacity-25 ms-4 mb-3">Download Chart Image</button></a>';
  });

  window.addEventListener('resize', drawChart, false);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="primaryYear2and3"></div>
<div id="downloadimg2and3"></div>

Javascript相关问答推荐

可以的.是否可以在不预编译的情况下使用嵌套 Select 器?

如何访问Json返回的ASP.NET Core 6中的导航图像属性

我在这个黑暗模式按钮上做错了什么?

从实时数据库(Firebase)上的子类别读取数据

fs. writeFile()vs fs.writeFile()vs fs.appendFile()

如何将连续的十六进制字符串拆分为以空间分隔的十六进制块,每个十六进制块包含32个二元组?

react/redux中的formData在expressjs中返回未定义的req.params.id

使用复选框在d3.js多折线图中添加或删除线条

Chrome是否忽略WebAuthentication userVerification设置?""

无法从NextJS组件传递函数作为参数'

JS—删除对象数组中对象的子对象

如何在ASP.NET中使用Google Charts API JavaScript将条形图标签显示为绝对值而不是负值

映射类型定义,其中值对应于键

OpenAI转录API错误请求

警告框不显示包含HTML输入字段的总和

我想使用GAS和HTML将从Electron 表格中获得的信息插入到文本字段的初始值中

处理TypeScrip Vue组件未初始化的react 对象

select 2-删除js插入的项目将其保留为选项

rxjs在每次迭代后更新数组的可观察值

无法在Adyen自定义卡安全字段创建中使用自定义占位符